summaryrefslogtreecommitdiffstats
path: root/tcl8.6
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2018-12-19 21:30:31 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2018-12-19 21:30:31 (GMT)
commit21ae37c5a9db158c6c4d54a0fa75b8e0b526ebed (patch)
tree312b750afe3bdbe92b5727e2e552da8ed1751b7f /tcl8.6
parent50f1824860159ebdb3896e14647a4562edf658d2 (diff)
parent0587fffc5409653d44546dbcebc7a497954cbb46 (diff)
downloadblt-21ae37c5a9db158c6c4d54a0fa75b8e0b526ebed.zip
blt-21ae37c5a9db158c6c4d54a0fa75b8e0b526ebed.tar.gz
blt-21ae37c5a9db158c6c4d54a0fa75b8e0b526ebed.tar.bz2
Merge branch 'devel'
Diffstat (limited to 'tcl8.6')
-rw-r--r--tcl8.6/ChangeLog2
-rw-r--r--tcl8.6/README24
-rw-r--r--tcl8.6/changes64
-rw-r--r--tcl8.6/compat/fixstrtod.c36
-rw-r--r--tcl8.6/compat/stdlib.h1
-rw-r--r--tcl8.6/compat/strtod.c252
-rw-r--r--tcl8.6/doc/Encoding.34
-rw-r--r--tcl8.6/doc/Eval.38
-rw-r--r--tcl8.6/doc/NRE.3260
-rw-r--r--tcl8.6/doc/clock.n13
-rw-r--r--tcl8.6/doc/define.n2
-rw-r--r--tcl8.6/doc/exec.n17
-rw-r--r--tcl8.6/doc/format.n4
-rw-r--r--tcl8.6/doc/http.n186
-rw-r--r--tcl8.6/doc/lreplace.n40
-rw-r--r--tcl8.6/doc/string.n8
-rw-r--r--tcl8.6/doc/tcltest.n14
-rw-r--r--tcl8.6/generic/regc_locale.c524
-rw-r--r--tcl8.6/generic/tcl.decls4
-rw-r--r--tcl8.6/generic/tcl.h12
-rw-r--r--tcl8.6/generic/tclAssembly.c23
-rw-r--r--tcl8.6/generic/tclBasic.c203
-rw-r--r--tcl8.6/generic/tclBinary.c11
-rw-r--r--tcl8.6/generic/tclCmdAH.c57
-rw-r--r--tcl8.6/generic/tclCmdIL.c98
-rw-r--r--tcl8.6/generic/tclCmdMZ.c403
-rw-r--r--tcl8.6/generic/tclCompCmds.c18
-rw-r--r--tcl8.6/generic/tclCompCmdsGR.c410
-rw-r--r--tcl8.6/generic/tclCompCmdsSZ.c308
-rw-r--r--tcl8.6/generic/tclCompile.h4
-rw-r--r--tcl8.6/generic/tclDate.c2
-rw-r--r--tcl8.6/generic/tclDictObj.c2
-rw-r--r--tcl8.6/generic/tclEncoding.c79
-rw-r--r--tcl8.6/generic/tclEnsemble.c240
-rw-r--r--tcl8.6/generic/tclEnv.c13
-rw-r--r--tcl8.6/generic/tclExecute.c296
-rw-r--r--tcl8.6/generic/tclFCmd.c54
-rw-r--r--tcl8.6/generic/tclFileName.c2
-rw-r--r--tcl8.6/generic/tclIO.c22
-rw-r--r--tcl8.6/generic/tclIOUtil.c29
-rw-r--r--tcl8.6/generic/tclInt.decls4
-rw-r--r--tcl8.6/generic/tclInt.h78
-rw-r--r--tcl8.6/generic/tclIntPlatDecls.h17
-rw-r--r--tcl8.6/generic/tclListObj.c626
-rw-r--r--tcl8.6/generic/tclNamesp.c48
-rw-r--r--tcl8.6/generic/tclOO.c1146
-rw-r--r--tcl8.6/generic/tclOOBasic.c13
-rw-r--r--tcl8.6/generic/tclOOCall.c13
-rw-r--r--tcl8.6/generic/tclOODefineCmds.c145
-rw-r--r--tcl8.6/generic/tclOOInt.h74
-rw-r--r--tcl8.6/generic/tclObj.c31
-rw-r--r--tcl8.6/generic/tclParse.c8
-rw-r--r--tcl8.6/generic/tclPkg.c712
-rw-r--r--tcl8.6/generic/tclProc.c178
-rw-r--r--tcl8.6/generic/tclStringObj.c69
-rw-r--r--tcl8.6/generic/tclStubInit.c29
-rw-r--r--tcl8.6/generic/tclTest.c6
-rw-r--r--tcl8.6/generic/tclThreadTest.c13
-rw-r--r--tcl8.6/generic/tclTrace.c53
-rw-r--r--tcl8.6/generic/tclUniData.c1457
-rw-r--r--tcl8.6/generic/tclUtf.c126
-rw-r--r--tcl8.6/generic/tclUtil.c496
-rw-r--r--tcl8.6/generic/tclVar.c798
-rw-r--r--tcl8.6/library/dde/pkgIndex.tcl4
-rw-r--r--tcl8.6/library/http/http.tcl2479
-rw-r--r--tcl8.6/library/http/pkgIndex.tcl2
-rw-r--r--tcl8.6/library/init.tcl2
-rwxr-xr-xtcl8.6/library/reg/pkgIndex.tcl4
-rw-r--r--tcl8.6/library/tcltest/pkgIndex.tcl4
-rw-r--r--tcl8.6/library/tcltest/tcltest.tcl47
-rw-r--r--tcl8.6/library/tzdata/Africa/Accra94
-rw-r--r--tcl8.6/library/tzdata/Africa/Bissau2
-rw-r--r--tcl8.6/library/tzdata/Africa/Casablanca280
-rw-r--r--tcl8.6/library/tzdata/Africa/Ceuta1
-rw-r--r--tcl8.6/library/tzdata/Africa/El_Aaiun256
-rw-r--r--tcl8.6/library/tzdata/Africa/Sao_Tome9
-rw-r--r--tcl8.6/library/tzdata/Africa/Windhoek95
-rw-r--r--tcl8.6/library/tzdata/America/Araguaina50
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Buenos_Aires58
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Catamarca56
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Cordoba58
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Jujuy52
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/La_Rioja56
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Mendoza52
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Rio_Gallegos56
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Salta56
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/San_Juan56
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/San_Luis50
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Tucuman58
-rw-r--r--tcl8.6/library/tzdata/America/Argentina/Ushuaia56
-rw-r--r--tcl8.6/library/tzdata/America/Asuncion250
-rw-r--r--tcl8.6/library/tzdata/America/Bahia60
-rw-r--r--tcl8.6/library/tzdata/America/Belem28
-rw-r--r--tcl8.6/library/tzdata/America/Boa_Vista32
-rw-r--r--tcl8.6/library/tzdata/America/Bogota2
-rw-r--r--tcl8.6/library/tzdata/America/Campo_Grande252
-rw-r--r--tcl8.6/library/tzdata/America/Cuiaba250
-rw-r--r--tcl8.6/library/tzdata/America/Eirunepe30
-rw-r--r--tcl8.6/library/tzdata/America/Fortaleza38
-rw-r--r--tcl8.6/library/tzdata/America/Grand_Turk4
-rw-r--r--tcl8.6/library/tzdata/America/Guayaquil2
-rw-r--r--tcl8.6/library/tzdata/America/Jamaica6
-rw-r--r--tcl8.6/library/tzdata/America/La_Paz2
-rw-r--r--tcl8.6/library/tzdata/America/Lima6
-rw-r--r--tcl8.6/library/tzdata/America/Maceio40
-rw-r--r--tcl8.6/library/tzdata/America/Manaus30
-rw-r--r--tcl8.6/library/tzdata/America/Montevideo126
-rw-r--r--tcl8.6/library/tzdata/America/Noronha38
-rw-r--r--tcl8.6/library/tzdata/America/Porto_Velho28
-rw-r--r--tcl8.6/library/tzdata/America/Punta_Arenas106
-rw-r--r--tcl8.6/library/tzdata/America/Recife38
-rw-r--r--tcl8.6/library/tzdata/America/Rio_Branco28
-rw-r--r--tcl8.6/library/tzdata/America/Santarem28
-rw-r--r--tcl8.6/library/tzdata/America/Santiago434
-rw-r--r--tcl8.6/library/tzdata/America/Sao_Paulo250
-rw-r--r--tcl8.6/library/tzdata/Antarctica/Casey1
-rw-r--r--tcl8.6/library/tzdata/Antarctica/Palmer78
-rw-r--r--tcl8.6/library/tzdata/Asia/Almaty48
-rw-r--r--tcl8.6/library/tzdata/Asia/Aqtau48
-rw-r--r--tcl8.6/library/tzdata/Asia/Aqtobe46
-rw-r--r--tcl8.6/library/tzdata/Asia/Ashgabat22
-rw-r--r--tcl8.6/library/tzdata/Asia/Atyrau46
-rw-r--r--tcl8.6/library/tzdata/Asia/Baghdad104
-rw-r--r--tcl8.6/library/tzdata/Asia/Baku62
-rw-r--r--tcl8.6/library/tzdata/Asia/Bishkek50
-rw-r--r--tcl8.6/library/tzdata/Asia/Choibalsan48
-rw-r--r--tcl8.6/library/tzdata/Asia/Dhaka2
-rw-r--r--tcl8.6/library/tzdata/Asia/Dushanbe20
-rw-r--r--tcl8.6/library/tzdata/Asia/Gaza72
-rw-r--r--tcl8.6/library/tzdata/Asia/Hebron72
-rw-r--r--tcl8.6/library/tzdata/Asia/Hovd48
-rw-r--r--tcl8.6/library/tzdata/Asia/Kuching14
-rw-r--r--tcl8.6/library/tzdata/Asia/Macau68
-rw-r--r--tcl8.6/library/tzdata/Asia/Manila18
-rw-r--r--tcl8.6/library/tzdata/Asia/Oral46
-rw-r--r--tcl8.6/library/tzdata/Asia/Pyongyang1
-rw-r--r--tcl8.6/library/tzdata/Asia/Qyzylorda46
-rw-r--r--tcl8.6/library/tzdata/Asia/Samarkand20
-rw-r--r--tcl8.6/library/tzdata/Asia/Shanghai43
-rw-r--r--tcl8.6/library/tzdata/Asia/Tashkent22
-rw-r--r--tcl8.6/library/tzdata/Asia/Tbilisi50
-rw-r--r--tcl8.6/library/tzdata/Asia/Tehran444
-rw-r--r--tcl8.6/library/tzdata/Asia/Tokyo16
-rw-r--r--tcl8.6/library/tzdata/Asia/Ulaanbaatar48
-rw-r--r--tcl8.6/library/tzdata/Asia/Yerevan60
-rw-r--r--tcl8.6/library/tzdata/Atlantic/Azores2
-rw-r--r--tcl8.6/library/tzdata/Atlantic/Cape_Verde2
-rw-r--r--tcl8.6/library/tzdata/Atlantic/Madeira2
-rw-r--r--tcl8.6/library/tzdata/Atlantic/Reykjavik66
-rw-r--r--tcl8.6/library/tzdata/Atlantic/Stanley66
-rw-r--r--tcl8.6/library/tzdata/Australia/Lord_Howe478
-rw-r--r--tcl8.6/library/tzdata/Europe/Dublin515
-rw-r--r--tcl8.6/library/tzdata/Europe/Lisbon2
-rw-r--r--tcl8.6/library/tzdata/Europe/Prague9
-rw-r--r--tcl8.6/library/tzdata/Europe/Volgograd1
-rw-r--r--tcl8.6/library/tzdata/Indian/Mauritius4
-rw-r--r--tcl8.6/library/tzdata/Pacific/Apia362
-rw-r--r--tcl8.6/library/tzdata/Pacific/Chatham504
-rw-r--r--tcl8.6/library/tzdata/Pacific/Easter424
-rw-r--r--tcl8.6/library/tzdata/Pacific/Efate20
-rw-r--r--tcl8.6/library/tzdata/Pacific/Enderbury2
-rw-r--r--tcl8.6/library/tzdata/Pacific/Fiji210
-rw-r--r--tcl8.6/library/tzdata/Pacific/Galapagos2
-rw-r--r--tcl8.6/library/tzdata/Pacific/Honolulu5
-rw-r--r--tcl8.6/library/tzdata/Pacific/Kiritimati2
-rw-r--r--tcl8.6/library/tzdata/Pacific/Noumea6
-rw-r--r--tcl8.6/library/tzdata/Pacific/Rarotonga26
-rw-r--r--tcl8.6/library/tzdata/Pacific/Tongatapu8
-rwxr-xr-xtcl8.6/macosx/configure210
-rw-r--r--tcl8.6/pkgs/itcl4.1.1/aclocal.m42
-rw-r--r--tcl8.6/pkgs/itcl4.1.1/doc/man.macros236
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/.project11
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/ChangeLog (renamed from tcl8.6/pkgs/itcl4.1.1/ChangeLog)2
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/Makefile.in (renamed from tcl8.6/pkgs/itcl4.1.1/Makefile.in)157
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/README (renamed from tcl8.6/pkgs/itcl4.1.1/README)2
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/TODO (renamed from tcl8.6/pkgs/itcl4.1.1/TODO)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/aclocal.m4 (renamed from tcl8.6/pkgs/sqlite3.21.0/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/itcl4.1.2/configure (renamed from tcl8.6/pkgs/itcl4.1.1/configure)768
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/itcl4.1.2/configure.ac (renamed from tcl8.6/pkgs/itcl4.1.1/configure.ac)103
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/Class.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/Class.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/List.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/List.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/Object.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/Object.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/Preserve.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/Preserve.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/RegisterC.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/RegisterC.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/Stack.3 (renamed from tcl8.6/pkgs/itcl4.1.1/doc/Stack.3)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/body.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/body.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/class.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/class.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/code.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/code.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/configbody.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/configbody.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/delete.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/delete.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/ensemble.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/ensemble.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/find.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/find.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/is.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/is.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itcl.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itcl.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itclcomponent.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itclcomponent.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itcldelegate.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itcldelegate.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itclextendedclass.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itclextendedclass.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itcloption.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itcloption.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itclvars.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itclvars.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/itclwidget.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/itclwidget.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/license.terms (renamed from tcl8.6/pkgs/itcl4.1.1/doc/license.terms)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/local.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/local.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/man.macros267
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/doc/scope.n (renamed from tcl8.6/pkgs/itcl4.1.1/doc/scope.n)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/clientData (renamed from tcl8.6/pkgs/itcl4.1.1/generic/clientData)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itcl.decls (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itcl.decls)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itcl.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itcl.h)4
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.c)16
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclBase.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclBase.c)27
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclBuiltin.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclBuiltin.c)3
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclClass.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclClass.c)15
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclCmd.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclCmd.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclDecls.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclDecls.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclEnsemble.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclEnsemble.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclHelpers.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclHelpers.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclInfo.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclInfo.c)34
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclInt.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclInt.h)4
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclIntDecls.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclIntDecls.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclLinkage.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclLinkage.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclMethod.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclMethod.c)74
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclObject.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclObject.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclParse.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclParse.c)9
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclResolve.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclResolve.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclResolve2.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclResolve2.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclStubInit.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclStubInit.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclStubLib.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclStubLib.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclStubs.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclStubs.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclTestRegisterC.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclTestRegisterC.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclUtil.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclUtil.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclVCInt.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclVCInt.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.c (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.h (renamed from tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.h)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/itclConfig.sh.in (renamed from tcl8.6/pkgs/itcl4.1.1/itclConfig.sh.in)8
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/library/itcl.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/library/itcl.tcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/library/itclHullCmds.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/library/itclHullCmds.tcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/library/itclWidget.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/library/itclWidget.tcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/library/test_Itcl_CreateObject.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/library/test_Itcl_CreateObject.tcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/license.terms (renamed from tcl8.6/pkgs/itcl4.1.1/license.terms)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/itcl4.1.1/pkgIndex.tcl.in)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/releasenotes.txt (renamed from tcl8.6/pkgs/itcl4.1.1/releasenotes.txt)2
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tclconfig/README.txt (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/README.txt)0
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/itcl4.1.2/tclconfig/install-sh (renamed from tcl8.6/pkgs/thread2.8.2/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tclconfig/tcl.m4 (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/tcl.m4)287
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/itcl4.1.2/tests/all.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/tests/all.tcl)7
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/basic.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/basic.test)177
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/body.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/body.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/chain.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/chain.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/delete.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/delete.test)4
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/eclasscomponent.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/eclasscomponent.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/ensemble.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/ensemble.test)10
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/general1.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/general1.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/import.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/import.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/info.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/info.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/inherit.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/inherit.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/interp.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/interp.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/local.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/local.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/methods.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/methods.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/mkindex.itcl (renamed from tcl8.6/pkgs/itcl4.1.1/tests/mkindex.itcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/mkindex.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/mkindex.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/namespace.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/namespace.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/protection.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/protection.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/scope.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/scope.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/sfbugs.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/sfbugs.test)11
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/tclIndex (renamed from tcl8.6/pkgs/itcl4.1.1/tests/tclIndex)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typeclass.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typeclass.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typedelegation.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typedelegation.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typefunction.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typefunction.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typeinfo.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typeinfo.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typeoption.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typeoption.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/typevariable.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/typevariable.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/widgetadaptor.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/widgetadaptor.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tests/widgetclass.test (renamed from tcl8.6/pkgs/itcl4.1.1/tests/widgetclass.test)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/tools/genStubs.tcl (renamed from tcl8.6/pkgs/itcl4.1.1/tools/genStubs.tcl)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/dllEntryPoint.c (renamed from tcl8.6/pkgs/itcl4.1.1/win/dllEntryPoint.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/itcl.rc (renamed from tcl8.6/pkgs/itcl4.1.1/win/itcl.rc)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/makefile.vc (renamed from tcl8.6/pkgs/itcl4.1.1/win/makefile.vc)202
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/nmakehlp.c (renamed from tcl8.6/pkgs/thread2.8.2/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/rules-ext.vc (renamed from tcl8.6/pkgs/thread2.8.2/win/rules-ext.vc)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/rules.vc1752
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/targets.vc (renamed from tcl8.6/pkgs/sqlite3.21.0/win/targets.vc)0
-rw-r--r--tcl8.6/pkgs/itcl4.1.2/win/toaster.bmp (renamed from tcl8.6/pkgs/itcl4.1.1/win/toaster.bmp)bin3126 -> 3126 bytes
-rw-r--r--tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/shell.c8380
-rw-r--r--tcl8.6/pkgs/sqlite3.21.0/tclconfig/tcl.m44241
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/Makefile.in (renamed from tcl8.6/pkgs/sqlite3.21.0/Makefile.in)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/README (renamed from tcl8.6/pkgs/sqlite3.21.0/README)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/aclocal.m49
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/shell.c16438
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/spaceanal.tcl (renamed from tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/spaceanal.tcl)17
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.c (renamed from tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.c)34027
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.h (renamed from tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.h)1202
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3ext.h (renamed from tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3ext.h)45
-rwxr-xr-xtcl8.6/pkgs/sqlite3.25.3/configure (renamed from tcl8.6/pkgs/sqlite3.21.0/configure)775
-rwxr-xr-xtcl8.6/pkgs/sqlite3.25.3/configure.ac (renamed from tcl8.6/pkgs/sqlite3.21.0/configure.ac)4
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/doc/sqlite3.n (renamed from tcl8.6/pkgs/sqlite3.21.0/doc/sqlite3.n)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/generic/tclsqlite3.c (renamed from tcl8.6/pkgs/sqlite3.21.0/generic/tclsqlite3.c)268
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/license.terms (renamed from tcl8.6/pkgs/sqlite3.21.0/license.terms)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/sqlite3.21.0/pkgIndex.tcl.in)0
-rwxr-xr-xtcl8.6/pkgs/sqlite3.25.3/tclconfig/install-sh (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/tclconfig/tcl.m4 (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/tcl.m4)283
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/tests/all.tcl (renamed from tcl8.6/pkgs/sqlite3.21.0/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/tests/leapsecond.test (renamed from tcl8.6/pkgs/sqlite3.21.0/tests/leapsecond.test)0
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/win/makefile.vc (renamed from tcl8.6/pkgs/sqlite3.21.0/win/makefile.vc)4
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/win/nmakehlp.c (renamed from tcl8.6/pkgs/sqlite3.21.0/win/nmakehlp.c)29
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/win/rules.vc (renamed from tcl8.6/pkgs/sqlite3.21.0/win/rules.vc)45
-rw-r--r--tcl8.6/pkgs/sqlite3.25.3/win/targets.vc (renamed from tcl8.6/pkgs/itcl4.1.1/win/targets.vc)196
-rw-r--r--tcl8.6/pkgs/tdbc1.0.6/pkgIndex.tcl.in12
-rw-r--r--tcl8.6/pkgs/tdbc1.0.6/tclconfig/ChangeLog1003
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/ChangeLog (renamed from tcl8.6/pkgs/tdbc1.0.6/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/Makefile.in (renamed from tcl8.6/pkgs/tdbc1.0.6/Makefile.in)121
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/README (renamed from tcl8.6/pkgs/tdbc1.0.6/README)2
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/aclocal.m4 (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/tdbc1.1.0/configure (renamed from tcl8.6/pkgs/tdbc1.0.6/configure)717
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbc1.1.0/configure.ac (renamed from tcl8.6/pkgs/tdbc1.0.6/configure.ac)50
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/Tdbc_Init.3 (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/Tdbc_Init.3)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_connection.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_connection.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_mapSqlState.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_mapSqlState.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_resultset.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_resultset.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_statement.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_statement.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_tokenize.n (renamed from tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_tokenize.n)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.c (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.c)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.decls (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.decls)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.h (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.h)4
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbcDecls.h (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbcDecls.h)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbcInt.h (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbcInt.h)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubInit.c (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubInit.c)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubLib.c (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubLib.c)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/generic/tdbcTokenize.c (renamed from tcl8.6/pkgs/tdbc1.0.6/generic/tdbcTokenize.c)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/library/tdbc.tcl (renamed from tcl8.6/pkgs/tdbc1.0.6/library/tdbc.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/license.terms (renamed from tcl8.6/pkgs/tdbc1.0.6/license.terms)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/pkgIndex.tcl.in18
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tclconfig/README.txt (renamed from tcl8.6/pkgs/tdbc1.0.6/tclconfig/README.txt)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tclconfig/install-sh (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tclconfig/tcl.m4 (renamed from tcl8.6/pkgs/tdbc1.0.6/tclconfig/tcl.m4)287
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tdbcConfig.sh.in (renamed from tcl8.6/pkgs/tdbc1.0.6/tdbcConfig.sh.in)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tests/all.tcl (renamed from tcl8.6/pkgs/tdbc1.0.6/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tests/tdbc.test (renamed from tcl8.6/pkgs/tdbc1.0.6/tests/tdbc.test)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tests/tokenize.test (renamed from tcl8.6/pkgs/tdbc1.0.6/tests/tokenize.test)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tools/genExtStubs.tcl (renamed from tcl8.6/pkgs/tdbc1.0.6/tools/genExtStubs.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tools/genStubs.tcl (renamed from tcl8.6/pkgs/tdbc1.0.6/tools/genStubs.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/tools/tdbc-man2html.tcl (renamed from tcl8.6/pkgs/tdbc1.0.6/tools/tdbc-man2html.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/makefile.vc (renamed from tcl8.6/pkgs/tdbc1.0.6/win/makefile.vc)206
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/nmakehlp.c (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/rules-ext.vc (renamed from tcl8.6/pkgs/sqlite3.21.0/win/rules-ext.vc)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/rules.vc (renamed from tcl8.6/pkgs/thread2.8.2/win/rules.vc)0
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/targets.vc (renamed from tcl8.6/pkgs/tdbc1.0.6/win/targets.vc)196
-rw-r--r--tcl8.6/pkgs/tdbc1.1.0/win/tdbc.rc (renamed from tcl8.6/pkgs/tdbc1.0.6/win/tdbc.rc)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/ChangeLog (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/Makefile.in (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/Makefile.in)128
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/README (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/README)2
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/aclocal.m4 (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/tdbcmysql1.1.0/configure (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/configure)1061
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcmysql1.1.0/configure.ac (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/configure.ac)49
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/doc/tdbc_mysql.n (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/doc/tdbc_mysql.n)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/fakemysql.h (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/fakemysql.h)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/int2ptr_ptr2int.h (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/int2ptr_ptr2int.h)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubDefs.txt (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubDefs.txt)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubInit.c (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubInit.c)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubs.h (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubs.h)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/generic/tdbcmysql.c (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/tdbcmysql.c)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/library/tdbcmysql.tcl (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/library/tdbcmysql.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/license.terms (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/license.terms)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/pkgIndex.tcl.in)2
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/README.txt26
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/install-sh (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/tcl.m4 (renamed from tcl8.6/pkgs/itcl4.1.1/tclconfig/tcl.m4)287
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/tests/all.tcl (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/tests/tdbcmysql.test (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/tests/tdbcmysql.test)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/win/makefile.vc (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/win/makefile.vc)222
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/win/nmakehlp.c (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/win/rules-ext.vc (renamed from tcl8.6/pkgs/tdbc1.0.6/win/rules-ext.vc)234
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/win/rules.vc (renamed from tcl8.6/pkgs/itcl4.1.1/win/rules.vc)3446
-rw-r--r--tcl8.6/pkgs/tdbcmysql1.1.0/win/targets.vc (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/win/targets.vc)196
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubInit.c483
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.0.6/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.0.6/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/ChangeLog (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/Makefile.in (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/Makefile.in)169
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/README (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/README)2
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/aclocal.m4 (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/tdbcodbc1.1.0/configure (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/configure)1039
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcodbc1.1.0/configure.ac (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/configure.ac)56
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/doc/tdbc_odbc.n (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/doc/tdbc_odbc.n)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/fakesql.h (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/generic/fakesql.h)4
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/int2ptr_ptr2int.h (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/generic/int2ptr_ptr2int.h)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubDefs.txt (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubDefs.txt)2
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubInit.c214
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubs.h (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubs.h)9
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/generic/tdbcodbc.c (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/generic/tdbcodbc.c)352
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/library/tdbcodbc.tcl (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/library/tdbcodbc.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/license.terms (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/license.terms)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/pkgIndex.tcl.in)2
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/README.txt26
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/install-sh (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/tcl.m44184
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/tests/all.tcl (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/tests/tdbcodbc.test (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/tests/tdbcodbc.test)22
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/tests/test.mdb (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/tests/test.mdb)bin65536 -> 65536 bytes
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/win/makefile.vc (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/win/makefile.vc)318
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/win/nmakehlp.c (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/win/rules-ext.vc (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/win/rules-ext.vc)234
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/win/rules.vc (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/win/rules.vc)3446
-rw-r--r--tcl8.6/pkgs/tdbcodbc1.1.0/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/ChangeLog1003
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/tcl.m44335
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules.vc1723
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.0.6/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/ChangeLog (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/Makefile.in (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/Makefile.in)123
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/README (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/README)2
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/TODO (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/TODO)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/aclocal.m4 (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/tdbcpostgres1.1.0/configure (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/configure)943
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/configure.ac (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/configure.ac)49
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/doc/tdbc_postgres.n (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/doc/tdbc_postgres.n)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/fakepq.h (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/fakepq.h)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/int2ptr_ptr2int.h (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/generic/int2ptr_ptr2int.h)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubDefs.txt (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubDefs.txt)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubInit.c (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubInit.c)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubs.h (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubs.h)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/generic/tdbcpostgres.c (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/generic/tdbcpostgres.c)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/library/tdbcpostgres.tcl (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/library/tdbcpostgres.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/license.terms (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/license.terms)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/pkgIndex.tcl.in)2
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/README.txt26
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/install-sh (renamed from tcl8.6/pkgs/tdbc1.0.6/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/tcl.m44184
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/tests/all.tcl (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/tests/future/tdbcpostgre.test.tcl (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/tests/future/tdbcpostgre.test.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/tests/tdbcpostgres.test (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/tests/tdbcpostgres.test)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/win/makefile.vc (renamed from tcl8.6/pkgs/tdbcpostgres1.0.6/win/makefile.vc)222
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/win/nmakehlp.c (renamed from tcl8.6/pkgs/tdbcmysql1.0.6/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules-ext.vc (renamed from tcl8.6/pkgs/itcl4.1.1/win/rules-ext.vc)234
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules.vc (renamed from tcl8.6/pkgs/tdbc1.0.6/win/rules.vc)3446
-rw-r--r--tcl8.6/pkgs/tdbcpostgres1.1.0/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.0.6/Makefile.in297
-rwxr-xr-xtcl8.6/pkgs/tdbcsqlite3-1.0.6/configure5150
-rwxr-xr-xtcl8.6/pkgs/tdbcsqlite3-1.0.6/configure.ac124
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/tcl.m44335
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules.vc1723
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/ChangeLog (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/Makefile.in478
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/README (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/README)2
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/aclocal.m4 (renamed from tcl8.6/pkgs/tdbc1.0.6/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/tdbcsqlite3-1.1.0/configure7780
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure.ac202
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/doc/tdbc_sqlite3.n (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/doc/tdbc_sqlite3.n)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/library/tdbcsqlite3.tcl (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/library/tdbcsqlite3.tcl)2
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/license.terms (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/license.terms)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/pkgIndex.tcl.in)5
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/README.txt26
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/install-sh (renamed from tcl8.6/pkgs/sqlite3.21.0/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/tcl.m44184
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/all.tcl (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/tdbcsqlite3.test (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/tdbcsqlite3.test)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/makefile.vc (renamed from tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/makefile.vc)84
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/nmakehlp.c (renamed from tcl8.6/pkgs/tdbc1.0.6/win/nmakehlp.c)0
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules.vc (renamed from tcl8.6/pkgs/tdbcodbc1.0.6/win/rules.vc)3446
-rw-r--r--tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/thread2.8.2/tclconfig/tcl.m44335
-rw-r--r--tcl8.6/pkgs/thread2.8.2/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/thread2.8.4/ChangeLog (renamed from tcl8.6/pkgs/thread2.8.2/ChangeLog)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/Makefile.in (renamed from tcl8.6/pkgs/thread2.8.2/Makefile.in)44
-rw-r--r--tcl8.6/pkgs/thread2.8.4/README (renamed from tcl8.6/pkgs/thread2.8.2/README)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/aclocal.m4 (renamed from tcl8.6/pkgs/thread2.8.2/aclocal.m4)0
-rwxr-xr-xtcl8.6/pkgs/thread2.8.4/configure (renamed from tcl8.6/pkgs/thread2.8.2/configure)680
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/thread2.8.4/configure.ac (renamed from tcl8.6/pkgs/thread2.8.2/configure.ac)4
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/format.tcl (renamed from tcl8.6/pkgs/thread2.8.2/doc/format.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/html/thread.html (renamed from tcl8.6/pkgs/thread2.8.2/doc/html/thread.html)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/html/tpool.html (renamed from tcl8.6/pkgs/thread2.8.2/doc/html/tpool.html)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/html/tsv.html (renamed from tcl8.6/pkgs/thread2.8.2/doc/html/tsv.html)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/html/ttrace.html (renamed from tcl8.6/pkgs/thread2.8.2/doc/html/ttrace.html)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/man.macros (renamed from tcl8.6/pkgs/thread2.8.2/doc/man.macros)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/man/thread.n (renamed from tcl8.6/pkgs/thread2.8.2/doc/man/thread.n)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/man/tpool.n (renamed from tcl8.6/pkgs/thread2.8.2/doc/man/tpool.n)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/man/tsv.n (renamed from tcl8.6/pkgs/thread2.8.2/doc/man/tsv.n)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/man/ttrace.n (renamed from tcl8.6/pkgs/thread2.8.2/doc/man/ttrace.n)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/thread.man (renamed from tcl8.6/pkgs/thread2.8.2/doc/thread.man)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/tpool.man (renamed from tcl8.6/pkgs/thread2.8.2/doc/tpool.man)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/tsv.man (renamed from tcl8.6/pkgs/thread2.8.2/doc/tsv.man)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/doc/ttrace.man (renamed from tcl8.6/pkgs/thread2.8.2/doc/ttrace.man)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/psGdbm.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/psGdbm.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/psGdbm.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/psGdbm.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/psLmdb.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/psLmdb.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/psLmdb.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/psLmdb.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/tclThread.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/tclThread.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/tclThreadInt.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/tclThreadInt.h)47
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.c)25
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadCmd.c)52
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadNs.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadNs.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadPoolCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadPoolCmd.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.c (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.h (renamed from tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.h)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/lib/ttrace.tcl (renamed from tcl8.6/pkgs/thread2.8.2/lib/ttrace.tcl)2
-rw-r--r--tcl8.6/pkgs/thread2.8.4/license.terms (renamed from tcl8.6/pkgs/thread2.8.2/license.terms)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/naviserver.m4 (renamed from tcl8.6/pkgs/thread2.8.2/naviserver.m4)0
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/thread2.8.4/pkgIndex.tcl.in (renamed from tcl8.6/pkgs/thread2.8.2/pkgIndex.tcl.in)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/README (renamed from tcl8.6/pkgs/thread2.8.2/tcl/README)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/cmdsrv/cmdsrv.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tcl/cmdsrv/cmdsrv.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/phttpd/index.htm (renamed from tcl8.6/pkgs/thread2.8.2/tcl/phttpd/index.htm)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/phttpd/phttpd.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tcl/phttpd/phttpd.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/phttpd/uhttpd.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tcl/phttpd/uhttpd.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tcl/tpool/tpool.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tcl/tpool/tpool.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tclconfig/README.txt26
-rw-r--r--[-rwxr-xr-x]tcl8.6/pkgs/thread2.8.4/tclconfig/install-sh (renamed from tcl8.6/pkgs/itcl4.1.1/tclconfig/install-sh)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tclconfig/tcl.m44184
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/French.txt (renamed from tcl8.6/pkgs/thread2.8.2/tests/French.txt)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/all.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tests/all.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/store-load.tcl (renamed from tcl8.6/pkgs/thread2.8.2/tests/store-load.tcl)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/thread.test (renamed from tcl8.6/pkgs/thread2.8.2/tests/thread.test)21
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/tkt-84be1b5a73.test (renamed from tcl8.6/pkgs/thread2.8.2/tests/tkt-84be1b5a73.test)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/tpool.test (renamed from tcl8.6/pkgs/thread2.8.2/tests/tpool.test)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/tsv.test (renamed from tcl8.6/pkgs/thread2.8.2/tests/tsv.test)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/tests/ttrace.test (renamed from tcl8.6/pkgs/thread2.8.2/tests/ttrace.test)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/unix/CONFIG (renamed from tcl8.6/pkgs/thread2.8.2/unix/CONFIG)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/unix/README (renamed from tcl8.6/pkgs/thread2.8.2/unix/README)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/unix/threadUnix.c (renamed from tcl8.6/pkgs/thread2.8.2/unix/threadUnix.c)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/CONFIG (renamed from tcl8.6/pkgs/thread2.8.2/win/CONFIG)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/README.txt (renamed from tcl8.6/pkgs/thread2.8.2/win/README.txt)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/makefile.vc (renamed from tcl8.6/pkgs/thread2.8.2/win/makefile.vc)2
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/nmakehlp.c (renamed from tcl8.6/pkgs/itcl4.1.1/win/nmakehlp.c)29
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/pkg.vc (renamed from tcl8.6/pkgs/thread2.8.2/win/pkg.vc)2
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/rules-ext.vc118
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/rules.vc1740
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/targets.vc98
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/thread.rc (renamed from tcl8.6/pkgs/thread2.8.2/win/thread.rc)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/threadWin.c (renamed from tcl8.6/pkgs/thread2.8.2/win/threadWin.c)2
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/thread_win.dsp (renamed from tcl8.6/pkgs/thread2.8.2/win/thread_win.dsp)0
-rw-r--r--tcl8.6/pkgs/thread2.8.4/win/thread_win.dsw (renamed from tcl8.6/pkgs/thread2.8.2/win/thread_win.dsw)0
-rw-r--r--tcl8.6/tests/all.tcl8
-rw-r--r--tcl8.6/tests/assemble.test6
-rw-r--r--tcl8.6/tests/async.test40
-rw-r--r--tcl8.6/tests/binary.test40
-rw-r--r--tcl8.6/tests/chanio.test20
-rw-r--r--tcl8.6/tests/cmdAH.test29
-rw-r--r--tcl8.6/tests/cmdIL.test33
-rw-r--r--tcl8.6/tests/coroutine.test2
-rw-r--r--tcl8.6/tests/env.test399
-rw-r--r--tcl8.6/tests/exec.test26
-rw-r--r--tcl8.6/tests/expr.test18
-rw-r--r--tcl8.6/tests/fCmd.test11
-rw-r--r--tcl8.6/tests/fileName.test18
-rw-r--r--tcl8.6/tests/fileSystem.test6
-rw-r--r--tcl8.6/tests/foreach.test6
-rw-r--r--tcl8.6/tests/format.test14
-rw-r--r--tcl8.6/tests/http.test6
-rw-r--r--tcl8.6/tests/http11.test12
-rw-r--r--tcl8.6/tests/httpPipeline.test866
-rw-r--r--tcl8.6/tests/httpTest.tcl505
-rw-r--r--tcl8.6/tests/httpTestScript.tcl509
-rw-r--r--tcl8.6/tests/info.test2
-rw-r--r--tcl8.6/tests/io.test20
-rw-r--r--tcl8.6/tests/ioCmd.test26
-rw-r--r--tcl8.6/tests/ioTrans.test2
-rw-r--r--tcl8.6/tests/iogt.test2
-rw-r--r--tcl8.6/tests/join.test5
-rw-r--r--tcl8.6/tests/lindex.test9
-rw-r--r--tcl8.6/tests/list.test18
-rw-r--r--tcl8.6/tests/lrange.test18
-rw-r--r--tcl8.6/tests/lreplace.test18
-rw-r--r--tcl8.6/tests/lsearch.test44
-rw-r--r--tcl8.6/tests/macOSXFCmd.test22
-rw-r--r--tcl8.6/tests/main.test2
-rw-r--r--tcl8.6/tests/namespace.test33
-rw-r--r--tcl8.6/tests/oo.test392
-rw-r--r--tcl8.6/tests/package.test12
-rw-r--r--tcl8.6/tests/pkgIndex.tcl6
-rw-r--r--tcl8.6/tests/platform.test6
-rw-r--r--tcl8.6/tests/proc.test16
-rw-r--r--tcl8.6/tests/registry.test12
-rw-r--r--tcl8.6/tests/safe.test20
-rw-r--r--tcl8.6/tests/string.test26
-rw-r--r--tcl8.6/tests/tailcall.test20
-rw-r--r--tcl8.6/tests/tcltest.test19
-rw-r--r--tcl8.6/tests/tcltests.tcl11
-rw-r--r--tcl8.6/tests/thread.test67
-rw-r--r--tcl8.6/tests/var.test50
-rw-r--r--tcl8.6/tests/winDde.test4
-rw-r--r--tcl8.6/tests/winFCmd.test16
-rw-r--r--tcl8.6/tests/winPipe.test285
-rw-r--r--tcl8.6/tools/genStubs.tcl51
-rw-r--r--tcl8.6/tools/uniClass.tcl6
-rw-r--r--tcl8.6/tools/uniParse.tcl11
-rw-r--r--tcl8.6/unix/Makefile.in18
-rwxr-xr-xtcl8.6/unix/configure486
-rwxr-xr-xtcl8.6/unix/configure.in22
-rw-r--r--tcl8.6/unix/tcl.m478
-rw-r--r--tcl8.6/unix/tcl.spec2
-rw-r--r--tcl8.6/unix/tclConfig.h.in6
-rw-r--r--tcl8.6/unix/tclUnixFCmd.c18
-rw-r--r--tcl8.6/unix/tclUnixFile.c6
-rw-r--r--tcl8.6/unix/tclUnixPort.h19
-rw-r--r--tcl8.6/unix/tclUnixSock.c6
-rw-r--r--tcl8.6/unix/tclUnixThrd.c8
-rw-r--r--tcl8.6/win/Makefile.in16
-rwxr-xr-xtcl8.6/win/configure8
-rw-r--r--tcl8.6/win/configure.in4
-rw-r--r--tcl8.6/win/makefile.vc4
-rw-r--r--tcl8.6/win/nmakehlp.c29
-rw-r--r--tcl8.6/win/rules-ext.vc2
-rw-r--r--tcl8.6/win/rules.vc45
-rw-r--r--tcl8.6/win/tclAppInit.c4
-rw-r--r--tcl8.6/win/tclWin32Dll.c87
-rw-r--r--tcl8.6/win/tclWinDde.c319
-rw-r--r--tcl8.6/win/tclWinFCmd.c7
-rwxr-xr-x[-rw-r--r--]tcl8.6/win/tclWinFile.c136
-rw-r--r--tcl8.6/win/tclWinInit.c53
-rw-r--r--tcl8.6/win/tclWinInt.h2
-rw-r--r--tcl8.6/win/tclWinPipe.c223
-rw-r--r--tcl8.6/win/tclWinPort.h3
-rw-r--r--tcl8.6/win/tclWinReg.c87
-rw-r--r--tcl8.6/win/tclWinSock.c16
-rw-r--r--tcl8.6/win/tclWinThrd.c8
630 files changed, 98031 insertions, 73902 deletions
diff --git a/tcl8.6/ChangeLog b/tcl8.6/ChangeLog
index e2881a0..84281bc 100644
--- a/tcl8.6/ChangeLog
+++ b/tcl8.6/ChangeLog
@@ -1,6 +1,6 @@
A NOTE ON THE CHANGELOG:
Starting in early 2011, Tcl source code has been under the management of
-fossil, hosted at http://core.tcl.tk/tcl/ . Fossil presents a "Timeline"
+fossil, hosted at https://core.tcl-lang.org/tcl/ . Fossil presents a "Timeline"
view of changes made that is superior in every way to a hand edited log file.
Because of this, many Tcl developers are now out of the habit of maintaining
this log file. You may still find useful things in it, but the Timeline is
diff --git a/tcl8.6/README b/tcl8.6/README
index adfdf97..dae0dda 100644
--- a/tcl8.6/README
+++ b/tcl8.6/README
@@ -1,5 +1,5 @@
README: Tcl
- This is the Tcl 8.6.8 source distribution.
+ This is the Tcl 8.6.9 source distribution.
http://sourceforge.net/projects/tcl/files/Tcl/
You can get any source release of Tcl from the URL above.
@@ -29,7 +29,7 @@ Tcl is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
takes place at:
- http://core.tcl.tk/
+ http://core.tcl-lang.org/
Tcl/Tk release and mailing list services are hosted by SourceForge:
@@ -37,7 +37,7 @@ Tcl/Tk release and mailing list services are hosted by SourceForge:
with the Tcl Developer Xchange hosted at:
- http://www.tcl.tk/
+ http://www.tcl-lang.org/
Tcl is a freely available open source package. You can do virtually
anything you like with it, such as modifying it, redistributing it,
@@ -49,21 +49,21 @@ and selling it either in whole or in part. See the file
Extensive documentation is available at our website.
The home page for this release, including new features, is
- http://www.tcl.tk/software/tcltk/8.6.html
+ http://www.tcl-lang.org/software/tcltk/8.6.html
Detailed release notes can be found at the file distributions page
by clicking on the relevant version.
http://sourceforge.net/projects/tcl/files/Tcl/
Information about Tcl itself can be found at
- http://www.tcl.tk/about/
+ http://www.tcl-lang.org/about/
There have been many Tcl books on the market. Many are mentioned in the Wiki:
- http://wiki.tcl.tk/_/ref?N=25206
+ http://wiki.tcl-lang.org/_/ref?N=25206
To view the complete set of reference manual entries for Tcl 8.6 online,
visit the URL:
- http://www.tcl.tk/man/tcl8.6/
+ http://www.tcl-lang.org/man/tcl8.6/
2a. Unix Documentation
----------------------
@@ -101,7 +101,7 @@ There are brief notes in the unix/README, win/README, and macosx/README about
compiling on these different platforms. There is additional information
about building Tcl from sources at
- http://www.tcl.tk/doc/howto/compile.html
+ http://www.tcl-lang.org/doc/howto/compile.html
4. Development tools
---------------------------
@@ -127,7 +127,7 @@ see the "Support and bug fixes" section below.
A Wiki-based open community site covering all aspects of Tcl/Tk is at:
- http://wiki.tcl.tk/
+ http://wiki.tcl-lang.org/
It is dedicated to the Tcl programming language and its extensions. A
wealth of useful information can be found there. It contains code
@@ -153,7 +153,7 @@ We are very interested in receiving bug reports, patches, and suggestions
for improvements. We prefer that you send this information to us as
tickets entered into our tracker at:
- http://core.tcl.tk/tcl/reportlist
+ http://core.tcl-lang.org/tcl/reportlist
We will log and follow-up on each bug, although we cannot promise a
specific turn-around time. Enhancements may take longer and may not happen
@@ -169,13 +169,13 @@ questions for which no one else is likely to know the answer. In addition,
see the following Web site for links to other organizations that offer
Tcl/Tk training:
- http://wiki.tcl.tk/training
+ http://wiki.tcl-lang.org/training
9. Tracking Development
-----------------------
Tcl is developed in public. To keep an eye on how Tcl is changing, see
- http://core.tcl.tk/
+ http://core.tcl-lang.org/
10. Thank You
-------------
diff --git a/tcl8.6/changes b/tcl8.6/changes
index 040f360..eb18c72 100644
--- a/tcl8.6/changes
+++ b/tcl8.6/changes
@@ -8830,3 +8830,67 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
2017-12-19 (bug)[586e71] EvalObjv exception handling at level #0 (sebres,porter)
--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tcl/ for details
+
+2018-02-11 (enhance) stop blocking conversion of object to/from class (coulter)
+
+2018-02-12 (enhance) NR-enable [package require] (coulter)
+
+2018-02-14 (bug)[9fd5c6] crash in object deletion, test oo-11.5 (coulter)
+
+2018-02-14 (bug)[3c32a3] crash deleting object with class mixed in (coulter)
+
+2018-02-15 (platform) stop using -lieee, removed from glibc-2.27 (porter)
+***POTENTIAL INCOMPATIBILITY for math programs that embed Tcl***
+
+2018-02-23 (bug)[8e6a9a] bad binary [string match], test string-11.55 (porter)
+
+2018-03-05 (bug)[1873ea] repair multi-thread std channel init (sebres)
+
+2018-03-09 (bug)[db36fa] broken bytecode for index values (porter)
+
+2018-03-13 (bug) broken compiled [string replace], test string-14.19 (porter)
+
+2018-03-14 (bug) [string trim*] engine crashed on invalid UTF (sebres)
+
+2018-04-17 (bug) missing trace in compiled [array set], test var-20.11 (porter)
+
+2018-04-22 (bug)[46a241] crash in unset array with search, var-13.[23] (goth)
+
+2018-04-30 (bug)[27b682] race made [file delete] raise "no such file" (sebres)
+
+2018-06-04 (bug)[925643] 32/64 cleanup of filesystem DIR operations (sebres)
+
+2018-06-18 (bug) leaks in TclSetEnv and env cache (coulter)
+
+2018-06-24 (bug)[3592747] [yieldto] dying namespace, tailcall-14.1 (coulter)
+
+2018-07-09 (bug)[270f78] race in [file mkdir] (sebres)
+
+2018-07-12 (bug)[3f7af0] [file delete] raised "permission denied" (sebres)
+
+2018-07-26 (bug)[d051b7] overflow crash in [format] (sebres)
+
+2018-08-29 revised quoting of [exec] args in generated command line (sebres)
+***POTENTIAL INCOMPATIBILITY***
+
+2018-09-20 HTTP Keep-Alive with pipelined requests (nash)
+=> http 2.9.0
+
+2018-09-27 (new)[TIP 505] [lreplace] accepts all out of range indices (porter)
+
+2018-10-04 (bug) Prevent crash from NULL keyName (nijtmans)
+=> registry 1.3.3
+
+2018-10-26 (enhance) advance dde version (nijtmans)
+=> dde 1.4.1
+
+2018-10-27 tzdata updated to Olson's tzdata2018g (jima)
+
+2018-10-29 Update tcltest package for Travis support (fellows)
+=> tcltest 2.5.0
+
+2018-11-09 (bug)[35a8f1] overlong string length of some lists (owens)
+
+2018-11-16 (bug)[00d04c] Repair [binary encode base64] (sebres)
+
+- Released 8.6.9, November 16, 2018 - details at http://core.tcl-lang.org/tcl/ -
diff --git a/tcl8.6/compat/fixstrtod.c b/tcl8.6/compat/fixstrtod.c
deleted file mode 100644
index 63fb8ef..0000000
--- a/tcl8.6/compat/fixstrtod.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * fixstrtod.c --
- *
- * Source code for the "fixstrtod" procedure. This procedure is
- * used in place of strtod under Solaris 2.4, in order to fix
- * a bug where the "end" pointer gets set incorrectly.
- *
- * Copyright (c) 1995 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include <stdio.h>
-
-#undef strtod
-
-/*
- * Declare strtod explicitly rather than including stdlib.h, since in
- * somes systems (e.g. SunOS 4.1.4) stdlib.h doesn't declare strtod.
- */
-
-extern double strtod(char *, char **);
-
-double
-fixstrtod(
- char *string,
- char **endPtr)
-{
- double d;
- d = strtod(string, endPtr);
- if ((endPtr != NULL) && (*endPtr != string) && ((*endPtr)[-1] == 0)) {
- *endPtr -= 1;
- }
- return d;
-}
diff --git a/tcl8.6/compat/stdlib.h b/tcl8.6/compat/stdlib.h
index 0ad4c1d..6900be3 100644
--- a/tcl8.6/compat/stdlib.h
+++ b/tcl8.6/compat/stdlib.h
@@ -29,7 +29,6 @@ extern char * malloc(unsigned int numBytes);
extern void qsort(void *base, int n, int size, int (*compar)(
const void *element1, const void *element2));
extern char * realloc(char *ptr, unsigned int numBytes);
-extern double strtod(const char *string, char **endPtr);
extern long strtol(const char *string, char **endPtr, int base);
extern unsigned long strtoul(const char *string, char **endPtr, int base);
diff --git a/tcl8.6/compat/strtod.c b/tcl8.6/compat/strtod.c
deleted file mode 100644
index 9643c09..0000000
--- a/tcl8.6/compat/strtod.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * strtod.c --
- *
- * Source code for the "strtod" library procedure.
- *
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tclInt.h"
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
- * exponent larger than this will already
- * produce underflow or overflow, so there's
- * no need to worry about additional digits.
- */
-static const double powersOf10[] = { /* Table giving binary powers of 10. Entry */
- 10., /* is 10^2^i. Used to convert decimal */
- 100., /* exponents into floating-point numbers. */
- 1.0e4,
- 1.0e8,
- 1.0e16,
- 1.0e32,
- 1.0e64,
- 1.0e128,
- 1.0e256
-};
-
-/*
- *----------------------------------------------------------------------
- *
- * strtod --
- *
- * This procedure converts a floating-point number from an ASCII
- * decimal representation to internal double-precision format.
- *
- * Results:
- * The return value is the double-precision floating-point
- * representation of the characters in string. If endPtr isn't
- * NULL, then *endPtr is filled in with the address of the
- * next character after the last one that was part of the
- * floating-point number.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-double
-strtod(
- const char *string, /* A decimal ASCII floating-point number,
- * optionally preceded by white space. Must
- * have form "-I.FE-X", where I is the integer
- * part of the mantissa, F is the fractional
- * part of the mantissa, and X is the
- * exponent. Either of the signs may be "+",
- * "-", or omitted. Either I or F may be
- * omitted, or both. The decimal point isn't
- * necessary unless F is present. The "E" may
- * actually be an "e". E and X may both be
- * omitted (but not just one). */
- char **endPtr) /* If non-NULL, store terminating character's
- * address here. */
-{
- int sign, expSign = FALSE;
- double fraction, dblExp;
- const double *d;
- register const char *p;
- register int c;
- int exp = 0; /* Exponent read from "EX" field. */
- int fracExp = 0; /* Exponent that derives from the fractional
- * part. Under normal circumstatnces, it is
- * the negative of the number of digits in F.
- * However, if I is very long, the last digits
- * of I get dropped (otherwise a long I with a
- * large negative exponent could cause an
- * unnecessary overflow on I alone). In this
- * case, fracExp is incremented one for each
- * dropped digit. */
- int mantSize; /* Number of digits in mantissa. */
- int decPt; /* Number of mantissa digits BEFORE decimal
- * point. */
- const char *pExp; /* Temporarily holds location of exponent in
- * string. */
-
- /*
- * Strip off leading blanks and check for a sign.
- */
-
- p = string;
- while (isspace(UCHAR(*p))) {
- p += 1;
- }
- if (*p == '-') {
- sign = TRUE;
- p += 1;
- } else {
- if (*p == '+') {
- p += 1;
- }
- sign = FALSE;
- }
-
- /*
- * Count the number of digits in the mantissa (including the decimal
- * point), and also locate the decimal point.
- */
-
- decPt = -1;
- for (mantSize = 0; ; mantSize += 1)
- {
- c = *p;
- if (!isdigit(c)) {
- if ((c != '.') || (decPt >= 0)) {
- break;
- }
- decPt = mantSize;
- }
- p += 1;
- }
-
- /*
- * Now suck up the digits in the mantissa. Use two integers to collect 9
- * digits each (this is faster than using floating-point). If the mantissa
- * has more than 18 digits, ignore the extras, since they can't affect the
- * value anyway.
- */
-
- pExp = p;
- p -= mantSize;
- if (decPt < 0) {
- decPt = mantSize;
- } else {
- mantSize -= 1; /* One of the digits was the point. */
- }
- if (mantSize > 18) {
- fracExp = decPt - 18;
- mantSize = 18;
- } else {
- fracExp = decPt - mantSize;
- }
- if (mantSize == 0) {
- fraction = 0.0;
- p = string;
- goto done;
- } else {
- int frac1, frac2;
-
- frac1 = 0;
- for ( ; mantSize > 9; mantSize -= 1) {
- c = *p;
- p += 1;
- if (c == '.') {
- c = *p;
- p += 1;
- }
- frac1 = 10*frac1 + (c - '0');
- }
- frac2 = 0;
- for (; mantSize > 0; mantSize -= 1) {
- c = *p;
- p += 1;
- if (c == '.') {
- c = *p;
- p += 1;
- }
- frac2 = 10*frac2 + (c - '0');
- }
- fraction = (1.0e9 * frac1) + frac2;
- }
-
- /*
- * Skim off the exponent.
- */
-
- p = pExp;
- if ((*p == 'E') || (*p == 'e')) {
- p += 1;
- if (*p == '-') {
- expSign = TRUE;
- p += 1;
- } else {
- if (*p == '+') {
- p += 1;
- }
- expSign = FALSE;
- }
- if (!isdigit(UCHAR(*p))) {
- p = pExp;
- goto done;
- }
- while (isdigit(UCHAR(*p))) {
- exp = exp * 10 + (*p - '0');
- p += 1;
- }
- }
- if (expSign) {
- exp = fracExp - exp;
- } else {
- exp = fracExp + exp;
- }
-
- /*
- * Generate a floating-point number that represents the exponent. Do this
- * by processing the exponent one bit at a time to combine many powers of
- * 2 of 10. Then combine the exponent with the fraction.
- */
-
- if (exp < 0) {
- expSign = TRUE;
- exp = -exp;
- } else {
- expSign = FALSE;
- }
- if (exp > maxExponent) {
- exp = maxExponent;
- errno = ERANGE;
- }
- dblExp = 1.0;
- for (d = powersOf10; exp != 0; exp >>= 1, ++d) {
- if (exp & 01) {
- dblExp *= *d;
- }
- }
- if (expSign) {
- fraction /= dblExp;
- } else {
- fraction *= dblExp;
- }
-
- done:
- if (endPtr != NULL) {
- *endPtr = (char *) p;
- }
-
- if (sign) {
- return -fraction;
- }
- return fraction;
-}
diff --git a/tcl8.6/doc/Encoding.3 b/tcl8.6/doc/Encoding.3
index 81ef508..79fca0f 100644
--- a/tcl8.6/doc/Encoding.3
+++ b/tcl8.6/doc/Encoding.3
@@ -260,10 +260,6 @@ Windows-only convenience
functions for converting between UTF-8 and Windows strings
based on the TCHAR type which is by convention
a Unicode character on Windows NT.
-These functions are essentially wrappers around
-\fBTcl_UtfToExternalDString\fR and
-\fBTcl_ExternalToUtfDString\fR that convert to and from the
-Unicode encoding.
.PP
\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
Given an \fIencoding\fR, the return value is the \fIname\fR argument that
diff --git a/tcl8.6/doc/Eval.3 b/tcl8.6/doc/Eval.3
index 191bace..e241794 100644
--- a/tcl8.6/doc/Eval.3
+++ b/tcl8.6/doc/Eval.3
@@ -176,10 +176,10 @@ it is faster to execute the script directly.
.TP 23
\fBTCL_EVAL_GLOBAL\fR
.
-If this flag is set, the script is processed at global level. This
-means that it is evaluated in the global namespace and its variable
-context consists of global variables only (it ignores any Tcl
-procedures that are active).
+If this flag is set, the script is evaluated in the global namespace instead of
+the current namespace and its variable context consists of global variables
+only (it ignores any Tcl procedures that are active).
+.\" TODO: document TCL_EVAL_INVOKE and TCL_EVAL_NOERR.
.SH "MISCELLANEOUS DETAILS"
.PP
diff --git a/tcl8.6/doc/NRE.3 b/tcl8.6/doc/NRE.3
index ff0d108..6078a53 100644
--- a/tcl8.6/doc/NRE.3
+++ b/tcl8.6/doc/NRE.3
@@ -1,5 +1,6 @@
.\"
.\" Copyright (c) 2008 by Kevin B. Kenny.
+.\" Copyright (c) 2018 by Nathan Coulter.
.\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -38,43 +39,39 @@ void
.SH ARGUMENTS
.AS Tcl_CmdDeleteProc *interp in
.AP Tcl_Interp *interp in
-Interpreter in which to create or evaluate a command.
+The relevant Interpreter.
.AP char *cmdName in
-Name of a new command to create.
+Name of the command to create.
.AP Tcl_ObjCmdProc *proc in
-Implementation of a command that will be called whenever \fIcmdName\fR
-is invoked as a command in the unoptimized way.
+Called in order to evaluate a command. Is often just a small wrapper that uses
+\fBTcl_NRCallObjProc\fR to call \fInreProc\fR using a new trampoline. Behaves
+in the same way as the \fIproc\fR argument to \fBTcl_CreateObjCommand\fR(3)
+(\fIq.v.\fR).
.AP Tcl_ObjCmdProc *nreProc in
-Implementation of a command that will be called whenever \fIcmdName\fR
-is invoked and requested to conserve the C stack.
+Called instead of \fIproc\fR when a trampoline is already in use.
.AP ClientData clientData in
-Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
-\fIdeleteProc\fR and \fIobjProc\fR.
+Arbitrary one-word value passed to \fIproc\fR, \fInreProc\fR, \fIdeleteProc\fR
+and \fIobjProc\fR.
.AP Tcl_CmdDeleteProc *deleteProc in/out
-Procedure to call before \fIcmdName\fR is deleted from the interpreter.
-This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
-is \fBNULL\fR, then no procedure is called before the command is deleted.
+Called before \fIcmdName\fR is deleted from the interpreter, allowing for
+command-specific cleanup. May be NULL.
.AP int objc in
-Count of parameters provided to the implementation of a command.
+Number of items in \fIobjv\fR.
.AP Tcl_Obj **objv in
-Pointer to an array of Tcl values. Each value holds the value of a
-single word in the command to execute.
+Words in the command.
.AP Tcl_Obj *objPtr in
-Pointer to a Tcl_Obj whose value is a script or expression to execute.
+A script or expression to evaluate.
.AP int flags in
-ORed combination of flag bits that specify additional options.
-\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
-.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
-.\" TCL_EVAL_NOERR well enough to document them.
+As described for \fITcl_EvalObjv\fR.
+.PP
.AP Tcl_Command cmd in
-Token for a command that is to be used instead of the currently
-executing command.
+Token to use instead of one derived from the first word of \fIobjv\fR in order
+to evaluate a command.
.AP Tcl_Obj *resultPtr out
-Pointer to an unshared Tcl_Obj where the result of expression
-evaluation is written.
+Pointer to an unshared Tcl_Obj where the result of the evaluation is stored if
+the return code is TCL_OK.
.AP Tcl_NRPostProc *postProcPtr in
-Pointer to a function that will be invoked when the command currently
-executing in the interpreter designated by \fIinterp\fR completes.
+A function to push.
.AP ClientData data0 in
.AP ClientData data1 in
.AP ClientData data2 in
@@ -84,98 +81,51 @@ to the function designated by \fIpostProcPtr\fR when it is invoked.
.BE
.SH DESCRIPTION
.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.
-.PP
-The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
-interpreter designated by \fIinterp\fR that is prepared to handle
-nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
-gives the name of the new command. If \fIcmdName\fR contains any
-namespace qualifiers, then the new command is added to the specified
-namespace; otherwise, it is added to the global namespace. \fIproc\fR
-gives the procedure that will be called when the interpreter wishes to
-evaluate the command in an unoptimized manner, and \fInreProc\fR is
-the procedure that will be called when the interpreter wishes to
-evaluate the command using a trampoline. \fIdeleteProc\fR is a
-function that will be called before the command is deleted from the
-interpreter. When any of the three functions is invoked, it is passed
-the \fIclientData\fR parameter.
-.PP
-\fBTcl_NRCreateCommand\fR deletes any existing command
-\fIname\fR already associated with the interpreter
-(however see below for an exception where the existing command
-is not deleted).
-It returns a token that may be used to refer
-to the command in subsequent calls to \fBTcl_GetCommandName\fR.
-If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
-the process of being deleted, then it does not create a new command,
-does not delete any existing command of the same name, and returns NULL.
-.PP
-The \fIproc\fR and \fInreProc\fR function are expected to conform to
-all the rules set forth for the \fIproc\fR argument to
-\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
-.PP
-When a command that is written to cope with evaluation via trampoline
-is invoked without a trampoline on the stack, it will usually respond
-to the invocation by creating a trampoline and calling the
-trampoline-enabled implementation of the same command. This call is done by
-means of \fBTcl_NRCallObjProc\fR. In the call to
-\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
-\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
-passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
-trampoline-enabled implementation of the command.
-.PP
-\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
-to be evaluated in the interpreter designated by \fIinterp\fR after
-the current command (which must be trampoline-enabled) returns. It is
-the method by which a command may invoke a script without consuming
-space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
-invoke a single Tcl command whose words have already been separated
-and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
-words of the command to be evaluated when execution reaches the
-trampoline.
-.PP
-\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
-resolution is already known. The \fIcmd\fR parameter gives a
-\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
-\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
-the trampoline; this command must match the word in \fIobjv[0]\fR.
-The remaining arguments are as for \fBTcl_NREvalObjv\fR.
-.PP
-\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.
-.\" 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
-evaluated in the global namespace. If it is not set, it is evaluated
-in the current namespace.
-.PP
-\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
-to be evaluated in the interpreter designated by \fIinterp\fR after
-the current command (which must be trampoline-enabled) returns. It is
-the method by which a command may evaluate a Tcl expression without consuming
-space on the C stack. The argument \fIresultPtr\fR is a pointer to an
-unshared Tcl_Obj where the result of expression evaluation is to be written.
-If expression evaluation returns any code other than TCL_OK, the
-\fIresultPtr\fR value is left untouched.
-.PP
-All of the routines return \fBTCL_OK\fR if command or expression invocation
-has been scheduled successfully. If for any reason the scheduling cannot
-be completed (for example, if the interpreter is unable to find
-the requested command), they return \fBTCL_ERROR\fR with an
-appropriate message left in the interpreter's result.
-.PP
-\fBTcl_NRAddCallback\fR arranges to have a C function called when the
-current trampoline-enabled command in the Tcl interpreter designated
-by \fIinterp\fR returns. The \fIpostProcPtr\fR argument is a pointer
-to the callback function, which must have arguments and return value
-consistent with the \fBTcl_NRPostProc\fR data type:
+These functions provide an interface to the function stack that an interpreter
+iterates through to evaluate commands. The routine behind a command is
+implemented by an initial function and any additional functions that the
+routine pushes onto the stack as it progresses. The interpreter itself pushes
+functions onto the stack to react to the end of a routine and to exercise other
+forms of control such as switching between in-progress stacks and the
+evaluation of other scripts at additional levels without adding frames to the C
+stack. To execute a routine, the initial function for the routine is called
+and then a small bit of code called a \fItrampoline\fR iteratively takes
+functions off the stack and calls them, using the value of the last call as the
+value of the routine.
+.PP
+\fBTcl_NRCallObjProc\fR calls \fInreProc\fR using a new trampoline.
+.PP
+\fBTcl_NRCreateCommand\fR, an alternative to \fBTcl_CreateObjCommand\fR,
+resolves \fIcmdName\fR, which may contain namespace qualifiers, relative to the
+current namespace, creates a command by that name, and returns a token for the
+command which may be used in subsequent calls to \fBTcl_GetCommandName\fR.
+Except for a few cases noted below any existing command by the same name is
+first deleted. If \fIinterp\fR is in the process of being deleted
+\fBTcl_NRCreateCommand\fR does not create any command, does not delete any
+command, and returns NULL.
+.PP
+\fBTcl_NREvalObj\fR pushes a function that is like \fBTcl_EvalObjEx\fR but
+consumes no space on the C stack.
+.PP
+\fBTcl_NREvalObjv\fR pushes a function that is like \fBTcl_EvalObjv\fR but
+consumes no space on the C stack.
+.PP
+\fBTcl_NRCmdSwap\fR is like \fBTcl_NREvalObjv\fR, but uses \fIcmd\fR, a token
+previously returned by \fBTcl_CreateObjCommand\fR or
+\fBTcl_GetCommandFromObj\fR, instead of resolving the first word of \fIobjv\fR.
+. The name of this command must be the same as \fIobjv[0]\fR.
+.PP
+\fBTcl_NRExprObj\fR pushes a function that evaluates \fIobjPtr\fR as an
+expression in the same manner as \fBTcl_ExprObj\fR but without consuming space
+on the C stack.
+.PP
+All of the functions return \fBTCL_OK\fR if the evaluation of the script,
+command, or expression has been scheduled successfully. Otherwise (for example
+if the command name cannot be resolved), they return \fBTCL_ERROR\fR and store
+a message as the interpreter's result.
+.PP
+\fBTcl_NRAddCallback\fR pushes \fIpostProcPtr\fR. The signature for
+\fBTcl_NRPostProc\fR is:
.PP
.CS
typedef int
@@ -185,25 +135,13 @@ typedef int
int \fIresult\fR);
.CE
.PP
-When the trampoline invokes the callback function, the \fIdata\fR
-parameter will point to an array containing the four one-word
-quantities that were passed to \fBTcl_NRAddCallback\fR in the
-\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
-be designated by the \fIinterp\fR parameter, and the \fIresult\fR
-parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
-\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
-returned by the command evaluation. The callback function is expected,
-in turn, either to return a \fIresult\fR to control further evaluation.
-.PP
-Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
-callbacks, which may be to the same or different callback
-functions. If multiple callbacks are requested, they are executed in
-last-in, first-out order, that is, the most recently requested
-callback is executed first.
+\fIdata\fR is a pointer to an array containing \fIdata0\fR through \fIdata3\fR.
+\fIresult\fR is the value returned by the previous function implementing part
+the routine.
.SH EXAMPLE
.PP
-The usual pattern for Tcl commands that invoke other Tcl commands
-is something like:
+The following command uses \fBTcl_EvalObjEx\fR, which consumes space on the C
+stack, to evalute a script:
.PP
.CS
int
@@ -228,28 +166,17 @@ int
\fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
.CE
.PP
-To enable a command like this one for trampoline-based evaluation,
-it must be split into three pieces:
-.IP \(bu
-A non-trampoline implementation, \fITheCmdNewObjProc\fR,
-which will simply create a trampoline
-and invoke the trampoline-based implementation.
-.IP \(bu
-A trampoline-enabled implementation, \fITheCmdNRObjProc\fR. This
-function will perform the initialization, request that the trampoline
-call the postprocessing routine after command evaluation, and finally,
-request that the trampoline call the inner command.
-.IP \(bu
-A postprocessing routine, \fITheCmdPostProc\fR. This function will
-perform the postprocessing formerly done after the return from the
-inner command in \fITheCmdObjProc\fR.
-.PP
-The non-trampoline implementation is simple and stylized, containing
-a single statement:
+To avoid consuming space on the C stack, \fITheCmdOldObjProc\fR is renamed to
+\fITheCmdNRObjProc\fR and the postprocessing step is split into a separate
+function, \fITheCmdPostProc\fR, which is pushed onto the function stack.
+\fITcl_EvalObjEx\fR is replaced with \fITcl_NREvalObj\fR, which uses a
+trampoline instead of consuming space on the C stack. A new version of
+\fITheCmdOldObjProc\fR is just a a wrapper that uses \fBTcl_NRCallObjProc\fR to
+call \fITheCmdNRObjProc\fR:
.PP
.CS
int
-\fITheCmdNewObjProc\fR(
+\fITheCmdOldObjProc\fR(
ClientData clientData,
Tcl_Interp *interp,
int objc,
@@ -260,9 +187,6 @@ int
}
.CE
.PP
-The trampoline-enabled implementation requests postprocessing,
-and returns to the trampoline requesting command evaluation.
-.PP
.CS
int
\fITheCmdNRObjProc\fR
@@ -284,9 +208,6 @@ int
}
.CE
.PP
-The postprocessing procedure does whatever the original command did
-upon return from the inner evaluation.
-.PP
.CS
int
\fITheCmdNRPostProc\fR(
@@ -303,26 +224,13 @@ int
}
.CE
.PP
-If \fItheCommand\fR is a command that results in multiple commands or
-scripts being evaluated, its postprocessing routine may schedule
-additional postprocessing and then request another command evaluation
-by means of \fBTcl_NREvalObj\fR or one of the other evaluation
-routines. Looping and sequencing constructs may be implemented in this way.
-.PP
-Finally, to install a trampoline-enabled command in the interpreter,
-\fBTcl_NRCreateCommand\fR is used in place of
-\fBTcl_CreateObjCommand\fR. It accepts two command procedures instead
-of one. The first is for use when no trampoline is yet on the stack,
-and the second is for use when there is already a trampoline in place.
+Any function comprising a routine can push other functions, making it possible
+implement looping and sequencing constructs using the function stack.
.PP
-.CS
-\fBTcl_NRCreateCommand\fR(interp, "theCommand",
- \fITheCmdNewObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
- TheCmdDeleteProc);
-.CE
.SH "SEE ALSO"
Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
.SH KEYWORDS
stackless, nonrecursive, execute, command, global, value, result, script
.SH COPYRIGHT
-Copyright (c) 2008 by Kevin B. Kenny
+Copyright (c) 2008 by Kevin B. Kenny.
+Copyright (c) 2018 by Nathan Coulter.
diff --git a/tcl8.6/doc/clock.n b/tcl8.6/doc/clock.n
index 889a5da..6efa722 100644
--- a/tcl8.6/doc/clock.n
+++ b/tcl8.6/doc/clock.n
@@ -453,6 +453,19 @@ If this situation occurs, the first occurrence of the time is chosen.
(For this reason, it is wise to have the input string contain the
time zone when converting local times. This caveat does not apply to
UTC times.)
+.PP
+If the interpretation of the groups yields an impossible time because
+a field is out of range, enough of that field's unit will be added to
+or subtracted from the time to bring it in range. Thus, if attempting to
+scan or format day 0 of the month, one day will be subtracted from day
+1 of the month, yielding the last day of the previous month.
+.PP
+If the interpretation of the groups yields an impossible time because
+a Daylight Saving Time change skips over that time, or an ambiguous
+time because a Daylight Saving Time change skips back so that the clock
+observes the given time twice, and no time zone specifier (\fB%z\fR
+or \fB%Z\fR) is present in the format, the time is interpreted as
+if the clock had not changed.
.SH "FORMAT GROUPS"
.PP
The following format groups are recognized by the \fBclock scan\fR and
diff --git a/tcl8.6/doc/define.n b/tcl8.6/doc/define.n
index 7599ec0..e619728 100644
--- a/tcl8.6/doc/define.n
+++ b/tcl8.6/doc/define.n
@@ -50,7 +50,7 @@ being constructed. Within the constructor, the \fBnext\fR command should be
used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
string, the constructor will be deleted.
.TP
-\fBdeletemethod\fI name\fR ?\fIname ...\fR
+\fBdeletemethod\fI name\fR ?\fIname ...\fR?
.
This deletes each of the methods called \fIname\fR from a class. The methods
must have previously existed in that class. Does not affect the superclasses
diff --git a/tcl8.6/doc/exec.n b/tcl8.6/doc/exec.n
index 70ace32..99dfdc5 100644
--- a/tcl8.6/doc/exec.n
+++ b/tcl8.6/doc/exec.n
@@ -217,6 +217,19 @@ information is instead sent to the console, if one is present, or is
discarded.
.RS
.PP
+Note that the current escape resp. quoting of arguments for windows works only
+with executables using CommandLineToArgv, CRT-library or similar, as well as
+with the windows batch files (excepting the newline, see below).
+Although it is the common escape algorithm, but, in fact, the way how the
+executable parses the command-line (resp. splits it into single arguments)
+is decisive.
+.PP
+Unfortunately, there is currently no way to supply newline character within
+an argument to the batch files (\fB.cmd\fR or \fB.bat\fR) or to the command
+processor (\fBcmd.exe /c\fR), because this causes truncation of command-line
+(also the argument chain) on the first newline character.
+But it works properly with an executable (using CommandLineToArgv, etc).
+.PP
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
@@ -409,6 +422,10 @@ that sometimes pop up:
With the file \fIcmp.bat\fR looking something like:
.PP
.CS
+@gcc %*
+.CE
+or like another variant using single parameters:
+.CS
@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9
.CE
.SS "WORKING WITH COMMAND BUILT-INS"
diff --git a/tcl8.6/doc/format.n b/tcl8.6/doc/format.n
index ba044f2..1c511e8 100644
--- a/tcl8.6/doc/format.n
+++ b/tcl8.6/doc/format.n
@@ -83,7 +83,7 @@ Specifies that the number should be padded on the left with
zeroes instead of spaces.
.TP 10
\fB#\fR
-Requests an alternate output form. For \fBo\fR and \fBO\fR
+Requests an alternate output form. For \fBo\fR
conversions it guarantees that the first digit is always \fB0\fR.
For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
will be added to the beginning of the result unless it is zero.
@@ -169,7 +169,7 @@ for \fBx\fR and
for \fBX\fR).
.TP 10
\fBb\fR
-Convert integer to binary string, using digits 0 and 1.
+Convert integer to unsigned binary string, using digits 0 and 1.
.TP 10
\fBc\fR
Convert integer to the Unicode character it represents.
diff --git a/tcl8.6/doc/http.n b/tcl8.6/doc/http.n
index 40ced23..7e633b3 100644
--- a/tcl8.6/doc/http.n
+++ b/tcl8.6/doc/http.n
@@ -6,14 +6,14 @@
'\" 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"
+.TH "http" n 2.9 http "Tcl Bundled Packages"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
http \- Client-side implementation of the HTTP/1.1 protocol
.SH SYNOPSIS
-\fBpackage require http ?2.7?\fR
+\fBpackage require http ?2.8?\fR
.\" See Also -useragent option documentation in body!
.sp
\fB::http::config ?\fI\-option value\fR ...?
@@ -22,6 +22,8 @@ http \- Client-side implementation of the HTTP/1.1 protocol
.sp
\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
.sp
+\fB::http::quoteString\fR \fIvalue\fR
+.sp
\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
.sp
\fB::http::wait \fItoken\fR
@@ -44,12 +46,14 @@ http \- Client-side implementation of the HTTP/1.1 protocol
.sp
\fB::http::register \fIproto port command\fR
.sp
+\fB::http::registerError \fIport\fR ?\fImessage\fR?
+.sp
\fB::http::unregister \fIproto\fR
.BE
.SH DESCRIPTION
.PP
The \fBhttp\fR package provides the client side of the HTTP/1.1
-protocol, as defined in RFC 2616.
+protocol, as defined in RFC 7230 to RFC 7235, which supersede RFC 2616.
The package implements the GET, POST, and HEAD operations
of HTTP/1.1. It allows configuration of a proxy host to get through
firewalls. The package is compatible with the \fBSafesock\fR security
@@ -95,6 +99,19 @@ comma-separated list of mime type patterns that you are
willing to receive. For example,
.QW "image/gif, image/jpeg, text/*" .
.TP
+\fB\-pipeline\fR \fIboolean\fR
+.
+Specifies whether HTTP/1.1 transactions on a persistent socket will be
+pipelined. See the \fBPERSISTENT SOCKETS\fR section for details. The default
+is 1.
+.TP
+\fB\-postfresh\fR \fIboolean\fR
+.
+Specifies whether requests that use the \fBPOST\fR method will always use a
+fresh socket, overriding the \fB-keepalive\fR option of
+command \fBhttp::geturl\fR. See the \fBPERSISTENT SOCKETS\fR section for details.
+The default is 0.
+.TP
\fB\-proxyhost\fR \fIhostname\fR
.
The name of the proxy host, if any. If this value is the
@@ -116,20 +133,47 @@ an empty list. The default filter returns the values of the
\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
non-empty.
.TP
+\fB\-repost\fR \fIboolean\fR
+.
+Specifies what to do if a POST request over a persistent connection fails
+because the server has half-closed the connection. If boolean \fBtrue\fR, the
+request
+will be automatically retried; if boolean \fBfalse\fR it will not, and the
+application
+that uses \fBhttp::geturl\fR is expected to seek user confirmation before
+retrying the POST. The value \fBtrue\fR should be used only under certain
+conditions. See the \fBPERSISTENT SOCKETS\fR section for details. The
+default is 0.
+.TP
\fB\-urlencoding\fR \fIencoding\fR
.
The \fIencoding\fR used for creating the x-url-encoded URLs with
-\fB::http::formatQuery\fR. The default is \fButf-8\fR, as specified by RFC
+\fB::http::formatQuery\fR and \fB::http::quoteString\fR.
+The default is \fButf-8\fR, as specified by RFC
2718. Prior to http 2.5 this was unspecified, and that behavior can be
returned by specifying the empty string (\fB{}\fR), although
\fIiso8859-1\fR is recommended to restore similar behavior but without the
-\fB::http::formatQuery\fR throwing an error processing non-latin-1
-characters.
+\fB::http::formatQuery\fR or \fB::http::quoteString\fR
+throwing an error processing non-latin-1 characters.
.TP
\fB\-useragent\fR \fIstring\fR
.
-The value of the User-Agent header in the HTTP request. The default is
-.QW "\fBTcl http client package 2.7\fR" .
+The value of the User-Agent header in the HTTP request. In an unsafe
+interpreter, the default value depends upon the operating system, and
+the version numbers of \fBhttp\fR and \fBTcl\fR, and is (for example)
+.QW "\fBMozilla/5.0 (Windows; U; Windows NT 10.0) http/2.8.12 Tcl/8.6.8\fR" .
+A safe interpreter cannot determine its operating system, and so the default
+in a safe interpreter is to use a Windows 10 value with the current version
+numbers of \fBhttp\fR and \fBTcl\fR.
+.TP
+\fB\-zip\fR \fIboolean\fR
+.
+If the value is boolean \fBtrue\fR, then by default requests will send a header
+.QW "\fBAccept-Encoding: gzip,deflate,compress\fR" .
+If the value is boolean \fBfalse\fR, then by default this header will not be sent.
+In either case the default can be overridden for an individual request by
+supplying a custom \fBAccept-Encoding\fR header in the \fB-headers\fR option
+of \fBhttp::geturl\fR. The default is 1.
.RE
.TP
\fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR?
@@ -227,7 +271,7 @@ Pragma: no-cache
.TP
\fB\-keepalive\fR \fIboolean\fR
.
-If true, attempt to keep the connection open for servicing
+If boolean \fBtrue\fR, attempt to keep the connection open for servicing
multiple requests. Default is 0.
.TP
\fB\-method\fR \fItype\fR
@@ -334,6 +378,11 @@ encodes the keys and values, and generates one string that has the
proper & and = separators. The result is suitable for the
\fB\-query\fR value passed to \fB::http::geturl\fR.
.TP
+\fB::http::quoteString\fR \fIvalue\fR
+.
+This procedure does x-url-encoding of string. It takes a single argument and
+encodes it.
+.TP
\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
.
This command resets the HTTP transaction identified by \fItoken\fR, if any.
@@ -415,6 +464,17 @@ set token [::http::geturl https://my.secure.site/]
.CE
.RE
.TP
+\fB::http::registerError\fR \fIport\fR ?\fImessage\fR?
+.
+This procedure allows a registered protocol handler to deliver an error
+message for use by \fBhttp\fR. Calling this command does not raise an
+error. The command is useful when a registered protocol detects an problem
+(for example, an invalid TLS certificate) that will cause an error to
+propagate to \fBhttp\fR. The command allows \fBhttp\fR to provide a
+precise error message rather than a general one. The command returns the
+value provided by the last call with argument \fImessage\fR, or the empty
+string if no such call has been made.
+.TP
\fB::http::unregister\fR \fIproto\fR
.
This procedure unregisters a protocol handler that was previously
@@ -504,6 +564,14 @@ The following elements of
the array are supported:
.RS
.TP
+\fBbinary\fR
+.
+This is boolean \fBtrue\fR if (after decoding any compression specified
+by the
+.QW "Content-Encoding"
+response header) the HTTP response is binary. It is boolean \fBfalse\fR
+if the HTTP response is text.
+.TP
\fBbody\fR
.
The contents of the URL. This will be empty if the \fB\-channel\fR
@@ -602,6 +670,106 @@ A copy of the \fBContent-Type\fR meta-data value.
.
The requested URL.
.RE
+.SH "PERSISTENT CONNECTIONS"
+.PP
+.SS "BASICS"
+.PP
+See RFC 7230 Sec 6, which supersedes RFC 2616 Sec 8.1.
+.PP
+A persistent connection allows multiple HTTP/1.1 transactions to be
+carried over the same TCP connection. Pipelining allows a
+client to make multiple requests over a persistent connection without
+waiting for each response. The server sends responses in the same order
+that the requests were received.
+.PP
+If a POST request fails to complete, typically user confirmation is
+needed before sending the request again. The user may wish to verify
+whether the server was modified by the failed POST request, before
+sending the same request again.
+.PP
+A HTTP request will use a persistent socket if the call to
+\fBhttp::geturl\fR has the option \fB-keepalive true\fR. It will use
+pipelining where permitted if the \fBhttp::config\fR option
+\fB-pipeline\fR is boolean \fBtrue\fR (its default value).
+.PP
+The http package maintains no more than one persistent connection to each
+server (i.e. each value of
+.QW "domain:port" ).
+If \fBhttp::geturl\fR is called to make a request over a persistent
+connection while the connection is busy with another request, the new
+request will be held in a queue until the connection is free.
+.PP
+The http package does not support HTTP/1.0 persistent connections
+controlled by the \fBKeep-Alive\fR header.
+.SS "SPECIAL CASES"
+.PP
+This subsection discusses issues related to closure of the
+persistent connection by the server, automatic retry of failed requests,
+the special treatment necessary for POST requests, and the options for
+dealing with these cases.
+.PP
+In accordance with RFC 7230, \fBhttp::geturl\fR does not pipeline
+requests that use the POST method. If a POST uses a persistent
+connection and is not the first request on that connection,
+\fBhttp::geturl\fR waits until it has received the response for the previous
+request; or (if \fBhttp::config\fR option \fB-postfresh\fR is boolean \fBtrue\fR) it
+uses a new connection for each POST.
+.PP
+If the server is processing a number of pipelined requests, and sends a
+response header
+.QW "\fBConnection: close\fR"
+with one of the responses (other than the last), then subsequent responses
+are unfulfilled. \fBhttp::geturl\fR will send the unfulfilled requests again
+over a new connection.
+.PP
+A difficulty arises when a HTTP client sends a request over a persistent
+connection that has been idle for a while. The HTTP server may
+half-close an apparently idle connection while the client is sending a
+request, but before the request arrives at the server: in this case (an
+.QW "asynchronous close event" )
+the request will fail. The difficulty arises because the client cannot
+be certain whether the POST modified the state of the server. For HEAD or
+GET requests, \fBhttp::geturl\fR opens another connection and retransmits
+the failed request. However, if the request was a POST, RFC 7230 forbids
+automatic retry by default, suggesting either user confirmation, or
+confirmation by user-agent software that has semantic understanding of
+the application. The \fBhttp::config\fR option \fB-repost\fR allows for
+either possibility.
+.PP
+Asynchronous close events can occur only in a short interval of time. The
+\fBhttp\fR package monitors each persistent connection for closure by the
+server. Upon detection, the connection is also closed at the client end,
+and subsequent requests will use a fresh connection.
+.PP
+If the \fBhttp::geturl\fR command is called with option \fB-keepalive true\fR,
+then it will both try to use an existing persistent connection
+(if one is available), and it will send the server a
+.QW "\fBConnection: keep-alive\fR"
+request header asking to keep the connection open for future requests.
+.PP
+The \fBhttp::config\fR options \fB-pipeline\fR, \fB-postfresh\fR, and
+\fB-repost\fR relate to persistent connections.
+.PP
+Option \fB-pipeline\fR, if boolean \fBtrue\fR, will pipeline GET and HEAD requests
+made
+over a persistent connection. POST requests will not be pipelined - if the
+POST is not the first transaction on the connection, its request will not
+be sent until the previous response has finished. GET and HEAD requests
+made after a POST will not be sent until the POST response has been
+delivered, and will not be sent if the POST fails.
+.PP
+Option \fB-postfresh\fR, if boolean \fBtrue\fR, will override the \fBhttp::geturl\fR option
+\fB-keepalive\fR, and always open a fresh connection for a POST request.
+.PP
+Option \fB-repost\fR, if \fBtrue\fR, permits automatic retry of a POST request
+that fails because it uses a persistent connection that the server has
+half-closed (an
+.QW "asynchronous close event" ).
+Subsequent GET and HEAD requests in a failed pipeline will also be retried.
+\fIThe -repost option should be used only if the application understands
+that the retry is appropriate\fR - specifically, the application must know
+that if the failed POST successfully modified the state of the server, a repeat POST
+would have no adverse effect.
.SH EXAMPLE
.PP
This example creates a procedure to copy a URL to a file while printing a
diff --git a/tcl8.6/doc/lreplace.n b/tcl8.6/doc/lreplace.n
index d19f0cd..32b7356 100644
--- a/tcl8.6/doc/lreplace.n
+++ b/tcl8.6/doc/lreplace.n
@@ -17,7 +17,7 @@ lreplace \- Replace elements in a list with new elements
.BE
.SH DESCRIPTION
.PP
-\fBlreplace\fR returns a new list formed by replacing one or more elements of
+\fBlreplace\fR returns a new list formed by replacing zero or more elements of
\fIlist\fR with the \fIelement\fR arguments.
\fIfirst\fR and \fIlast\fR are index values specifying the first and
last elements of the range to replace.
@@ -27,23 +27,26 @@ supporting simple index arithmetic and indices relative to the
end of the list.
0 refers to the first element of the
list, and \fBend\fR refers to the last element of the list.
-If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored.
.PP
-If \fIfirst\fR is less than zero, it is considered to refer to before the
-first element of the list. For non-empty lists, the element indicated
-by \fIfirst\fR must exist or \fIfirst\fR must indicate before the
-start of the list.
+If either \fIfirst\fR or \fIlast\fR is less than zero, it is considered
+to refer to before the first element of the list. This allows \fBlreplace\fR
+to prepend elements to \fIlist\fR.
+.VS TIP505
+If either \fIfirst\fR or \fIlast\fR indicates a position greater than the
+index of the last element of the list, it is treated as if it is an
+index one greater than the last element. This allows \fBlreplace\fR to
+append elements to \fIlist\fR.
+.VE TIP505
.PP
If \fIlast\fR is less than \fIfirst\fR, then any specified elements
-will be inserted into the list before the point specified by \fIfirst\fR
+will be inserted into the list before the element specified by \fIfirst\fR
with no elements being deleted.
.PP
-The \fIelement\fR arguments specify zero or more new arguments to
+The \fIelement\fR arguments specify zero or more new elements to
be added to the list in place of those that were deleted.
Each \fIelement\fR argument will become a separate element of
the list. If no \fIelement\fR arguments are specified, then the elements
-between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR
-is empty, any \fIelement\fR arguments are added to the end of the list.
+between \fIfirst\fR and \fIlast\fR are simply deleted.
.SH EXAMPLES
.PP
Replacing an element of a list with another:
@@ -78,9 +81,26 @@ proc lremove {listVariable value} {
set var [\fBlreplace\fR $var $idx $idx]
}
.CE
+.PP
+.VS TIP505
+Appending elements to the list; note that \fBend+2\fR will initially
+be treated as if it is \fB6\fR here, but both that and \fB12345\fR are greater
+than the index of the final item so they behave identically:
+.PP
+.CS
+% set var {a b c d e}
+a b c d e
+% set var [\fBlreplace\fR $var 12345 end+2 f g h i]
+a b c d e f g h i
+.CE
+.VE TIP505
.SH "SEE ALSO"
list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
lset(n), lrange(n), lsort(n),
string(n)
.SH KEYWORDS
element, list, replace
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/tcl8.6/doc/string.n b/tcl8.6/doc/string.n
index 00ce85c..7e666ea 100644
--- a/tcl8.6/doc/string.n
+++ b/tcl8.6/doc/string.n
@@ -115,9 +115,7 @@ Any Unicode control character.
Any Unicode digit character. Note that this includes characters
outside of the [0\-9] range.
.IP \fBdouble\fR 12
-Any of the valid forms for a double in Tcl, with optional surrounding
-whitespace. In case of under/overflow in the value, 0 is returned and
-the \fIvarname\fR will contain \-1.
+Any of the forms allowed to \fBTcl_GetDoubleFromObj\fR.
.IP \fBentier\fR 12
.VS 8.6
Any of the valid string formats for an integer value of arbitrary size
@@ -131,7 +129,7 @@ false.
Any Unicode printing character, except space.
.IP \fBinteger\fR 12
Any of the valid string formats for a 32-bit integer value in Tcl,
-with optional surrounding whitespace. In case of under/overflow in
+with optional surrounding whitespace. In case of overflow in
the value, 0 is returned and the \fIvarname\fR will contain \-1.
.IP \fBlist\fR 12
Any proper list structure, with optional surrounding whitespace. In
@@ -156,7 +154,7 @@ true.
Any upper case alphabet character in the Unicode character set.
.IP \fBwideinteger\fR 12
Any of the valid forms for a wide integer in Tcl, with optional
-surrounding whitespace. In case of under/overflow in the value, 0 is
+surrounding whitespace. In case of overflow in the value, 0 is
returned and the \fIvarname\fR will contain \-1.
.IP \fBwordchar\fR 12
Any Unicode word character. That is any alphanumeric character, and
diff --git a/tcl8.6/doc/tcltest.n b/tcl8.6/doc/tcltest.n
index 05c1922..b161a2b 100644
--- a/tcl8.6/doc/tcltest.n
+++ b/tcl8.6/doc/tcltest.n
@@ -8,7 +8,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"
+.TH "tcltest" n 2.5 tcltest "Tcl Bundled Packages"
.so man.macros
.BS
'\" Note: do not modify the .SH NAME line immediately below!
@@ -16,7 +16,7 @@
tcltest \- Test harness support code and utilities
.SH SYNOPSIS
.nf
-\fBpackage require tcltest\fR ?\fB2.3\fR?
+\fBpackage require tcltest\fR ?\fB2.5\fR?
\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
@@ -454,6 +454,7 @@ The valid options for \fBtest\fR are summarized:
?\fB\-output \fIexpectedOutput\fR?
?\fB\-errorOutput \fIexpectedError\fR?
?\fB\-returnCodes \fIcodeList\fR?
+ ?\fB\-errorCode \fIexpectedErrorCode\fR?
?\fB\-match \fImode\fR?
.CE
.PP
@@ -577,6 +578,15 @@ return codes known to \fBreturn\fR, in both numeric and symbolic
form, including extended return codes, are acceptable elements in
the \fIexpectedCodeList\fR. Default value is
.QW "\fBok return\fR" .
+.TP
+\fB\-errorCode \fIexpectedErrorCode\fR
+.
+The optional \fB\-errorCode\fR attribute supplies \fIexpectedErrorCode\fR,
+a glob pattern that should match the error code reported from evaluation of the
+\fB\-body\fR script. If evaluation of the \fB\-body\fR script returns
+a code not matching \fIexpectedErrorCode\fR, the test fails. Default value is
+.QW "\fB*\fR" .
+If \fB\-returnCodes\fR does not include \fBerror\fR it is set to \fBerror\fR.
.PP
To pass, a test must successfully evaluate its \fB\-setup\fR, \fB\-body\fR,
and \fB\-cleanup\fR scripts. The return code of the \fB\-body\fR script and
diff --git a/tcl8.6/generic/regc_locale.c b/tcl8.6/generic/regc_locale.c
index 8f67a52..2f79026 100644
--- a/tcl8.6/generic/regc_locale.c
+++ b/tcl8.6/generic/regc_locale.c
@@ -137,8 +137,8 @@ static const crange alphaRangeTable[] = {
{0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
{0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
{0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
- {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
- {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
+ {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x560, 0x588},
+ {0x5d0, 0x5ea}, {0x5ef, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
{0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
{0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4},
{0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980},
@@ -165,45 +165,42 @@ static const crange alphaRangeTable[] = {
{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},
+ {0x1820, 0x1878}, {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}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4},
- {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d},
- {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149},
- {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee},
- {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6},
- {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
- {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035},
- {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff},
- {0x3105, 0x312e}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff},
- {0x3400, 0x4db5}, {0x4e00, 0x9fea}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd},
- {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d},
- {0xa6a0, 0xa6e5}, {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}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28},
- {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf},
- {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4},
- {0xab01, 0xab06}, {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}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
- {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74},
- {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
- {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
-#if TCL_UTF_MAX > 4
+ {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba},
+ {0x1cbd, 0x1cbf}, {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}, {0x1fd6, 0x1fdb},
+ {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c},
+ {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139},
+ {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
+ {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67},
+ {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
+ {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
+ {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f},
+ {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e},
+ {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef},
+ {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f},
+ {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f},
+ {0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
+ {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3},
+ {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c},
+ {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe},
+ {0xaa00, 0xaa28}, {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76},
+ {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea},
+ {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
+ {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65},
+ {0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
+ {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
+ {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
+ {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
+ {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a},
+ {0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
+ {0xffda, 0xffdc}
+#if CHRBITS > 16
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
{0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
@@ -212,23 +209,25 @@ static const crange alphaRangeTable[] = {
{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},
+ {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {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}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
+ {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c},
+ {0x10f30, 0x10f45}, {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, 0x1171a},
+ {0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
{0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e},
- {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {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}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
+ {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65},
+ {0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {0x12000, 0x12399}, {0x12480, 0x12543},
+ {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
+ {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
+ {0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
+ {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
{0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
@@ -264,17 +263,18 @@ static const chr alphaCharTable[] = {
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
+ 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1,
+ 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
+ 0xfb44
+#if CHRBITS > 16
,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, 0x11a00,
- 0x11a3a, 0x11a50, 0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x16f50, 0x16fe0, 0x16fe1,
- 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
+ 0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f,
+ 0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644,
+ 0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46,
+ 0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 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
};
@@ -288,7 +288,7 @@ static const crange controlRangeTable[] = {
{0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f},
{0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
{0xfff9, 0xfffb}
-#if TCL_UTF_MAX > 4
+#if CHRBITS > 16
,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
{0x100000, 0x10fffd}
#endif
@@ -298,8 +298,8 @@ static const crange controlRangeTable[] = {
static const chr controlCharTable[] = {
0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
-#if TCL_UTF_MAX > 4
- ,0x110bd, 0xe0001
+#if CHRBITS > 16
+ ,0x110bd, 0x110cd, 0xe0001
#endif
};
@@ -320,12 +320,12 @@ static const crange digitRangeTable[] = {
{0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
{0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
{0xff10, 0xff19}
-#if TCL_UTF_MAX > 4
- ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
- {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
- {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
- {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
- {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
+#if CHRBITS > 16
+ ,{0x104a0, 0x104a9}, {0x10d30, 0x10d39}, {0x11066, 0x1106f}, {0x110f0, 0x110f9},
+ {0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459},
+ {0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739},
+ {0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9},
+ {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
#endif
};
@@ -348,19 +348,20 @@ 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, 0x2e49},
+ {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4e},
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
{0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
{0xff5f, 0xff65}
-#if TCL_UTF_MAX > 4
+#if CHRBITS > 16
,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
- {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
- {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
- {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
- {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45},
- {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
+ {0x10b99, 0x10b9c}, {0x10f55, 0x10f59}, {0x11047, 0x1104d}, {0x110be, 0x110c1},
+ {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x111dd, 0x111df}, {0x11238, 0x1123d},
+ {0x1144b, 0x1144f}, {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c},
+ {0x1173c, 0x1173e}, {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2},
+ {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x16e97, 0x16e9a},
+ {0x1da87, 0x1da8b}
#endif
};
@@ -371,18 +372,20 @@ static const chr punctCharTable[] = {
0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
- 0x9fd, 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9,
- 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736,
- 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e,
- 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe,
- 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673,
- 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df,
- 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68,
- 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
-#if TCL_UTF_MAX > 4
+ 0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14,
+ 0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c,
+ 0x1735, 0x1736, 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3,
+ 0x207d, 0x207e, 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc,
+ 0x29fd, 0x2cfe, 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe,
+ 0xa4ff, 0xa673, 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f,
+ 0xa9de, 0xa9df, 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f,
+ 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f,
+ 0xff5b, 0xff5d
+#if CHRBITS > 16
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
- 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
- 0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
+ 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b,
+ 0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f,
+ 0x1e95e, 0x1e95f
#endif
};
@@ -413,25 +416,25 @@ static const crange lowerRangeTable[] = {
{0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
{0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
{0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
- {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
- {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
+ {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x560, 0x588}, {0x10d0, 0x10fa},
+ {0x10fd, 0x10ff}, {0x13f8, 0x13fd}, {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 CHRBITS > 16
,{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}
+ {0x16e60, 0x16e7f}, {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
};
@@ -501,8 +504,8 @@ static const chr lowerCharTable[] = {
0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
- 0xa7b5, 0xa7b7, 0xa7fa
-#if TCL_UTF_MAX > 4
+ 0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa
+#if CHRBITS > 16
,0x1d4bb, 0x1d7cb
#endif
};
@@ -518,20 +521,22 @@ static const crange upperRangeTable[] = {
{0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
{0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
{0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5},
- {0x13a0, 0x13f5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f},
- {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb},
- {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, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
-#if TCL_UTF_MAX > 4
+ {0x13a0, 0x13f5}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf}, {0x1f08, 0x1f0f},
+ {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d},
+ {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {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, 0xa7ae},
+ {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
+#if CHRBITS > 16
,{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}
+ {0x16e40, 0x16e5f}, {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
};
@@ -600,8 +605,9 @@ static const chr upperCharTable[] = {
0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766,
0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
- 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6
-#if TCL_UTF_MAX > 4
+ 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6,
+ 0xa7b8
+#if CHRBITS > 16
,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
0x1d539, 0x1d546, 0x1d7ca
#endif
@@ -616,85 +622,80 @@ static const chr upperCharTable[] = {
static const crange graphRangeTable[] = {
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
- {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
- {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
- {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
- {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a},
- {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983},
- {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
- {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fd},
- {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}, {0xaf9, 0xaff},
- {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},
- {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 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}, {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4},
- {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47},
- {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc},
- {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 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},
- {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
- {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c},
- {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c},
- {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9},
- {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa},
- {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b},
- {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
- {0x19d0, 0x19da}, {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, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf9},
- {0x1d00, 0x1df9}, {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, 0x20bf}, {0x20d0, 0x20f0},
- {0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
- {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd2},
- {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
+ {0x559, 0x58a}, {0x58d, 0x58f}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
+ {0x5ef, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d},
+ {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x7fd, 0x82d},
+ {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, {0x8a0, 0x8b4},
+ {0x8b6, 0x8bd}, {0x8d3, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
+ {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
+ {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fe}, {0xa01, 0xa03},
+ {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
+ {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa76}, {0xa81, 0xa83},
+ {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
+ {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
+ {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, {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, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
+ {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
+ {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c},
+ {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
+ {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
+ {0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
+ {0xd12, 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}, {0xead, 0xeb9}, {0xebb, 0xebd},
+ {0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf},
+ {0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc},
+ {0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 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}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5},
+ {0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
+ {0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
+ {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
+ {0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878},
+ {0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b},
+ {0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
+ {0x19b0, 0x19c9}, {0x19d0, 0x19da}, {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, 0x1c88}, {0x1c90, 0x1cba},
+ {0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {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, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426},
+ {0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8},
+ {0x2bca, 0x2bfe}, {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, 0x2e49},
+ {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4e},
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
- {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e},
+ {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f},
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
- {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c},
- {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
- {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
- {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},
- {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed},
- {0xabf0, 0xabf9}, {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},
- {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f},
- {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19},
- {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
- {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
- {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
-#if TCL_UTF_MAX > 4
+ {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c},
+ {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9},
+ {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5},
+ {0xa8ce, 0xa8d9}, {0xa8e0, 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}, {0xab20, 0xab26}, {0xab28, 0xab2e},
+ {0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
+ {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
+ {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c},
+ {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7},
+ {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66},
+ {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe},
+ {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc},
+ {0xffe0, 0xffe6}, {0xffe8, 0xffee}
+#if CHRBITS > 16
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
{0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
@@ -705,80 +706,85 @@ static const crange graphRangeTable[] = {
{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},
+ {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a38, 0x10a3a},
+ {0x10a3f, 0x10a48}, {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},
- {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2},
- {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
- {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
- {0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59},
+ {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39},
+ {0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d},
+ {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8},
+ {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {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},
+ {0x1133b, 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, 0x1171a},
+ {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2},
+ {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8},
+ {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c},
+ {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06},
+ {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65},
+ {0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8},
{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}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {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},
- {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f8},
- {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
- {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b},
- {0x1f910, 0x1f93e}, {0x1f940, 0x1f94c}, {0x1f950, 0x1f96b}, {0x1f980, 0x1f997},
- {0x1f9d0, 0x1f9e6}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
- {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
+ {0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
+ {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
+ {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
+ {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
+ {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356},
+ {0x1d360, 0x1d378}, {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}, {0x1ec71, 0x1ecb4},
+ {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, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
+ {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4},
+ {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8},
+ {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887},
+ {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970},
+ {0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2},
+ {0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
+ {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d},
+ {0xe0100, 0xe01ef}
#endif
};
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
static const chr graphCharTable[] = {
- 0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
- 0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
- 0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
- 0xad0, 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, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82,
- 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab,
- 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
- 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e,
- 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
-#if TCL_UTF_MAX > 4
+ 0x38c, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, 0x9d7, 0x9dc,
+ 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39,
+ 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, 0xad0, 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,
+ 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87,
+ 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7,
+ 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, 0x1f5b, 0x1f5d,
+ 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44, 0xfffc, 0xfffd
+#if CHRBITS > 16
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
- 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x11d08, 0x11d09,
- 0x11d3a, 0x11d3c, 0x11d3d, 0x16a6e, 0x16a6f, 0x16fe0, 0x16fe1, 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, 0x1f9c0
+ 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08,
+ 0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e,
+ 0x16a6f, 0x16fe0, 0x16fe1, 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, 0x1f97a
#endif
};
diff --git a/tcl8.6/generic/tcl.decls b/tcl8.6/generic/tcl.decls
index db1f892..b62cd28 100644
--- a/tcl8.6/generic/tcl.decls
+++ b/tcl8.6/generic/tcl.decls
@@ -2370,6 +2370,10 @@ export {
void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
}
export {
+ void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
+ Tcl_Interp *interp)
+}
+export {
const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
int exact)
}
diff --git a/tcl8.6/generic/tcl.h b/tcl8.6/generic/tcl.h
index b43b2d7..17ab2d3 100644
--- a/tcl8.6/generic/tcl.h
+++ b/tcl8.6/generic/tcl.h
@@ -42,10 +42,6 @@ extern "C" {
* win/configure.in (as above)
* win/tcl.m4 (not patchlevel)
* README (sections 0 and 2, with and without separator)
- * macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC
- * macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC
- * macosx/Tcl.xcode/project.pbxproj (not patchlevel) 2 LOC
- * macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
* macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
* win/README (not patchlevel) (sections 0 and 2)
* unix/tcl.spec (1 LOC patch)
@@ -55,10 +51,10 @@ extern "C" {
#define TCL_MAJOR_VERSION 8
#define TCL_MINOR_VERSION 6
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
-#define TCL_RELEASE_SERIAL 8
+#define TCL_RELEASE_SERIAL 9
#define TCL_VERSION "8.6"
-#define TCL_PATCH_LEVEL "8.6.8"
+#define TCL_PATCH_LEVEL "8.6.9"
/*
*----------------------------------------------------------------------------
@@ -1986,7 +1982,7 @@ typedef struct Tcl_Token {
* TCL_TOKEN_OPERATOR - The token describes one expression operator.
* An operator might be the name of a math
* function such as "abs". A TCL_TOKEN_OPERATOR
- * token is always preceeded by one
+ * token is always preceded by one
* TCL_TOKEN_SUB_EXPR token for the operator's
* subexpression, and is followed by zero or more
* TCL_TOKEN_SUB_EXPR tokens for the operator's
@@ -2622,7 +2618,7 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
#ifndef TCL_NO_DEPRECATED
/*
* These function have been renamed. The old names are deprecated, but we
- * define these macros for backwards compatibilty.
+ * define these macros for backwards compatibility.
*/
# define Tcl_Ckalloc Tcl_Alloc
diff --git a/tcl8.6/generic/tclAssembly.c b/tcl8.6/generic/tclAssembly.c
index 120fd9a..b6bebb6 100644
--- a/tcl8.6/generic/tclAssembly.c
+++ b/tcl8.6/generic/tclAssembly.c
@@ -2248,23 +2248,24 @@ GetListIndexOperand(
Tcl_Token* tokenPtr = *tokenPtrPtr;
/* INOUT: Pointer to the next token in the
* source code */
- Tcl_Obj* intObj; /* Integer from the source code */
- int status; /* Tcl status return */
-
- /*
- * Extract the next token as a string.
- */
+ Tcl_Obj *value;
+ int status;
- if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
+ /* General operand validity check */
+ if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) {
return TCL_ERROR;
}
-
+
+ /* Convert to an integer, advance to the next token and return. */
/*
- * Convert to an integer, advance to the next token and return.
+ * NOTE: Indexing a list with an index before it yields the
+ * same result as indexing after it, and might be more easily portable
+ * when list size limits grow.
*/
+ status = TclIndexEncode(interp, value,
+ TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
- status = TclGetIntForIndex(interp, intObj, -2, result);
- Tcl_DecrRefCount(intObj);
+ Tcl_DecrRefCount(value);
*tokenPtrPtr = TokenAfter(tokenPtr);
return status;
}
diff --git a/tcl8.6/generic/tclBasic.c b/tcl8.6/generic/tclBasic.c
index ddc828a..e014b06 100644
--- a/tcl8.6/generic/tclBasic.c
+++ b/tcl8.6/generic/tclBasic.c
@@ -234,7 +234,7 @@ static const CmdInfo builtInCmds[] = {
{"lsearch", Tcl_LsearchObjCmd, NULL, NULL, CMD_IS_SAFE},
{"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, NULL, CMD_IS_SAFE},
{"lsort", Tcl_LsortObjCmd, NULL, NULL, CMD_IS_SAFE},
- {"package", Tcl_PackageObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"package", Tcl_PackageObjCmd, NULL, TclNRPackageObjCmd, CMD_IS_SAFE},
{"proc", Tcl_ProcObjCmd, NULL, NULL, CMD_IS_SAFE},
{"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, CMD_IS_SAFE},
{"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, CMD_IS_SAFE},
@@ -2087,13 +2087,13 @@ Tcl_CreateCommand(
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
- if (isNew || deleted) {
+ if (isNew || deleted) {
/*
* isNew - No conflict with existing command.
* deleted - We've already deleted a conflicting command
*/
break;
- }
+ }
/* An existing command conflicts. Try to delete it.. */
cmdPtr = Tcl_GetHashValue(hPtr);
@@ -2234,64 +2234,82 @@ Tcl_CreateObjCommand(
* name. */
ClientData clientData, /* Arbitrary value to pass to object
* function. */
- Tcl_CmdDeleteProc *deleteProc)
+ Tcl_CmdDeleteProc *deleteProc
/* If not NULL, gives a function to call when
* this command is deleted. */
+)
{
Interp *iPtr = (Interp *) interp;
- ImportRef *oldRefPtr = NULL;
Namespace *nsPtr;
- Command *cmdPtr;
- Tcl_HashEntry *hPtr;
const char *tail;
- int isNew = 0, deleted = 0;
- ImportedCmdData *dataPtr;
if (iPtr->flags & DELETED) {
/*
* The interpreter is being deleted. Don't create any new commands;
* it's not safe to muck with the interpreter anymore.
*/
-
return (Tcl_Command) NULL;
}
/*
+ * Determine where the command should reside. If its name contains
+ * namespace qualifiers, we put it in the specified namespace;
+ * otherwise, we always put it in the global namespace.
+ */
+
+ if (strstr(cmdName, "::") != NULL) {
+ Namespace *dummy1, *dummy2;
+
+ TclGetNamespaceForQualName(interp, cmdName, NULL,
+ TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+ if ((nsPtr == NULL) || (tail == NULL)) {
+ return (Tcl_Command) NULL;
+ }
+ } else {
+ nsPtr = iPtr->globalNsPtr;
+ tail = cmdName;
+ }
+
+ return TclCreateObjCommandInNs(interp, tail, (Tcl_Namespace *) nsPtr,
+ proc, clientData, deleteProc);
+}
+
+Tcl_Command
+TclCreateObjCommandInNs (
+ Tcl_Interp *interp,
+ const char *cmdName, /* Name of command, without any namespace components */
+ Tcl_Namespace *namespace, /* The namespace to create the command in */
+ Tcl_ObjCmdProc *proc, /* Object-based function to associate with
+ * name. */
+ ClientData clientData, /* Arbitrary value to pass to object
+ * function. */
+ Tcl_CmdDeleteProc *deleteProc
+ /* If not NULL, gives a function to call when
+ * this command is deleted. */
+) {
+ int deleted = 0, isNew = 0;
+ Command *cmdPtr;
+ ImportRef *oldRefPtr = NULL;
+ ImportedCmdData *dataPtr;
+ Tcl_HashEntry *hPtr;
+ Namespace *nsPtr = (Namespace *) namespace;
+ /*
* If the command name we seek to create already exists, we need to
* delete that first. That can be tricky in the presence of traces.
* Loop until we no longer find an existing command in the way, or
* until we've deleted one command and that didn't finish the job.
*/
-
while (1) {
- /*
- * Determine where the command should reside. If its name contains
- * namespace qualifiers, we put it in the specified namespace;
- * otherwise, we always put it in the global namespace.
- */
-
- if (strstr(cmdName, "::") != NULL) {
- Namespace *dummy1, *dummy2;
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
- TclGetNamespaceForQualName(interp, cmdName, NULL,
- TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
- if ((nsPtr == NULL) || (tail == NULL)) {
- return (Tcl_Command) NULL;
- }
- } else {
- nsPtr = iPtr->globalNsPtr;
- tail = cmdName;
- }
-
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
-
- if (isNew || deleted) {
+ if (isNew || deleted) {
/*
* isNew - No conflict with existing command.
* deleted - We've already deleted a conflicting command
*/
break;
- }
+ }
+
/* An existing command conflicts. Try to delete it.. */
cmdPtr = Tcl_GetHashValue(hPtr);
@@ -2325,7 +2343,13 @@ Tcl_CreateObjCommand(
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
}
+ /* Make sure namespace doesn't get deallocated. */
+ cmdPtr->nsPtr->refCount++;
+
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+ nsPtr = (Namespace *) TclEnsureNamespace(interp,
+ (Tcl_Namespace *)cmdPtr->nsPtr);
+ TclNsDecrRefCount(cmdPtr->nsPtr);
if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
oldRefPtr = cmdPtr->importRefPtr;
@@ -2334,7 +2358,6 @@ Tcl_CreateObjCommand(
TclCleanupCommandMacro(cmdPtr);
deleted = 1;
}
-
if (!isNew) {
/*
* If the deletion callback recreated the command, just throw away
@@ -2356,7 +2379,7 @@ Tcl_CreateObjCommand(
* commands.
*/
- TclInvalidateCmdLiteral(interp, tail, nsPtr);
+ TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
/*
* The list of command exported from the namespace might have changed.
@@ -2586,10 +2609,6 @@ TclRenameCommand(
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
return TCL_ERROR;
}
- cmdNsPtr = cmdPtr->nsPtr;
- oldFullName = Tcl_NewObj();
- Tcl_IncrRefCount(oldFullName);
- Tcl_GetCommandFullName(interp, cmd, oldFullName);
/*
* If the new command name is NULL or empty, delete the command. Do this
@@ -2598,10 +2617,14 @@ TclRenameCommand(
if ((newName == NULL) || (*newName == '\0')) {
Tcl_DeleteCommandFromToken(interp, cmd);
- result = TCL_OK;
- goto done;
+ return TCL_OK;
}
+ cmdNsPtr = cmdPtr->nsPtr;
+ oldFullName = Tcl_NewObj();
+ Tcl_IncrRefCount(oldFullName);
+ Tcl_GetCommandFullName(interp, cmd, oldFullName);
+
/*
* Make sure that the destination command does not already exist. The
* rename operation is like creating a command, so we should automatically
@@ -3100,7 +3123,7 @@ Tcl_DeleteCommandFromToken(
/*
* We must delete this command, even though both traces and delete procs
* may try to avoid this (renaming the command etc). Also traces and
- * delete procs may try to delete the command themsevles. This flag
+ * delete procs may try to delete the command themselves. This flag
* declares that a delete is in progress and that recursive deletes should
* be ignored.
*/
@@ -3113,6 +3136,7 @@ Tcl_DeleteCommandFromToken(
*/
cmdPtr->nsPtr->refCount++;
+
if (cmdPtr->tracePtr != NULL) {
CommandTrace *tracePtr;
CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
@@ -4428,6 +4452,8 @@ TclNRRunCallbacks(
(void) Tcl_GetObjResult(interp);
}
+ /* This is the trampoline. */
+
while (TOP_CB(interp) != rootPtr) {
callbackPtr = TOP_CB(interp);
procPtr = callbackPtr->procPtr;
@@ -7580,7 +7606,19 @@ ExprEntierFunc(
if (type == TCL_NUMBER_DOUBLE) {
d = *((const double *) ptr);
- if ((d >= (double)LONG_MAX) || (d <= (double)LONG_MIN)) {
+ if ((d < (double)LONG_MAX) && (d > (double)LONG_MIN)) {
+ long result = (long) d;
+
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
+ return TCL_OK;
+#ifndef TCL_WIDE_INT_IS_LONG
+ } else if ((d < (double)LLONG_MAX) && (d > (double)LLONG_MIN)) {
+ Tcl_WideInt result = (Tcl_WideInt) d;
+
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
+ return TCL_OK;
+#endif
+ } else {
mp_int big;
if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
@@ -7589,11 +7627,6 @@ ExprEntierFunc(
}
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
return TCL_OK;
- } else {
- long result = (long) d;
-
- Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
- return TCL_OK;
}
}
@@ -7702,8 +7735,8 @@ ExprRandFunc(
iPtr->flags |= RAND_SEED_INITIALIZED;
/*
- * Take into consideration the thread this interp is running in order
- * to insure different seeds in different threads (bug #416643)
+ * To ensure different seeds in different threads (bug #416643),
+ * take into consideration the thread this interp is running in.
*/
iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
@@ -8167,6 +8200,22 @@ Tcl_NRCreateCommand(
cmdPtr->nreProc = nreProc;
return (Tcl_Command) cmdPtr;
}
+
+Tcl_Command
+TclNRCreateCommandInNs (
+ Tcl_Interp *interp,
+ const char *cmdName,
+ Tcl_Namespace *nsPtr,
+ Tcl_ObjCmdProc *proc,
+ Tcl_ObjCmdProc *nreProc,
+ ClientData clientData,
+ Tcl_CmdDeleteProc *deleteProc) {
+ Command *cmdPtr = (Command *)
+ TclCreateObjCommandInNs(interp,cmdName,nsPtr,proc,clientData,deleteProc);
+
+ cmdPtr->nreProc = nreProc;
+ return (Tcl_Command) cmdPtr;
+}
/****************************************************************************
* Stuff for the public api
@@ -8360,18 +8409,12 @@ TclNRTailcallObjCmd(
if (objc > 1) {
Tcl_Obj *listPtr, *nsObjPtr;
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
- Tcl_Namespace *ns1Ptr;
/* The tailcall data is in a Tcl list: the first element is the
* namespace, the rest the command to be tailcalled. */
- listPtr = Tcl_NewListObj(objc, objv);
-
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
- if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
- || (nsPtr != ns1Ptr)) {
- Tcl_Panic("Tailcall failed to find the proper namespace");
- }
+ listPtr = Tcl_NewListObj(objc, objv);
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
iPtr->varFramePtr->tailcallPtr = listPtr;
@@ -8952,9 +8995,9 @@ TclNRCoroutineObjCmd(
{
Command *cmdPtr;
CoroutineData *corPtr;
- const char *fullName, *procName;
- Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
- Tcl_DString ds;
+ const char *procName, *simpleName;
+ Namespace *nsPtr, *altNsPtr, *cxtNsPtr,
+ *inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
if (objc < 3) {
@@ -8962,34 +9005,21 @@ TclNRCoroutineObjCmd(
return TCL_ERROR;
}
- /*
- * FIXME: this is copy/pasted from Tcl_ProcObjCommand. Should have
- * something in tclUtil.c to find the FQ name.
- */
-
- fullName = TclGetString(objv[1]);
- TclGetNamespaceForQualName(interp, fullName, NULL, 0,
- &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
+ procName = TclGetString(objv[1]);
+ TclGetNamespaceForQualName(interp, procName, inNsPtr, 0,
+ &nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
if (nsPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create procedure \"%s\": unknown namespace",
- fullName));
+ procName));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
return TCL_ERROR;
}
- if (procName == NULL) {
+ if (simpleName == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create procedure \"%s\": bad procedure name",
- fullName));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL);
- return TCL_ERROR;
- }
- if ((nsPtr != iPtr->globalNsPtr)
- && (procName != NULL) && (procName[0] == ':')) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't create procedure \"%s\" in non-global namespace with"
- " name starting with \":\"", procName));
+ procName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
return TCL_ERROR;
}
@@ -9001,16 +9031,9 @@ TclNRCoroutineObjCmd(
corPtr = ckalloc(sizeof(CoroutineData));
- Tcl_DStringInit(&ds);
- if (nsPtr != iPtr->globalNsPtr) {
- Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
- TclDStringAppendLiteral(&ds, "::");
- }
- Tcl_DStringAppend(&ds, procName, -1);
-
- cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
- /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
- Tcl_DStringFree(&ds);
+ cmdPtr = (Command *) TclNRCreateCommandInNs(interp, simpleName,
+ (Tcl_Namespace *)nsPtr, /*objProc*/ NULL, TclNRInterpCoroutine,
+ corPtr, DeleteCoroutine);
corPtr->cmdPtr = cmdPtr;
cmdPtr->refCount++;
@@ -9071,7 +9094,7 @@ TclNRCoroutineObjCmd(
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
NULL, NULL, NULL);
- /* insure that the command is looked up in the correct namespace */
+ /* ensure that the command is looked up in the correct namespace */
iPtr->lookupNsPtr = lookupNsPtr;
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
iPtr->numLevels--;
diff --git a/tcl8.6/generic/tclBinary.c b/tcl8.6/generic/tclBinary.c
index bb918f2..571eb07 100644
--- a/tcl8.6/generic/tclBinary.c
+++ b/tcl8.6/generic/tclBinary.c
@@ -2914,6 +2914,11 @@ BinaryDecode64(
} else if (i > 1) {
c = '=';
} else {
+ if (strict && i <= 1) {
+ /* single resp. unfulfilled char (each 4th next single char)
+ * is rather bad64 error case in strict mode */
+ goto bad64;
+ }
cut += 3;
break;
}
@@ -2944,9 +2949,11 @@ BinaryDecode64(
value = (value << 6) | 0x3e;
} else if (c == '/') {
value = (value << 6) | 0x3f;
- } else if (c == '=') {
+ } else if (c == '=' && (
+ !strict || i > 1) /* "=" and "a=" is rather bad64 error case in strict mode */
+ ) {
value <<= 6;
- cut++;
+ if (i) cut++;
} else if (strict || !isspace(c)) {
goto bad64;
} else {
diff --git a/tcl8.6/generic/tclCmdAH.c b/tcl8.6/generic/tclCmdAH.c
index a48dfc7..7e117af 100644
--- a/tcl8.6/generic/tclCmdAH.c
+++ b/tcl8.6/generic/tclCmdAH.c
@@ -513,63 +513,6 @@ Tcl_ContinueObjCmd(
}
/*
- *----------------------------------------------------------------------
- *
- * Tcl_EncodingObjCmd --
- *
- * This command manipulates encodings.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tcl_EncodingObjCmd(
- ClientData dummy, /* Not used. */
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- int index;
-
- static const char *const optionStrings[] = {
- "convertfrom", "convertto", "dirs", "names", "system",
- NULL
- };
- enum options {
- ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM
- };
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
-
- switch ((enum options) index) {
- case ENC_CONVERTTO:
- return EncodingConverttoObjCmd(dummy, interp, objc, objv);
- case ENC_CONVERTFROM:
- return EncodingConvertfromObjCmd(dummy, interp, objc, objv);
- case ENC_DIRS:
- return EncodingDirsObjCmd(dummy, interp, objc, objv);
- case ENC_NAMES:
- return EncodingNamesObjCmd(dummy, interp, objc, objv);
- case ENC_SYSTEM:
- return EncodingSystemObjCmd(dummy, interp, objc, objv);
- }
- return TCL_OK;
-}
-
-/*
*-----------------------------------------------------------------------------
*
* TclInitEncodingCmd --
diff --git a/tcl8.6/generic/tclCmdIL.c b/tcl8.6/generic/tclCmdIL.c
index e3c5f10..10fbd3f 100644
--- a/tcl8.6/generic/tclCmdIL.c
+++ b/tcl8.6/generic/tclCmdIL.c
@@ -64,8 +64,9 @@ typedef struct SortInfo {
* SORTMODE_COMMAND. Pre-initialized to hold
* base of command. */
int *indexv; /* If the -index option was specified, this
- * holds the indexes contained in the list
- * supplied as an argument to that option.
+ * holds an encoding of the indexes contained
+ * in the list supplied as an argument to
+ * that option.
* NULL if no indexes supplied, and points to
* singleIndex field when only one
* supplied. */
@@ -93,14 +94,6 @@ typedef struct SortInfo {
#define SORTMODE_ASCII_NC 8
/*
- * Magic values for the index field of the SortInfo structure. Note that the
- * index "end-1" will be translated to SORTIDX_END-1, etc.
- */
-
-#define SORTIDX_NONE -1 /* Not indexed; use whole value. */
-#define SORTIDX_END -2 /* Indexed from end. */
-
-/*
* Forward declarations for procedures defined in this file:
*/
@@ -2754,21 +2747,10 @@ Tcl_LreplaceObjCmd(
if (first < 0) {
first = 0;
}
-
- /*
- * Complain if the user asked for a start element that is greater than the
- * list length. This won't ever trigger for the "end-*" case as that will
- * be properly constrained by TclGetIntForIndex because we use listLen-1
- * (to allow for replacing the last elem).
- */
-
- 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",
- NULL);
- return TCL_ERROR;
+ if (first > listLen) {
+ first = listLen;
}
+
if (last >= listLen) {
last = listLen - 1;
}
@@ -2913,7 +2895,7 @@ Tcl_LsearchObjCmd(
Tcl_Obj *const objv[]) /* Argument values. */
{
const char *bytes, *patternBytes;
- int i, match, index, result, listc, length, elemLen, bisect;
+ int i, match, index, result=TCL_OK, listc, length, elemLen, bisect;
int dataType, isIncreasing, lower, upper, offset;
Tcl_WideInt patWide, objWide;
int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
@@ -3113,13 +3095,26 @@ Tcl_LsearchObjCmd(
*/
for (j=0 ; j<sortInfo.indexc ; j++) {
- if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
- &sortInfo.indexv[j]) != TCL_OK) {
+ int encoded = 0;
+ if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
+ TCL_INDEX_AFTER, &encoded) != TCL_OK) {
+ result = TCL_ERROR;
+ }
+ if ((encoded == TCL_INDEX_BEFORE)
+ || (encoded == TCL_INDEX_AFTER)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "index \"%s\" cannot select an element "
+ "from any list", Tcl_GetString(indices[j])));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
+ "OUTOFRANGE", NULL);
+ result = TCL_ERROR;
+ }
+ if (result == TCL_ERROR) {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (-index option item number %d)", j));
- result = TCL_ERROR;
goto done;
}
+ sortInfo.indexv[j] = encoded;
}
break;
}
@@ -3492,8 +3487,8 @@ Tcl_LsearchObjCmd(
itemPtr = Tcl_NewIntObj(i);
for (j=0 ; j<sortInfo.indexc ; j++) {
- Tcl_ListObjAppendElement(interp, itemPtr,
- Tcl_NewIntObj(sortInfo.indexv[j]));
+ Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
+ TclIndexDecode(sortInfo.indexv[j], listc)));
}
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else {
@@ -3514,8 +3509,8 @@ Tcl_LsearchObjCmd(
itemPtr = Tcl_NewIntObj(index);
for (j=0 ; j<sortInfo.indexc ; j++) {
- Tcl_ListObjAppendElement(interp, itemPtr,
- Tcl_NewIntObj(sortInfo.indexv[j]));
+ Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
+ TclIndexDecode(sortInfo.indexv[j], listc)));
}
Tcl_SetObjResult(interp, itemPtr);
} else {
@@ -3732,7 +3727,7 @@ Tcl_LsortObjCmd(
sortInfo.isIncreasing = 1;
break;
case LSORT_INDEX: {
- int indexc, dummy;
+ int indexc;
Tcl_Obj **indexv;
if (i == objc-2) {
@@ -3758,8 +3753,20 @@ Tcl_LsortObjCmd(
*/
for (j=0 ; j<indexc ; j++) {
- if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
- &dummy) != TCL_OK) {
+ int encoded = 0;
+ int result = TclIndexEncode(interp, indexv[j],
+ TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
+
+ if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
+ || (encoded == TCL_INDEX_AFTER))) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "index \"%s\" cannot select an element "
+ "from any list", Tcl_GetString(indexv[j])));
+ Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
+ "OUTOFRANGE", NULL);
+ result = TCL_ERROR;
+ }
+ if (result == TCL_ERROR) {
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (-index option item number %d)", j));
sortInfo.resultCode = TCL_ERROR;
@@ -3839,8 +3846,8 @@ Tcl_LsortObjCmd(
* might be decreased by 1 later. */
}
for (j=0 ; j<sortInfo.indexc ; j++) {
- TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
- &sortInfo.indexv[j]);
+ /* Prescreened values, no errors or out of range possible */
+ TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
}
}
@@ -3911,10 +3918,7 @@ Tcl_LsortObjCmd(
* offset of the element within each group by which to sort.
*/
- groupOffset = sortInfo.indexv[0];
- if (groupOffset <= SORTIDX_END) {
- groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
- }
+ groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
if (groupOffset < 0 || groupOffset >= groupSize) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"when used with \"-stride\", the leading \"-index\""
@@ -3933,6 +3937,9 @@ Tcl_LsortObjCmd(
/*
* Do not shrink the actual memory block used; that doesn't
* work with TclStackAlloc-allocated memory. [Bug 2918962]
+ *
+ * TODO: Consider a pointer increment to replace this
+ * array shift.
*/
for (i = 0; i < sortInfo.indexc; i++) {
@@ -4501,15 +4508,8 @@ SelectObjFromSublist(
infoPtr->resultCode = TCL_ERROR;
return NULL;
}
- index = infoPtr->indexv[i];
-
- /*
- * Adjust for end-based indexing.
- */
- if (index < SORTIDX_NONE) {
- index += listLen + 1;
- }
+ index = TclIndexDecode(infoPtr->indexv[i], listLen - 1);
if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
&currentObj) != TCL_OK) {
diff --git a/tcl8.6/generic/tclCmdMZ.c b/tcl8.6/generic/tclCmdMZ.c
index d63a985..8530719 100644
--- a/tcl8.6/generic/tclCmdMZ.c
+++ b/tcl8.6/generic/tclCmdMZ.c
@@ -1571,7 +1571,6 @@ StringIsCmd(
chcomp = Tcl_UniCharIsDigit;
break;
case STR_IS_DOUBLE: {
- /* TODO */
if ((objPtr->typePtr == &tclDoubleType) ||
(objPtr->typePtr == &tclIntType) ||
#ifndef TCL_WIDE_INT_IS_LONG
@@ -2353,7 +2352,7 @@ StringRplcCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_UniChar *ustring;
- int first, last, length;
+ int first, last, length, end;
if (objc < 4 || objc > 5) {
Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
@@ -2361,20 +2360,38 @@ StringRplcCmd(
}
ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
- length--;
+ end = length - 1;
- if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
- TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
+ if (TclGetIntForIndexM(interp, objv[2], end, &first) != TCL_OK ||
+ TclGetIntForIndexM(interp, objv[3], end, &last) != TCL_OK){
return TCL_ERROR;
}
- if ((last < first) || (last < 0) || (first > length)) {
+ /*
+ * The following test screens out most empty substrings as
+ * candidates for replacement. When they are detected, no
+ * replacement is done, and the result is the original string,
+ */
+ if ((last < 0) || /* Range ends before start of string */
+ (first > end) || /* Range begins after end of string */
+ (last < first)) { /* Range begins after it starts */
+
+ /*
+ * BUT!!! when (end < 0) -- an empty original string -- we can
+ * have (first <= end < 0 <= last) and an empty string is permitted
+ * to be replaced.
+ */
Tcl_SetObjResult(interp, objv[1]);
} else {
Tcl_Obj *resultPtr;
+ /*
+ * We are re-fetching in case the string argument is same value as
+ * an index argument, and shimmering cost us our ustring.
+ */
+
ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
- length--;
+ end = length-1;
if (first < 0) {
first = 0;
@@ -2384,9 +2401,9 @@ StringRplcCmd(
if (objc == 5) {
Tcl_AppendObjToObj(resultPtr, objv[4]);
}
- if (last < length) {
+ if (last < end) {
Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
- length - last);
+ end - last);
}
Tcl_SetObjResult(interp, resultPtr);
}
@@ -2582,10 +2599,8 @@ StringEqualCmd(
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
- const char *string1, *string2;
- int length1, length2, i, match, length, nocase = 0, reqlength = -1;
- typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
- strCmpFn_t strCmpFn;
+ const char *string2;
+ int length2, i, match, nocase = 0, reqlength = -1;
if (objc < 3 || objc > 6) {
str_cmp_args:
@@ -2624,78 +2639,7 @@ StringEqualCmd(
objv += objc-2;
- if ((reqlength == 0) || (objv[0] == objv[1])) {
- /*
- * Always match at 0 chars of if it is the same obj.
- */
-
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- return TCL_OK;
- }
-
- if (!nocase && TclIsPureByteArray(objv[0]) &&
- TclIsPureByteArray(objv[1])) {
- /*
- * Use binary versions of comparisons since that won't cause undue
- * type conversions and it is much faster. Only do this if we're
- * case-sensitive (which is all that really makes sense with byte
- * arrays anyway, and we have no memcasecmp() for some reason... :^)
- */
-
- string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
- string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
- strCmpFn = (strCmpFn_t) memcmp;
- } else if ((objv[0]->typePtr == &tclStringType)
- && (objv[1]->typePtr == &tclStringType)) {
- /*
- * Do a unicode-specific comparison if both of the args are of String
- * type. In benchmark testing this proved the most efficient check
- * between the unicode and string comparison operations.
- */
-
- string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
- string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
- strCmpFn = (strCmpFn_t)
- (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
- } else {
- /*
- * As a catch-all we will work with UTF-8. We cannot use memcmp() as
- * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
- * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
- * case-sensitive and no specific length was requested.
- */
-
- string1 = (char *) TclGetStringFromObj(objv[0], &length1);
- string2 = (char *) TclGetStringFromObj(objv[1], &length2);
- if ((reqlength < 0) && !nocase) {
- strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
- } else {
- length1 = Tcl_NumUtfChars(string1, length1);
- length2 = Tcl_NumUtfChars(string2, length2);
- strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
- }
- }
-
- if ((reqlength < 0) && (length1 != length2)) {
- match = 1; /* This will be reversed below. */
- } else {
- length = (length1 < length2) ? length1 : length2;
- if (reqlength > 0 && reqlength < length) {
- length = reqlength;
- } else if (reqlength < 0) {
- /*
- * The requested length is negative, so we ignore it by setting it
- * to length + 1 so we correct the match var.
- */
-
- reqlength = length + 1;
- }
-
- match = strCmpFn(string1, string2, (unsigned) length);
- if ((match == 0) && (reqlength > length)) {
- match = length1 - length2;
- }
- }
+ match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
return TCL_OK;
@@ -2732,11 +2676,194 @@ StringCmpCmd(
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
- const char *string1, *string2;
- int length1, length2, i, match, length, nocase = 0, reqlength = -1;
- typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
- strCmpFn_t strCmpFn;
+ int match, nocase, reqlength, status;
+
+ if ((status = TclStringCmpOpts(interp, objc, objv, &nocase, &reqlength))
+ != TCL_OK) {
+
+ return status;
+ }
+
+ objv += objc-2;
+ match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
+ return TCL_OK;
+}
+
+int TclStringCmp (
+ Tcl_Obj *value1Ptr,
+ Tcl_Obj *value2Ptr,
+ int checkEq, /* comparison is only for equality */
+ int nocase, /* comparison is not case sensitive */
+ int reqlength /* requested length */
+) {
+ char *s1, *s2;
+ int empty, length, match, s1len, s2len;
+ memCmpFn_t memCmpFn;
+
+ if ((reqlength == 0) || (value1Ptr == value2Ptr)) {
+ /*
+ * Always match at 0 chars of if it is the same obj.
+ */
+ match = 0;
+ } else {
+ if (!nocase && TclIsPureByteArray(value1Ptr)
+ && TclIsPureByteArray(value2Ptr)) {
+ /*
+ * Use binary versions of comparisons since that won't cause undue
+ * type conversions and it is much faster. Only do this if we're
+ * case-sensitive (which is all that really makes sense with byte
+ * arrays anyway, and we have no memcasecmp() for some reason... :^)
+ */
+ s1 = (char *) Tcl_GetByteArrayFromObj(value1Ptr, &s1len);
+ s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
+ memCmpFn = memcmp;
+ } else if ((value1Ptr->typePtr == &tclStringType)
+ && (value2Ptr->typePtr == &tclStringType)) {
+ /*
+ * Do a unicode-specific comparison if both of the args are of
+ * String type. If the char length == byte length, we can do a
+ * memcmp. In benchmark testing this proved the most efficient
+ * check between the unicode and string comparison operations.
+ */
+
+ if (nocase) {
+ s1 = (char *) Tcl_GetUnicodeFromObj(value1Ptr, &s1len);
+ s2 = (char *) Tcl_GetUnicodeFromObj(value2Ptr, &s2len);
+ memCmpFn = (memCmpFn_t)Tcl_UniCharNcasecmp;
+ } else {
+ s1len = Tcl_GetCharLength(value1Ptr);
+ s2len = Tcl_GetCharLength(value2Ptr);
+ if ((s1len == value1Ptr->length)
+ && (value1Ptr->bytes != NULL)
+ && (s2len == value2Ptr->length)
+ && (value2Ptr->bytes != NULL)) {
+ s1 = value1Ptr->bytes;
+ s2 = value2Ptr->bytes;
+ memCmpFn = memcmp;
+ } else {
+ s1 = (char *) Tcl_GetUnicode(value1Ptr);
+ s2 = (char *) Tcl_GetUnicode(value2Ptr);
+ if (
+#ifdef WORDS_BIGENDIAN
+ 1
+#else
+ checkEq
+#endif
+ ) {
+ memCmpFn = memcmp;
+ s1len *= sizeof(Tcl_UniChar);
+ s2len *= sizeof(Tcl_UniChar);
+ } else {
+ memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
+ }
+ }
+ }
+ } else {
+ if ((empty = TclCheckEmptyString(value1Ptr)) > 0) {
+ switch (TclCheckEmptyString(value2Ptr)) {
+ case -1:
+ s1 = "";
+ s1len = 0;
+ s2 = TclGetStringFromObj(value2Ptr, &s2len);
+ break;
+ case 0:
+ match = -1;
+ goto matchdone;
+ case 1:
+ default: /* avoid warn: `s2` may be used uninitialized */
+ match = 0;
+ goto matchdone;
+ }
+ } else if (TclCheckEmptyString(value2Ptr) > 0) {
+ switch (empty) {
+ case -1:
+ s2 = "";
+ s2len = 0;
+ s1 = TclGetStringFromObj(value1Ptr, &s1len);
+ break;
+ case 0:
+ match = 1;
+ goto matchdone;
+ case 1:
+ default: /* avoid warn: `s1` may be used uninitialized */
+ match = 0;
+ goto matchdone;
+ }
+ } else {
+ s1 = TclGetStringFromObj(value1Ptr, &s1len);
+ s2 = TclGetStringFromObj(value2Ptr, &s2len);
+ }
+ if (!nocase && checkEq) {
+ /*
+ * When we have equal-length we can check only for (in)equality.
+ * We can use memcmp in all (n)eq cases because we
+ * don't need to worry about lexical LE/BE variance.
+ */
+ memCmpFn = memcmp;
+ } else {
+
+ /*
+ * As a catch-all we will work with UTF-8. We cannot use memcmp() as
+ * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
+ * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
+ * case-sensitive and no specific length was requested.
+ */
+
+ if ((reqlength < 0) && !nocase) {
+ memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
+ } else {
+ s1len = Tcl_NumUtfChars(s1, s1len);
+ s2len = Tcl_NumUtfChars(s2, s2len);
+ memCmpFn = (memCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
+ }
+ }
+ }
+
+ length = (s1len < s2len) ? s1len : s2len;
+ if (reqlength > 0 && reqlength < length) {
+ length = reqlength;
+ } else if (reqlength < 0) {
+ /*
+ * The requested length is negative, so we ignore it by setting it to
+ * length + 1 so we correct the match var.
+ */
+
+ reqlength = length + 1;
+ }
+
+ if (checkEq && (s1len != s2len)) {
+ match = 1; /* This will be reversed below. */
+ } else {
+ /*
+ * The comparison function should compare up to the minimum
+ * byte length only.
+ */
+ match = memCmpFn(s1, s2, (size_t) length);
+ }
+ if ((match == 0) && (reqlength > length)) {
+ match = s1len - s2len;
+ }
+ match = (match > 0) ? 1 : (match < 0) ? -1 : 0;
+ }
+ matchdone:
+ return match;
+}
+
+int TclStringCmpOpts (
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects. */
+ int *nocase,
+ int *reqlength
+)
+{
+ int i, length;
+ const char *string;
+
+ *reqlength = -1;
+ *nocase = 0;
if (objc < 3 || objc > 6) {
str_cmp_args:
Tcl_WrongNumArgs(interp, 1, objv,
@@ -2745,106 +2872,27 @@ StringCmpCmd(
}
for (i = 1; i < objc-2; i++) {
- string2 = TclGetStringFromObj(objv[i], &length2);
- if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
- nocase = 1;
- } else if ((length2 > 1)
- && !strncmp(string2, "-length", (size_t)length2)) {
+ string = TclGetStringFromObj(objv[i], &length);
+ if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
+ *nocase = 1;
+ } else if ((length > 1)
+ && !strncmp(string, "-length", (size_t)length)) {
if (i+1 >= objc-2) {
goto str_cmp_args;
}
i++;
- if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
+ if (TclGetIntFromObj(interp, objv[i], reqlength) != TCL_OK) {
return TCL_ERROR;
}
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad option \"%s\": must be -nocase or -length",
- string2));
+ string));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
- string2, NULL);
+ string, NULL);
return TCL_ERROR;
}
}
-
- /*
- * From now on, we only access the two objects at the end of the argument
- * array.
- */
-
- objv += objc-2;
-
- if ((reqlength == 0) || (objv[0] == objv[1])) {
- /*
- * Always match at 0 chars of if it is the same obj.
- */
-
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
-
- if (!nocase && TclIsPureByteArray(objv[0]) &&
- TclIsPureByteArray(objv[1])) {
- /*
- * Use binary versions of comparisons since that won't cause undue
- * type conversions and it is much faster. Only do this if we're
- * case-sensitive (which is all that really makes sense with byte
- * arrays anyway, and we have no memcasecmp() for some reason... :^)
- */
-
- string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
- string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
- strCmpFn = (strCmpFn_t) memcmp;
- } else if ((objv[0]->typePtr == &tclStringType)
- && (objv[1]->typePtr == &tclStringType)) {
- /*
- * Do a unicode-specific comparison if both of the args are of String
- * type. In benchmark testing this proved the most efficient check
- * between the unicode and string comparison operations.
- */
-
- string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
- string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
- strCmpFn = (strCmpFn_t)
- (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
- } else {
- /*
- * As a catch-all we will work with UTF-8. We cannot use memcmp() as
- * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
- * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
- * case-sensitive and no specific length was requested.
- */
-
- string1 = (char *) TclGetStringFromObj(objv[0], &length1);
- string2 = (char *) TclGetStringFromObj(objv[1], &length2);
- if ((reqlength < 0) && !nocase) {
- strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
- } else {
- length1 = Tcl_NumUtfChars(string1, length1);
- length2 = Tcl_NumUtfChars(string2, length2);
- strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
- }
- }
-
- length = (length1 < length2) ? length1 : length2;
- if (reqlength > 0 && reqlength < length) {
- length = reqlength;
- } else if (reqlength < 0) {
- /*
- * The requested length is negative, so we ignore it by setting it to
- * length + 1 so we correct the match var.
- */
-
- reqlength = length + 1;
- }
-
- match = strCmpFn(string1, string2, (unsigned) length);
- if ((match == 0) && (reqlength > length)) {
- match = length1 - length2;
- }
-
- Tcl_SetObjResult(interp,
- Tcl_NewIntObj((match > 0) ? 1 : (match < 0) ? -1 : 0));
return TCL_OK;
}
@@ -3267,8 +3315,7 @@ StringTrimCmd(
}
string1 = TclGetStringFromObj(objv[1], &length1);
- triml = TclTrimLeft(string1, length1, string2, length2);
- trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2);
+ triml = TclTrim(string1, length1, string2, length2, &trimr);
Tcl_SetObjResult(interp,
Tcl_NewStringObj(string1 + triml, length1 - triml - trimr));
diff --git a/tcl8.6/generic/tclCompCmds.c b/tcl8.6/generic/tclCompCmds.c
index c2b4bdb..838e9d7 100644
--- a/tcl8.6/generic/tclCompCmds.c
+++ b/tcl8.6/generic/tclCompCmds.c
@@ -322,11 +322,22 @@ TclCompileArraySetCmd(
*/
if (isDataValid && !isDataEven) {
+ /* Abandon custom compile and let invocation raise the error */
+ code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+ goto done;
+
+ /*
+ * We used to compile to the bytecode that would throw the error,
+ * but that was wrong because it would not invoke the array trace
+ * on the variable.
+ *
PushStringLiteral(envPtr, "list must have an even number of elements");
PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR, envPtr);
TclEmitInt4( 0, envPtr);
goto done;
+ *
+ */
}
/*
@@ -404,6 +415,10 @@ TclCompileArraySetCmd(
* Start issuing instructions to write to the array.
*/
+ TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
+ TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
+ TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
+
CompileWord(envPtr, dataTokenPtr, interp, 2);
if (!isDataLiteral || !isDataValid) {
/*
@@ -428,9 +443,6 @@ TclCompileArraySetCmd(
TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
}
- TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex, envPtr);
- TclEmitInstInt1(INST_JUMP_TRUE1, 7, envPtr);
- TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex, envPtr);
TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr);
offsetBack = CurrentOffset(envPtr);
Emit14Inst( INST_LOAD_SCALAR, keyVar, envPtr);
diff --git a/tcl8.6/generic/tclCompCmdsGR.c b/tcl8.6/generic/tclCompCmdsGR.c
index ffe39ba..1094352 100644
--- a/tcl8.6/generic/tclCompCmdsGR.c
+++ b/tcl8.6/generic/tclCompCmdsGR.c
@@ -28,56 +28,39 @@ static void CompileReturnInternal(CompileEnv *envPtr,
static int IndexTailVarIfKnown(Tcl_Interp *interp,
Tcl_Token *varTokenPtr, CompileEnv *envPtr);
-#define INDEX_END (-2)
/*
*----------------------------------------------------------------------
*
- * GetIndexFromToken --
+ * TclGetIndexFromToken --
*
- * Parse a token and get the encoded version of the index (as understood
- * by TEBC), assuming it is at all knowable at compile time. Only handles
- * indices that are integers or 'end' or 'end-integer'.
+ * Parse a token to determine if an index value is known at
+ * compile time.
*
* Returns:
* TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
*
* Side effects:
- * Sets *index to the index value if successful.
+ * When TCL_OK is returned, the encoded index value is written
+ * to *index.
*
*----------------------------------------------------------------------
*/
-static inline int
-GetIndexFromToken(
+int
+TclGetIndexFromToken(
Tcl_Token *tokenPtr,
- int *index)
+ int before,
+ int after,
+ int *indexPtr)
{
Tcl_Obj *tmpObj = Tcl_NewObj();
- int result, idx;
-
- if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
- Tcl_DecrRefCount(tmpObj);
- return TCL_ERROR;
- }
+ int result = TCL_ERROR;
- result = TclGetIntFromObj(NULL, tmpObj, &idx);
- if (result == TCL_OK) {
- if (idx < 0) {
- result = TCL_ERROR;
- }
- } else {
- result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
- if (result == TCL_OK && idx > INDEX_END) {
- result = TCL_ERROR;
- }
+ if (TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
+ result = TclIndexEncode(NULL, tmpObj, before, after, indexPtr);
}
Tcl_DecrRefCount(tmpObj);
-
- if (result == TCL_OK) {
- *index = idx;
- }
-
return result;
}
@@ -144,7 +127,7 @@ TclCompileGlobalCmd(
return TCL_ERROR;
}
- /* TODO: Consider what value can pass throug the
+ /* TODO: Consider what value can pass through the
* IndexTailVarIfKnown() screen. Full CompileWord()
* likely does not apply here. Push known value instead. */
CompileWord(envPtr, varTokenPtr, interp, i);
@@ -1053,7 +1036,7 @@ TclCompileLassignCmd(
*/
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
return TCL_OK;
}
@@ -1104,14 +1087,14 @@ TclCompileLindexCmd(
}
idxTokenPtr = TokenAfter(valTokenPtr);
- if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) {
+ if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_BEFORE,
+ &idx) == TCL_OK) {
/*
- * All checks have been completed, and we have exactly one of these
- * constructs:
- * lindex <arbitraryValue> <posInt>
- * lindex <arbitraryValue> end-<posInt>
- * This is best compiled as a push of the arbitrary value followed by
- * an "immediate lindex" which is the most efficient variety.
+ * The idxTokenPtr parsed as a valid index value and was
+ * encoded as expected by INST_LIST_INDEX_IMM.
+ *
+ * NOTE: that we rely on indexing before a list producing the
+ * same result as indexing after a list.
*/
CompileWord(envPtr, valTokenPtr, interp, 1);
@@ -1258,7 +1241,7 @@ TclCompileListCmd(
if (concat && numWords == 2) {
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
}
return TCL_OK;
}
@@ -1332,21 +1315,25 @@ TclCompileLrangeCmd(
}
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
- /*
- * Parse the indices. Will only compile if both are constants and not an
- * _integer_ less than zero (since we reserve negative indices here for
- * end-relative indexing) or an end-based index greater than 'end' itself.
- */
-
tokenPtr = TokenAfter(listTokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
+ &idx1) != TCL_OK) {
return TCL_ERROR;
}
+ /*
+ * Token was an index value, and we treat all "first" indices
+ * before the list same as the start of the list.
+ */
tokenPtr = TokenAfter(tokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
+ &idx2) != TCL_OK) {
return TCL_ERROR;
}
+ /*
+ * Token was an index value, and we treat all "last" indices
+ * after the list same as the end of the list.
+ */
/*
* Issue instructions. It's not safe to skip doing the LIST_RANGE, as
@@ -1396,21 +1383,30 @@ TclCompileLinsertCmd(
*/
tokenPtr = TokenAfter(listTokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) {
+
+ /*
+ * NOTE: This command treats all inserts at indices before the list
+ * the same as inserts at the start of the list, and all inserts
+ * after the list the same as inserts at the end of the list. We
+ * make that transformation here so we can use the optimized bytecode
+ * as much as possible.
+ */
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END,
+ &idx) != TCL_OK) {
return TCL_ERROR;
}
/*
* There are four main cases. If there are no values to insert, this is
* just a confirm-listiness check. If the index is '0', this is a prepend.
- * If the index is 'end' (== INDEX_END), this is an append. Otherwise,
+ * If the index is 'end' (== TCL_INDEX_END), this is an append. Otherwise,
* this is a splice (== split, insert values as list, concat-3).
*/
CompileWord(envPtr, listTokenPtr, interp, 1);
if (parsePtr->numWords == 3) {
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
return TCL_OK;
}
@@ -1420,13 +1416,25 @@ TclCompileLinsertCmd(
}
TclEmitInstInt4( INST_LIST, i-3, envPtr);
- if (idx == 0 /*start*/) {
+ if (idx == TCL_INDEX_START) {
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- } else if (idx == INDEX_END /*end*/) {
+ } else if (idx == TCL_INDEX_END) {
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
} else {
- if (idx < 0) {
+ /*
+ * Here we handle two ranges for idx. First when idx > 0, we
+ * want the first half of the split to end at index idx-1 and
+ * the second half to start at index idx.
+ * Second when idx < TCL_INDEX_END, indicating "end-N" indexing,
+ * we want the first half of the split to end at index end-N and
+ * the second half to start at index end-N+1. We accomplish this
+ * with a pre-adjustment of the end-N value.
+ * The root of this is that the commands [lrange] and [linsert]
+ * differ in their interpretation of the "end" index.
+ */
+
+ if (idx < TCL_INDEX_END) {
idx++;
}
TclEmitInstInt4( INST_OVER, 1, envPtr);
@@ -1434,7 +1442,7 @@ TclCompileLinsertCmd(
TclEmitInt4( idx-1, envPtr);
TclEmitInstInt4( INST_REVERSE, 3, envPtr);
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
}
@@ -1464,250 +1472,116 @@ TclCompileLreplaceCmd(
{
Tcl_Token *tokenPtr, *listTokenPtr;
DefineLineInformation; /* TIP #280 */
- Tcl_Obj *tmpObj;
- int idx1, idx2, i, offset, offset2;
+ int idx1, idx2, i;
+ int emptyPrefix=1, suffixStart = 0;
if (parsePtr->numWords < 4) {
return TCL_ERROR;
}
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
- /*
- * Parse the indices. Will only compile if both are constants and not an
- * _integer_ less than zero (since we reserve negative indices here for
- * end-relative indexing) or an end-based index greater than 'end' itself.
- */
-
tokenPtr = TokenAfter(listTokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
+ &idx1) != TCL_OK) {
return TCL_ERROR;
}
tokenPtr = TokenAfter(tokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
+ &idx2) != TCL_OK) {
return TCL_ERROR;
}
/*
- * idx1, idx2 are now in canonical form:
+ * General structure of the [lreplace] result is
+ * prefix replacement suffix
+ * In a few cases we can predict various parts will be empty and
+ * take advantage.
*
- * - 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)) {
+ * The proper suffix begins with the greater of indices idx1 or
+ * idx2 + 1. If we cannot tell at compile time which is greater,
+ * we must defer to direct evaluation.
+ */
+
+ if (idx1 == TCL_INDEX_AFTER) {
+ suffixStart = idx1;
+ } else if (idx2 == TCL_INDEX_BEFORE) {
+ suffixStart = idx1;
+ } else if (idx2 == TCL_INDEX_END) {
+ suffixStart = TCL_INDEX_AFTER;
+ } else if (((idx2 < TCL_INDEX_END) && (idx1 <= TCL_INDEX_END))
+ || ((idx2 >= TCL_INDEX_START) && (idx1 >= TCL_INDEX_START))) {
+ suffixStart = (idx1 > idx2 + 1) ? idx1 : idx2 + 1;
+ } else {
return TCL_ERROR;
}
- if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) {
- idx2 = idx1 - 1;
- }
+ /* All paths start with computing/pushing the original value. */
+ CompileWord(envPtr, listTokenPtr, interp, 1);
/*
- * Work out what this [lreplace] is actually doing.
+ * Push all the replacement values next so any errors raised in
+ * creating them get raised first.
*/
-
- tmpObj = NULL;
- CompileWord(envPtr, listTokenPtr, interp, 1);
- if (parsePtr->numWords == 4) {
- if (idx1 == 0) {
- if (idx2 == INDEX_END) {
- goto dropAll;
- }
- idx1 = idx2 + 1;
- idx2 = INDEX_END;
- goto dropEnd;
- } else if (idx2 == INDEX_END) {
- idx2 = idx1 - 1;
- idx1 = 0;
- goto dropEnd;
- } else {
- if (idx2 < idx1) {
- idx2 = idx1 - 1;
- }
- if (idx1 > 0) {
- tmpObj = Tcl_NewIntObj(idx1);
- Tcl_IncrRefCount(tmpObj);
- }
- goto dropRange;
- }
- }
-
- tokenPtr = TokenAfter(tokenPtr);
- for (i=4 ; i<parsePtr->numWords ; i++) {
- CompileWord(envPtr, tokenPtr, interp, i);
+ if (parsePtr->numWords > 4) {
+ /* Push the replacement arguments */
tokenPtr = TokenAfter(tokenPtr);
- }
- TclEmitInstInt4( INST_LIST, i - 4, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- if (idx1 == 0) {
- if (idx2 == INDEX_END) {
- goto replaceAll;
- }
- idx1 = idx2 + 1;
- idx2 = INDEX_END;
- goto replaceHead;
- } else if (idx2 == INDEX_END) {
- idx2 = idx1 - 1;
- idx1 = 0;
- goto replaceTail;
- } else {
- if (idx2 < idx1) {
- idx2 = idx1 - 1;
- }
- if (idx1 > 0) {
- tmpObj = Tcl_NewIntObj(idx1);
- Tcl_IncrRefCount(tmpObj);
+ for (i=4 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
}
- goto replaceRange;
- }
-
- /*
- * Issue instructions to perform the operations relating to configurations
- * that just drop. The only argument pushed on the stack is the list to
- * operate on.
- */
-
- dropAll: /* This just ensures the arg is a list. */
- TclEmitOpcode( INST_LIST_LENGTH, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- PushStringLiteral(envPtr, "");
- goto done;
-
- dropEnd:
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
- TclEmitInt4( idx2, envPtr);
- goto done;
-
- 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_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_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,
- Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
- TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
- envPtr->codeStart + offset + 1);
- TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
- envPtr->codeStart + offset2 + 1);
- TclAdjustStackDepth(-1, envPtr);
- }
- TclEmitOpcode( INST_DUP, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( idx1 - 1, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- goto done;
-
- /*
- * Issue instructions to perform the operations relating to configurations
- * that do real replacement. All arguments are pushed and assembled into a
- * pair: the list of values to replace with, and the list to do the
- * surgery on.
- */
-
- replaceAll:
- TclEmitOpcode( INST_LIST_LENGTH, envPtr);
- TclEmitOpcode( INST_POP, envPtr);
- goto done;
-
- replaceHead:
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
- TclEmitInt4( idx2, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- goto done;
-
- replaceTail:
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
- TclEmitInt4( idx2, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- goto done;
-
- replaceRange:
- if (tmpObj != NULL) {
- /*
- * Emit bytecode to check the list length.
- */
- TclEmitOpcode( INST_DUP, envPtr);
- TclEmitOpcode( INST_LIST_LENGTH, envPtr);
+ /* Make a list of them... */
+ TclEmitInstInt4( INST_LIST, i - 4, envPtr);
+ emptyPrefix = 0;
+ }
+
+ if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) {
/*
- * Check the list length vs idx1.
+ * This is a "no-op". Example: [lreplace {a b c} 2 0]
+ * We still do a list operation to get list-verification
+ * and canonicalization side effects.
*/
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
+ return TCL_OK;
+ }
- TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), 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.
- */
+ if (idx1 != TCL_INDEX_START) {
+ /* Prefix may not be empty; generate bytecode to push it */
+ if (emptyPrefix) {
+ TclEmitOpcode( INST_DUP, envPtr);
+ } else {
+ TclEmitInstInt4( INST_OVER, 1, envPtr);
+ }
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
+ TclEmitInt4( idx1 - 1, envPtr);
+ if (!emptyPrefix) {
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ }
+ emptyPrefix = 0;
+ }
- TclEmitOpcode( INST_DUP, envPtr);
- TclEmitOpcode( INST_LIST_LENGTH, envPtr);
- offset2 = CurrentOffset(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,
- Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
- TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
- envPtr->codeStart + offset + 1);
- TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
- envPtr->codeStart + offset2 + 1);
- TclAdjustStackDepth(-1, envPtr);
- }
- TclEmitOpcode( INST_DUP, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( idx1 - 1, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr);
- TclEmitInt4( INDEX_END, envPtr);
- TclEmitInstInt4( INST_REVERSE, 3, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- goto done;
-
- /*
- * Clean up the allocated memory.
- */
+ if (!emptyPrefix) {
+ TclEmitInstInt4( INST_REVERSE, 2, envPtr);
+ }
- done:
- if (tmpObj != NULL) {
- Tcl_DecrRefCount(tmpObj);
+ if (suffixStart == TCL_INDEX_AFTER) {
+ TclEmitOpcode( INST_POP, envPtr);
+ if (emptyPrefix) {
+ PushStringLiteral(envPtr, "");
+ }
+ } else {
+ /* Suffix may not be empty; generate bytecode to push it */
+ TclEmitInstInt4( INST_LIST_RANGE_IMM, suffixStart, envPtr);
+ TclEmitInt4( TCL_INDEX_END, envPtr);
+ if (!emptyPrefix) {
+ TclEmitOpcode( INST_LIST_CONCAT, envPtr);
+ }
}
+
return TCL_OK;
}
@@ -2933,7 +2807,7 @@ TclCompileVariableCmd(
return TCL_ERROR;
}
- /* TODO: Consider what value can pass throug the
+ /* TODO: Consider what value can pass through the
* IndexTailVarIfKnown() screen. Full CompileWord()
* likely does not apply here. Push known value instead. */
CompileWord(envPtr, varTokenPtr, interp, i);
diff --git a/tcl8.6/generic/tclCompCmdsSZ.c b/tcl8.6/generic/tclCompCmdsSZ.c
index 101edbd..c13376b 100644
--- a/tcl8.6/generic/tclCompCmdsSZ.c
+++ b/tcl8.6/generic/tclCompCmdsSZ.c
@@ -107,58 +107,6 @@ const AuxDataType tclJumptableInfoType = {
#define INVOKE(name) \
TclEmitInvoke(envPtr,INST_##name)
-#define INDEX_END (-2)
-
-/*
- *----------------------------------------------------------------------
- *
- * GetIndexFromToken --
- *
- * Parse a token and get the encoded version of the index (as understood
- * by TEBC), assuming it is at all knowable at compile time. Only handles
- * indices that are integers or 'end' or 'end-integer'.
- *
- * Returns:
- * TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
- *
- * Side effects:
- * Sets *index to the index value if successful.
- *
- *----------------------------------------------------------------------
- */
-
-static inline int
-GetIndexFromToken(
- Tcl_Token *tokenPtr,
- int *index)
-{
- Tcl_Obj *tmpObj = Tcl_NewObj();
- int result, idx;
-
- if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
- Tcl_DecrRefCount(tmpObj);
- return TCL_ERROR;
- }
-
- result = TclGetIntFromObj(NULL, tmpObj, &idx);
- if (result == TCL_OK) {
- if (idx < 0) {
- result = TCL_ERROR;
- }
- } else {
- result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
- if (result == TCL_OK && idx > INDEX_END) {
- result = TCL_ERROR;
- }
- }
- Tcl_DecrRefCount(tmpObj);
-
- if (result == TCL_OK) {
- *index = idx;
- }
-
- return result;
-}
/*
*----------------------------------------------------------------------
@@ -982,22 +930,48 @@ TclCompileStringRangeCmd(
fromTokenPtr = TokenAfter(stringTokenPtr);
toTokenPtr = TokenAfter(fromTokenPtr);
+ /* Every path must push the string argument */
+ CompileWord(envPtr, stringTokenPtr, interp, 1);
+
/*
* Parse the two indices.
*/
- if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) {
+ if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
+ &idx1) != TCL_OK) {
goto nonConstantIndices;
}
- if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) {
+ /*
+ * Token parsed as an index expression. We treat all indices before
+ * the string the same as the start of the string.
+ */
+
+ if (idx1 == TCL_INDEX_AFTER) {
+ /* [string range $s end+1 $last] must be empty string */
+ OP( POP);
+ PUSH( "");
+ return TCL_OK;
+ }
+
+ if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
+ &idx2) != TCL_OK) {
goto nonConstantIndices;
}
+ /*
+ * Token parsed as an index expression. We treat all indices after
+ * the string the same as the end of the string.
+ */
+ if (idx2 == TCL_INDEX_BEFORE) {
+ /* [string range $s $first -1] must be empty string */
+ OP( POP);
+ PUSH( "");
+ return TCL_OK;
+ }
/*
* Push the operand onto the stack and then the substring operation.
*/
- CompileWord(envPtr, stringTokenPtr, interp, 1);
OP44( STR_RANGE_IMM, idx1, idx2);
return TCL_OK;
@@ -1006,7 +980,6 @@ TclCompileStringRangeCmd(
*/
nonConstantIndices:
- CompileWord(envPtr, stringTokenPtr, interp, 1);
CompileWord(envPtr, fromTokenPtr, interp, 2);
CompileWord(envPtr, toTokenPtr, interp, 3);
OP( STR_RANGE);
@@ -1022,124 +995,197 @@ TclCompileStringReplaceCmd(
* compiled. */
CompileEnv *envPtr) /* Holds the resulting instructions. */
{
- Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL;
+ Tcl_Token *tokenPtr, *valueTokenPtr;
DefineLineInformation; /* TIP #280 */
- int idx1, idx2;
+ int first, last;
if (parsePtr->numWords < 4 || parsePtr->numWords > 5) {
return TCL_ERROR;
}
+
+ /* Bytecode to compute/push string argument being replaced */
valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (parsePtr->numWords == 5) {
- tokenPtr = TokenAfter(valueTokenPtr);
- tokenPtr = TokenAfter(tokenPtr);
- replacementTokenPtr = TokenAfter(tokenPtr);
- }
+ CompileWord(envPtr, valueTokenPtr, interp, 1);
/*
- * Parse the indices. Will only compile special cases if both are
- * constants and not an _integer_ less than zero (since we reserve
- * negative indices here for end-relative indexing) or an end-based index
- * greater than 'end' itself.
+ * Check for first index known and useful at compile time.
*/
-
tokenPtr = TokenAfter(valueTokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
+ &first) != TCL_OK) {
goto genericReplace;
}
+ /*
+ * Check for last index known and useful at compile time.
+ */
tokenPtr = TokenAfter(tokenPtr);
- if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+ if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
+ &last) != TCL_OK) {
goto genericReplace;
}
- /*
- * We handle these replacements specially: first character (where
- * idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything
- * else and the semantics get rather screwy.
+ /*
+ * [string replace] is an odd bird. For many arguments it is
+ * a conventional substring replacer. However it also goes out
+ * of its way to become a no-op for many cases where it would be
+ * replacing an empty substring. Precisely, it is a no-op when
+ *
+ * (last < first) OR
+ * (last < 0) OR
+ * (end < first)
+ *
+ * For some compile-time values we can detect these cases, and
+ * compile direct to bytecode implementing the no-op.
*/
- if (idx1 == 0 && idx2 == 0) {
- int notEq, end;
+ if ((last == TCL_INDEX_BEFORE) /* Know (last < 0) */
+ || (first == TCL_INDEX_AFTER) /* Know (first > end) */
/*
- * Just working with the first character.
+ * Tricky to determine when runtime (last < first) can be
+ * certainly known based on the encoded values. Consider the
+ * cases...
+ *
+ * (first <= TCL_INDEX_END) &&
+ * (last == TCL_INDEX_AFTER) => cannot tell REJECT
+ * (last <= TCL_INDEX END) && (last < first) => ACCEPT
+ * else => cannot tell REJECT
*/
-
- CompileWord(envPtr, valueTokenPtr, interp, 1);
- if (replacementTokenPtr == NULL) {
- /* Drop first */
- OP44( STR_RANGE_IMM, 1, INDEX_END);
- return TCL_OK;
+ || ((first <= TCL_INDEX_END) && (last <= TCL_INDEX_END)
+ && (last < first)) /* Know (last < first) */
+ /*
+ * (first == TCL_INDEX_BEFORE) &&
+ * (last == TCL_INDEX_AFTER) => (first < last) REJECT
+ * (last <= TCL_INDEX_END) => cannot tell REJECT
+ * else => (first < last) REJECT
+ *
+ * else [[first >= TCL_INDEX_START]] &&
+ * (last == TCL_INDEX_AFTER) => cannot tell REJECT
+ * (last <= TCL_INDEX_END) => cannot tell REJECT
+ * else [[last >= TCL_INDEX START]] && (last < first) => ACCEPT
+ */
+ || ((first >= TCL_INDEX_START) && (last >= TCL_INDEX_START)
+ && (last < first))) { /* Know (last < first) */
+ if (parsePtr->numWords == 5) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 4);
+ OP( POP); /* Pop newString */
}
- /* Replace first */
- CompileWord(envPtr, replacementTokenPtr, interp, 4);
- OP4( OVER, 1);
- PUSH( "");
- OP( STR_EQ);
- JUMP1( JUMP_FALSE, notEq);
- OP( POP);
- JUMP1( JUMP, end);
- FIXJUMP1(notEq);
- TclAdjustStackDepth(1, envPtr);
- OP4( REVERSE, 2);
- OP44( STR_RANGE_IMM, 1, INDEX_END);
- OP1( STR_CONCAT1, 2);
- FIXJUMP1(end);
+ /* Original string argument now on TOS as result */
return TCL_OK;
+ }
- } else if (idx1 == INDEX_END && idx2 == INDEX_END) {
- int notEq, end;
-
- /*
- * Just working with the last character.
- */
+ if (parsePtr->numWords == 5) {
+ /*
+ * When we have a string replacement, we have to take care about
+ * not replacing empty substrings that [string replace] promises
+ * not to replace
+ *
+ * The remaining index values might be suitable for conventional
+ * string replacement, but only if they cannot possibly meet the
+ * conditions described above at runtime. If there's a chance they
+ * might, we would have to emit bytecode to check and at that point
+ * we're paying more in bytecode execution time than would make
+ * things worthwhile. Trouble is we are very limited in
+ * how much we can detect that at compile time. After decoding,
+ * we need, first:
+ *
+ * (first <= end)
+ *
+ * The encoded indices (first <= TCL_INDEX END) and
+ * (first == TCL_INDEX_BEFORE) always meets this condition, but
+ * any other encoded first index has some list for which it fails.
+ *
+ * We also need, second:
+ *
+ * (last >= 0)
+ *
+ * The encoded indices (last >= TCL_INDEX_START) and
+ * (last == TCL_INDEX_AFTER) always meet this condition but any
+ * other encoded last index has some list for which it fails.
+ *
+ * Finally we need, third:
+ *
+ * (first <= last)
+ *
+ * Considered in combination with the constraints we already have,
+ * we see that we can proceed when (first == TCL_INDEX_BEFORE)
+ * or (last == TCL_INDEX_AFTER). These also permit simplification
+ * of the prefix|replace|suffix construction. The other constraints,
+ * though, interfere with getting a guarantee that first <= last.
+ */
- CompileWord(envPtr, valueTokenPtr, interp, 1);
- if (replacementTokenPtr == NULL) {
- /* Drop last */
- OP44( STR_RANGE_IMM, 0, INDEX_END-1);
- return TCL_OK;
- }
- /* Replace last */
- CompileWord(envPtr, replacementTokenPtr, interp, 4);
- OP4( OVER, 1);
- PUSH( "");
- OP( STR_EQ);
- JUMP1( JUMP_FALSE, notEq);
- OP( POP);
- JUMP1( JUMP, end);
- FIXJUMP1(notEq);
- TclAdjustStackDepth(1, envPtr);
- OP4( REVERSE, 2);
- OP44( STR_RANGE_IMM, 0, INDEX_END-1);
+ if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) {
+ /* empty prefix */
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 4);
OP4( REVERSE, 2);
+ if (last == TCL_INDEX_AFTER) {
+ OP( POP); /* Pop original */
+ } else {
+ OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
+ OP1( STR_CONCAT1, 2);
+ }
+ return TCL_OK;
+ }
+
+ if ((last == TCL_INDEX_AFTER) && (first <= TCL_INDEX_END)) {
+ OP44( STR_RANGE_IMM, 0, first-1);
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 4);
OP1( STR_CONCAT1, 2);
- FIXJUMP1(end);
return TCL_OK;
+ }
+
+ /* FLOW THROUGH TO genericReplace */
} else {
- /*
- * Need to process indices at runtime. This could be because the
- * indices are not constants, or because we need to resolve them to
- * absolute indices to work out if a replacement is going to happen.
- * In any case, to runtime it is.
+ /*
+ * When we have no replacement string to worry about, we may
+ * have more luck, because the forbidden empty string replacements
+ * are harmless when they are replaced by another empty string.
*/
+ if ((first == TCL_INDEX_BEFORE) || (first == TCL_INDEX_START)) {
+ /* empty prefix - build suffix only */
+
+ if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
+ /* empty suffix too => empty result */
+ OP( POP); /* Pop original */
+ PUSH ( "");
+ return TCL_OK;
+ }
+ OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
+ return TCL_OK;
+ } else {
+ if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
+ /* empty suffix - build prefix only */
+ OP44( STR_RANGE_IMM, 0, first-1);
+ return TCL_OK;
+ }
+ OP( DUP);
+ OP44( STR_RANGE_IMM, 0, first-1);
+ OP4( REVERSE, 2);
+ OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
+ OP1( STR_CONCAT1, 2);
+ return TCL_OK;
+ }
+ }
+
genericReplace:
- CompileWord(envPtr, valueTokenPtr, interp, 1);
tokenPtr = TokenAfter(valueTokenPtr);
CompileWord(envPtr, tokenPtr, interp, 2);
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, 3);
- if (replacementTokenPtr != NULL) {
- CompileWord(envPtr, replacementTokenPtr, interp, 4);
+ if (parsePtr->numWords == 5) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 4);
} else {
PUSH( "");
}
OP( STR_REPLACE);
return TCL_OK;
- }
}
int
diff --git a/tcl8.6/generic/tclCompile.h b/tcl8.6/generic/tclCompile.h
index c04fc0e..0466429 100644
--- a/tcl8.6/generic/tclCompile.h
+++ b/tcl8.6/generic/tclCompile.h
@@ -1121,6 +1121,8 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr,
int distThreshold);
MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr);
MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
+MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr,
+ int before, int after, int *indexPtr);
MODULE_SCOPE void TclInitByteCodeObj(Tcl_Obj *objPtr,
CompileEnv *envPtr);
MODULE_SCOPE void TclInitCompileEnv(Tcl_Interp *interp,
@@ -1492,7 +1494,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
#endif
#define TclGetInt4AtPtr(p) \
- (((int) TclGetInt1AtPtr(p) << 24) | \
+ (((int) (TclGetUInt1AtPtr(p) << 24)) | \
(*((p)+1) << 16) | \
(*((p)+2) << 8) | \
(*((p)+3)))
diff --git a/tcl8.6/generic/tclDate.c b/tcl8.6/generic/tclDate.c
index e4dd000..717a1b3 100644
--- a/tcl8.6/generic/tclDate.c
+++ b/tcl8.6/generic/tclDate.c
@@ -1348,7 +1348,7 @@ yyparse (info)
int yychar;
/* The semantic value of the look-ahead symbol. */
-YYSTYPE yylval;
+YYSTYPE yylval = {0};
/* Number of syntax errors so far. */
int yynerrs;
diff --git a/tcl8.6/generic/tclDictObj.c b/tcl8.6/generic/tclDictObj.c
index 2eff1ff..32234a3 100644
--- a/tcl8.6/generic/tclDictObj.c
+++ b/tcl8.6/generic/tclDictObj.c
@@ -153,7 +153,7 @@ typedef struct Dict {
* must be assignable as well as readable.
*/
-#define DICT(dictObj) (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1))
+#define DICT(dictObj) ((dictObj)->internalRep.twoPtrValue.ptr1)
/*
* The structure below defines the dictionary object type by means of
diff --git a/tcl8.6/generic/tclEncoding.c b/tcl8.6/generic/tclEncoding.c
index 2548b73..6b440e7 100644
--- a/tcl8.6/generic/tclEncoding.c
+++ b/tcl8.6/generic/tclEncoding.c
@@ -2296,8 +2296,11 @@ UtfToUtfProc(
const char *srcStart, *srcEnd, *srcClose;
const char *dstStart, *dstEnd;
int result, numChars, charLimit = INT_MAX;
- Tcl_UniChar ch = 0;
+ Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
+ if (flags & TCL_ENCODING_START) {
+ *statePtr = 0;
+ }
result = TCL_OK;
srcStart = src;
@@ -2349,12 +2352,19 @@ UtfToUtfProc(
* incomplete char its bytes are made to represent themselves.
*/
- ch = (unsigned char) *src;
+ *chPtr = (unsigned char) *src;
src += 1;
- dst += Tcl_UniCharToUtf(ch, dst);
+ dst += Tcl_UniCharToUtf(*chPtr, dst);
} else {
- src += TclUtfToUniChar(src, &ch);
- dst += Tcl_UniCharToUtf(ch, dst);
+ int len = TclUtfToUniChar(src, chPtr);
+ src += len;
+ dst += Tcl_UniCharToUtf(*chPtr, dst);
+#if TCL_UTF_MAX == 4
+ if (!len) {
+ src += TclUtfToUniChar(src, chPtr);
+ dst += Tcl_UniCharToUtf(*chPtr, dst);
+ }
+#endif
}
}
@@ -2410,8 +2420,11 @@ UnicodeToUtfProc(
const char *srcStart, *srcEnd;
const char *dstEnd, *dstStart;
int result, numChars, charLimit = INT_MAX;
- Tcl_UniChar ch = 0;
+ Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
+ if (flags & TCL_ENCODING_START) {
+ *statePtr = 0;
+ }
if (flags & TCL_ENCODING_CHAR_LIMIT) {
charLimit = *dstCharsPtr;
}
@@ -2439,11 +2452,11 @@ UnicodeToUtfProc(
* Tcl_UniChar-size data.
*/
- ch = *(Tcl_UniChar *)src;
- if (ch && ch < 0x80) {
- *dst++ = (ch & 0xFF);
+ *chPtr = *(Tcl_UniChar *)src;
+ if (*chPtr && *chPtr < 0x80) {
+ *dst++ = (*chPtr & 0xFF);
} else {
- dst += Tcl_UniCharToUtf(ch, dst);
+ dst += Tcl_UniCharToUtf(*chPtr, dst);
}
src += sizeof(Tcl_UniChar);
}
@@ -2500,8 +2513,11 @@ UtfToUnicodeProc(
{
const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
int result, numChars;
- Tcl_UniChar ch = 0;
+ Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
+ if (flags & TCL_ENCODING_START) {
+ *statePtr = 0;
+ }
srcStart = src;
srcEnd = src + srcLen;
srcClose = srcEnd;
@@ -2527,7 +2543,7 @@ UtfToUnicodeProc(
result = TCL_CONVERT_NOSPACE;
break;
}
- src += TclUtfToUniChar(src, &ch);
+ src += TclUtfToUniChar(src, chPtr);
/*
* Need to handle this in a way that won't cause misalignment by
@@ -2536,23 +2552,23 @@ UtfToUnicodeProc(
#ifdef WORDS_BIGENDIAN
#if TCL_UTF_MAX > 4
- *dst++ = (ch >> 24);
- *dst++ = ((ch >> 16) & 0xFF);
- *dst++ = ((ch >> 8) & 0xFF);
- *dst++ = (ch & 0xFF);
+ *dst++ = (*chPtr >> 24);
+ *dst++ = ((*chPtr >> 16) & 0xFF);
+ *dst++ = ((*chPtr >> 8) & 0xFF);
+ *dst++ = (*chPtr & 0xFF);
#else
- *dst++ = (ch >> 8);
- *dst++ = (ch & 0xFF);
+ *dst++ = (*chPtr >> 8);
+ *dst++ = (*chPtr & 0xFF);
#endif
#else
#if TCL_UTF_MAX > 4
- *dst++ = (ch & 0xFF);
- *dst++ = ((ch >> 8) & 0xFF);
- *dst++ = ((ch >> 16) & 0xFF);
- *dst++ = (ch >> 24);
+ *dst++ = (*chPtr & 0xFF);
+ *dst++ = ((*chPtr >> 8) & 0xFF);
+ *dst++ = ((*chPtr >> 16) & 0xFF);
+ *dst++ = (*chPtr >> 24);
#else
- *dst++ = (ch & 0xFF);
- *dst++ = (ch >> 8);
+ *dst++ = (*chPtr & 0xFF);
+ *dst++ = (*chPtr >> 8);
#endif
#endif
}
@@ -2754,7 +2770,7 @@ TableFromUtfProc(
}
len = TclUtfToUniChar(src, &ch);
-#if TCL_UTF_MAX > 3
+#if TCL_UTF_MAX > 4
/*
* This prevents a crash condition. More evaluation is required for
* full support of int Tcl_UniChar. [Bug 1004065]
@@ -2763,6 +2779,10 @@ TableFromUtfProc(
if (ch & 0xffff0000) {
word = 0;
} else
+#elif TCL_UTF_MAX == 4
+ if (!len) {
+ word = 0;
+ } else
#endif
word = fromUnicode[(ch >> 8)][ch & 0xff];
@@ -2960,11 +2980,18 @@ Iso88591FromUtfProc(
* Check for illegal characters.
*/
- if (ch > 0xff) {
+ if (ch > 0xff
+#if TCL_UTF_MAX == 4
+ || !len
+#endif
+ ) {
if (flags & TCL_ENCODING_STOPONERROR) {
result = TCL_CONVERT_UNKNOWN;
break;
}
+#if TCL_UTF_MAX == 4
+ if (!len) len = 4;
+#endif
/*
* Plunge on, using '?' as a fallback character.
diff --git a/tcl8.6/generic/tclEnsemble.c b/tcl8.6/generic/tclEnsemble.c
index b79eaa3..51cf61d 100644
--- a/tcl8.6/generic/tclEnsemble.c
+++ b/tcl8.6/generic/tclEnsemble.c
@@ -146,10 +146,12 @@ TclNamespaceEnsembleCmd(
Tcl_Obj *const objv[])
{
Tcl_Namespace *namespacePtr;
- Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+ Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp), *cxtPtr,
+ *foundNsPtr, *altFoundNsPtr, *actualCxtPtr;
Tcl_Command token;
Tcl_DictSearch search;
Tcl_Obj *listObj;
+ const char *simpleName;
int index, done;
if (nsPtr == NULL || nsPtr->flags & NS_DYING) {
@@ -195,13 +197,8 @@ TclNamespaceEnsembleCmd(
objv += 2;
objc -= 2;
- /*
- * Work out what name to use for the command to create. If supplied,
- * it is either fully specified or relative to the current namespace.
- * If not supplied, it is exactly the name of the current namespace.
- */
-
- name = nsPtr->fullName;
+ name = nsPtr->name;
+ cxtPtr = (Namespace *) nsPtr->parentPtr;
/*
* Parse the option list, applying type checks as we go. Note that we
@@ -221,6 +218,7 @@ TclNamespaceEnsembleCmd(
switch ((enum EnsCreateOpts) index) {
case CRT_CMD:
name = TclGetString(objv[1]);
+ cxtPtr = nsPtr;
continue;
case CRT_SUBCMDS:
if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
@@ -337,6 +335,10 @@ TclNamespaceEnsembleCmd(
}
}
+ TclGetNamespaceForQualName(interp, name, cxtPtr,
+ TCL_CREATE_NS_IF_UNKNOWN, &foundNsPtr, &altFoundNsPtr, &actualCxtPtr,
+ &simpleName);
+
/*
* Create the ensemble. Note that this might delete another ensemble
* linked to the same namespace, so we must be careful. However, we
@@ -344,8 +346,9 @@ TclNamespaceEnsembleCmd(
* we've created it (and after any deletions have occurred.)
*/
- token = Tcl_CreateEnsemble(interp, name, NULL,
- (permitPrefix ? TCL_ENSEMBLE_PREFIX : 0));
+ token = TclCreateEnsembleInNs(interp, simpleName,
+ (Tcl_Namespace *) foundNsPtr, (Tcl_Namespace *) nsPtr,
+ (permitPrefix ? TCL_ENSEMBLE_PREFIX : 0));
Tcl_SetEnsembleSubcommandList(interp, token, subcmdObj);
Tcl_SetEnsembleMappingDict(interp, token, mapObj);
Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj);
@@ -636,48 +639,38 @@ TclNamespaceEnsembleCmd(
/*
*----------------------------------------------------------------------
*
- * Tcl_CreateEnsemble --
- *
- * Create a simple ensemble attached to the given namespace.
+ * TclCreateEnsembleInNs --
*
- * Results:
- * The token for the command created.
- *
- * Side effects:
- * The ensemble is created and marked for compilation.
+ * Like Tcl_CreateEnsemble, but additionally accepts as an argument the
+ * name of the namespace to create the command in.
*
*----------------------------------------------------------------------
*/
Tcl_Command
-Tcl_CreateEnsemble(
- Tcl_Interp *interp,
- const char *name,
- Tcl_Namespace *namespacePtr,
- int flags)
+TclCreateEnsembleInNs(
+ Tcl_Interp *interp,
+
+ const char *name, /* Simple name of command to create (no */
+ /* namespace components). */
+ Tcl_Namespace /* Name of namespace to create the command in. */
+ *nameNsPtr,
+ Tcl_Namespace
+ *ensembleNsPtr, /* Name of the namespace for the ensemble. */
+ int flags
+ )
{
- Namespace *nsPtr = (Namespace *) namespacePtr;
- EnsembleConfig *ensemblePtr = ckalloc(sizeof(EnsembleConfig));
- Tcl_Obj *nameObj = NULL;
-
- if (nsPtr == NULL) {
- nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
- }
-
- /*
- * Make the name of the ensemble into a fully qualified name. This might
- * allocate a temporary object.
- */
+ Namespace *nsPtr = (Namespace *) ensembleNsPtr;
+ EnsembleConfig *ensemblePtr;
+ Tcl_Command token;
- if (!(name[0] == ':' && name[1] == ':')) {
- nameObj = NewNsObj((Tcl_Namespace *) nsPtr);
- if (nsPtr->parentPtr == NULL) {
- Tcl_AppendStringsToObj(nameObj, name, NULL);
- } else {
- Tcl_AppendStringsToObj(nameObj, "::", name, NULL);
- }
- Tcl_IncrRefCount(nameObj);
- name = TclGetString(nameObj);
+ ensemblePtr = ckalloc(sizeof(EnsembleConfig));
+ token = TclNRCreateCommandInNs(interp, name,
+ (Tcl_Namespace *) nameNsPtr, NsEnsembleImplementationCmd,
+ NsEnsembleImplementationCmdNR, ensemblePtr, DeleteEnsembleConfig);
+ if (token == NULL) {
+ ckfree(ensemblePtr);
+ return NULL;
}
ensemblePtr->nsPtr = nsPtr;
@@ -690,9 +683,7 @@ Tcl_CreateEnsemble(
ensemblePtr->numParameters = 0;
ensemblePtr->parameterList = NULL;
ensemblePtr->unknownHandler = NULL;
- ensemblePtr->token = Tcl_NRCreateCommand(interp, name,
- NsEnsembleImplementationCmd, NsEnsembleImplementationCmdNR,
- ensemblePtr, DeleteEnsembleConfig);
+ ensemblePtr->token = token;
ensemblePtr->next = (EnsembleConfig *) nsPtr->ensembles;
nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr;
@@ -709,11 +700,52 @@ Tcl_CreateEnsemble(
((Command *) ensemblePtr->token)->compileProc = TclCompileEnsemble;
}
- if (nameObj != NULL) {
- TclDecrRefCount(nameObj);
- }
return ensemblePtr->token;
+
}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateEnsemble
+ *
+ * Create a simple ensemble attached to the given namespace.
+ *
+ * Deprecated by TclCreateEnsembleInNs.
+ *
+ * Value
+ *
+ * The token for the command created.
+ *
+ * Effect
+ * The ensemble is created and marked for compilation.
+ *
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_CreateEnsemble(
+ Tcl_Interp *interp,
+ const char *name,
+ Tcl_Namespace *namespacePtr,
+ int flags)
+{
+ Namespace *nsPtr = (Namespace *)namespacePtr, *foundNsPtr, *altNsPtr,
+ *actualNsPtr;
+ const char * simpleName;
+
+ if (nsPtr == NULL) {
+ nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+ }
+
+ TclGetNamespaceForQualName(interp, name, nsPtr, TCL_CREATE_NS_IF_UNKNOWN,
+ &foundNsPtr, &altNsPtr, &actualNsPtr, &simpleName);
+ return TclCreateEnsembleInNs(interp, simpleName,
+ (Tcl_Namespace *) foundNsPtr, (Tcl_Namespace *) nsPtr, flags);
+}
+
/*
*----------------------------------------------------------------------
@@ -1885,6 +1917,7 @@ NsEnsembleImplementationCmdNR(
TclSkipTailcall(interp);
Tcl_ListObjGetElements(NULL, copyPtr, &copyObjc, &copyObjv);
+ ((Interp *)interp)->lookupNsPtr = ensemblePtr->nsPtr;
return TclNREvalObjv(interp, copyObjc, copyObjv, TCL_EVAL_INVOKE, NULL);
}
@@ -2487,10 +2520,9 @@ DeleteEnsembleConfig(
* BuildEnsembleConfig --
*
* Create the internal data structures that describe how an ensemble
- * looks, being a hash mapping from the full command name to the Tcl list
+ * looks, being a hash mapping from the simple command name to the Tcl list
* that describes the implementation prefix words, and a sorted array of
- * all the full command names to allow for reasonably efficient
- * unambiguous prefix handling.
+ * the names to allow for reasonably efficient unambiguous prefix handling.
*
* Results:
* None.
@@ -2549,12 +2581,7 @@ BuildEnsembleConfig(
name = TclGetString(subv[i+1]);
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
if (isNew) {
- cmdObj = Tcl_NewStringObj(ensemblePtr->nsPtr->fullName, -1);
- if (ensemblePtr->nsPtr->parentPtr != NULL) {
- Tcl_AppendStringsToObj(cmdObj, "::", name, NULL);
- } else {
- Tcl_AppendStringsToObj(cmdObj, name, NULL);
- }
+ cmdObj = Tcl_NewStringObj(name, -1);
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
Tcl_SetHashValue(hPtr, cmdPrefixObj);
Tcl_IncrRefCount(cmdPrefixObj);
@@ -2586,12 +2613,7 @@ BuildEnsembleConfig(
* command is actually there; that is the programmer's
* responsibility (or [::unknown] of course).
*/
- cmdObj = Tcl_NewStringObj(ensemblePtr->nsPtr->fullName, -1);
- if (ensemblePtr->nsPtr->parentPtr != NULL) {
- Tcl_AppendStringsToObj(cmdObj, "::", name, NULL);
- } else {
- Tcl_AppendStringsToObj(cmdObj, name, NULL);
- }
+ cmdObj = Tcl_NewStringObj(name, -1);
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
Tcl_SetHashValue(hPtr, cmdPrefixObj);
Tcl_IncrRefCount(cmdPrefixObj);
@@ -2619,53 +2641,49 @@ BuildEnsembleConfig(
Tcl_DictObjNext(&dictSearch, &keyObj, &valueObj, &done);
}
} else {
- /*
- * Discover what commands are actually exported by the namespace.
- * What we have is an array of patterns and a hash table whose keys
- * are the command names exported by the namespace (the contents do
- * not matter here.) We must find out what commands are actually
- * exported by filtering each command in the namespace against each of
- * the patterns in the export list. Note that we use an intermediate
- * hash table to make memory management easier, and because that makes
- * exact matching far easier too.
- *
- * Suggestion for future enhancement: compute the unique prefixes and
- * place them in the hash too, which should make for even faster
- * matching.
- */
+ /*
+ * Discover what commands are actually exported by the namespace.
+ * What we have is an array of patterns and a hash table whose keys
+ * are the command names exported by the namespace (the contents do
+ * not matter here.) We must find out what commands are actually
+ * exported by filtering each command in the namespace against each of
+ * the patterns in the export list. Note that we use an intermediate
+ * hash table to make memory management easier, and because that makes
+ * exact matching far easier too.
+ *
+ * Suggestion for future enhancement: compute the unique prefixes and
+ * place them in the hash too, which should make for even faster
+ * matching.
+ */
- hPtr = Tcl_FirstHashEntry(&ensemblePtr->nsPtr->cmdTable, &search);
- for (; hPtr!= NULL ; hPtr=Tcl_NextHashEntry(&search)) {
- char *nsCmdName = /* Name of command in namespace. */
- Tcl_GetHashKey(&ensemblePtr->nsPtr->cmdTable, hPtr);
-
- for (i=0 ; i<ensemblePtr->nsPtr->numExportPatterns ; i++) {
- if (Tcl_StringMatch(nsCmdName,
- ensemblePtr->nsPtr->exportArrayPtr[i])) {
- hPtr = Tcl_CreateHashEntry(hash, nsCmdName, &isNew);
-
- /*
- * Remember, hash entries have a full reference to the
- * substituted part of the command (as a list) as their
- * content!
- */
-
- if (isNew) {
- Tcl_Obj *cmdObj, *cmdPrefixObj;
-
- TclNewObj(cmdObj);
- Tcl_AppendStringsToObj(cmdObj,
- ensemblePtr->nsPtr->fullName,
- (ensemblePtr->nsPtr->parentPtr ? "::" : ""),
- nsCmdName, NULL);
- cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
- Tcl_SetHashValue(hPtr, cmdPrefixObj);
- Tcl_IncrRefCount(cmdPrefixObj);
- }
- break;
- }
- }
- }
+ hPtr = Tcl_FirstHashEntry(&ensemblePtr->nsPtr->cmdTable, &search);
+ for (; hPtr!= NULL ; hPtr=Tcl_NextHashEntry(&search)) {
+ char *nsCmdName = /* Name of command in namespace. */
+ Tcl_GetHashKey(&ensemblePtr->nsPtr->cmdTable, hPtr);
+
+ for (i=0 ; i<ensemblePtr->nsPtr->numExportPatterns ; i++) {
+ if (Tcl_StringMatch(nsCmdName,
+ ensemblePtr->nsPtr->exportArrayPtr[i])) {
+ hPtr = Tcl_CreateHashEntry(hash, nsCmdName, &isNew);
+
+ /*
+ * Remember, hash entries have a full reference to the
+ * substituted part of the command (as a list) as their
+ * content!
+ */
+
+ if (isNew) {
+ Tcl_Obj *cmdObj, *cmdPrefixObj;
+
+ cmdObj = Tcl_NewStringObj(nsCmdName, -1);
+ cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
+ Tcl_SetHashValue(hPtr, cmdPrefixObj);
+ Tcl_IncrRefCount(cmdPrefixObj);
+ }
+ break;
+ }
+ }
+ }
}
if (hash->numEntries == 0) {
diff --git a/tcl8.6/generic/tclEnv.c b/tcl8.6/generic/tclEnv.c
index 8cc4b74..40ced17 100644
--- a/tcl8.6/generic/tclEnv.c
+++ b/tcl8.6/generic/tclEnv.c
@@ -723,14 +723,25 @@ TclFinalizeEnvironment(void)
* strings. This may leak more memory that strictly necessary, since some
* of the strings may no longer be in the environment. However,
* determining which ones are ok to delete is n-squared, and is pretty
- * unlikely, so we don't bother.
+ * unlikely, so we don't bother. However, in the case of DPURIFY, just
+ * free all strings in the cache.
*/
if (env.cache) {
+#ifdef PURIFY
+ int i;
+ for (i = 0; i < env.cacheSize; i++) {
+ ckfree(env.cache[i]);
+ }
+#endif
ckfree(env.cache);
env.cache = NULL;
env.cacheSize = 0;
#ifndef USE_PUTENV
+ if ((env.ourEnviron != NULL)) {
+ ckfree(env.ourEnviron);
+ env.ourEnviron = NULL;
+ }
env.ourEnvironSize = 0;
#endif
}
diff --git a/tcl8.6/generic/tclExecute.c b/tcl8.6/generic/tclExecute.c
index 761a23e..4c14514 100644
--- a/tcl8.6/generic/tclExecute.c
+++ b/tcl8.6/generic/tclExecute.c
@@ -1333,12 +1333,12 @@ TclStackAlloc(
int numBytes)
{
Interp *iPtr = (Interp *) interp;
- int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
+ int numWords;
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
return (void *) ckalloc(numBytes);
}
-
+ numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
return (void *) StackAllocWords(interp, numWords);
}
@@ -4169,7 +4169,8 @@ TEBCresume(
}
TRACE(("%s %u \"%.30s\" => ",
(flags ? "normal" : "noerr"), opnd, O2S(part2Ptr)));
- if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)) {
+ if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)
+ && !(arrayPtr->flags & VAR_SEARCH_ACTIVE)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (varPtr && TclIsVarDirectUnsettable(varPtr)) {
/*
@@ -4294,17 +4295,12 @@ TEBCresume(
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/0, /*createPart2*/0, &arrayPtr);
doArrayExists:
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- DECACHE_STACK_INFO();
- result = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
- NULL, (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|
- TCL_GLOBAL_ONLY|TCL_TRACE_ARRAY), 1, opnd);
- CACHE_STACK_INFO();
- if (result == TCL_ERROR) {
- TRACE_ERROR(interp);
- goto gotError;
- }
+ DECACHE_STACK_INFO();
+ result = TclCheckArrayTraces(interp, varPtr, arrayPtr, part1Ptr, opnd);
+ CACHE_STACK_INFO();
+ if (result == TCL_ERROR) {
+ TRACE_ERROR(interp);
+ goto gotError;
}
if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
objResultPtr = TCONST(1);
@@ -5089,16 +5085,9 @@ TEBCresume(
goto gotError;
}
- /*
- * Select the list item based on the index. Negative operand means
- * end-based indexing.
- */
+ /* Decode end-offset index values. */
- if (opnd < -1) {
- index = opnd+1 + objc;
- } else {
- index = opnd;
- }
+ index = TclIndexDecode(opnd, objc - 1);
pcAdjustment = 5;
lindexFastPath:
@@ -5246,60 +5235,64 @@ TEBCresume(
}
#endif
- /*
- * Adjust the indices for end-based handling.
+ /* Every range of an empty list is an empty list */
+ if (objc == 0) {
+ TRACE_APPEND(("\n"));
+ NEXT_INST_F(9, 0, 0);
+ }
+
+ /* Decode index value operands. */
+
+ /*
+ assert ( toIdx != TCL_INDEX_AFTER);
+ *
+ * Extra safety for legacy bytecodes:
*/
+ if (toIdx == TCL_INDEX_AFTER) {
+ toIdx = TCL_INDEX_END;
+ }
- if (fromIdx < -1) {
- fromIdx += 1+objc;
- if (fromIdx < -1) {
- fromIdx = -1;
- }
- } else if (fromIdx > objc) {
- fromIdx = objc;
+ if ((toIdx == TCL_INDEX_BEFORE) || (fromIdx == TCL_INDEX_AFTER)) {
+ goto emptyList;
}
- if (toIdx < -1) {
- toIdx += 1 + objc;
- if (toIdx < -1) {
- toIdx = -1;
- }
- } else if (toIdx > objc) {
- toIdx = objc;
+ toIdx = TclIndexDecode(toIdx, objc - 1);
+ if (toIdx < 0) {
+ goto emptyList;
+ } else if (toIdx >= objc) {
+ toIdx = objc - 1;
}
+ assert ( toIdx >= 0 && toIdx < objc);
/*
- * Check if we are referring to a valid, non-empty list range, and if
- * so, build the list of elements in that range.
+ assert ( fromIdx != TCL_INDEX_BEFORE );
+ *
+ * Extra safety for legacy bytecodes:
*/
+ if (fromIdx == TCL_INDEX_BEFORE) {
+ fromIdx = TCL_INDEX_START;
+ }
- if (fromIdx<=toIdx && fromIdx<objc && toIdx>=0) {
- if (fromIdx < 0) {
- fromIdx = 0;
- }
- if (toIdx >= objc) {
- toIdx = objc-1;
- }
- if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) {
- /*
- * BEWARE! This is looking inside the implementation of the
- * list type.
- */
-
- List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1;
+ fromIdx = TclIndexDecode(fromIdx, objc - 1);
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
- if (listPtr->refCount == 1) {
- for (index=toIdx+1; index<objc ; index++) {
- TclDecrRefCount(objv[index]);
- }
- listPtr->elemCount = toIdx+1;
- listPtr->canonicalFlag = 1;
- TclInvalidateStringRep(valuePtr);
- TRACE_APPEND(("%.30s\n", O2S(valuePtr)));
- NEXT_INST_F(9, 0, 0);
+ if (fromIdx <= toIdx) {
+ /* Construct the subsquence list */
+ /* unshared optimization */
+ if (Tcl_IsShared(valuePtr)) {
+ objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx);
+ } else {
+ if (toIdx != objc - 1) {
+ Tcl_ListObjReplace(NULL, valuePtr, toIdx + 1, LIST_MAX,
+ 0, NULL);
}
+ Tcl_ListObjReplace(NULL, valuePtr, 0, fromIdx, 0, NULL);
+ TRACE_APPEND(("%.30s\n", O2S(valuePtr)));
+ NEXT_INST_F(9, 0, 0);
}
- objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx);
} else {
+ emptyList:
TclNewObj(objResultPtr);
}
@@ -5391,88 +5384,10 @@ TEBCresume(
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
- if (valuePtr == value2Ptr) {
- match = 0;
- } else {
- /*
- * We only need to check (in)equality when we have equal length
- * strings. We can use memcmp in all (n)eq cases because we
- * don't need to worry about lexical LE/BE variance.
- */
-
- typedef int (*memCmpFn_t)(const void*, const void*, size_t);
- memCmpFn_t memCmpFn;
+ {
int checkEq = ((*pc == INST_EQ) || (*pc == INST_NEQ)
|| (*pc == INST_STR_EQ) || (*pc == INST_STR_NEQ));
-
- if (TclIsPureByteArray(valuePtr)
- && TclIsPureByteArray(value2Ptr)) {
- s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len);
- s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
- memCmpFn = memcmp;
- } else if ((valuePtr->typePtr == &tclStringType)
- && (value2Ptr->typePtr == &tclStringType)) {
- /*
- * Do a unicode-specific comparison if both of the args are of
- * String type. If the char length == byte length, we can do a
- * memcmp. In benchmark testing this proved the most efficient
- * check between the unicode and string comparison operations.
- */
-
- s1len = Tcl_GetCharLength(valuePtr);
- s2len = Tcl_GetCharLength(value2Ptr);
- if ((s1len == valuePtr->length)
- && (valuePtr->bytes != NULL)
- && (s2len == value2Ptr->length)
- && (value2Ptr->bytes != NULL)) {
- s1 = valuePtr->bytes;
- s2 = value2Ptr->bytes;
- memCmpFn = memcmp;
- } else {
- s1 = (char *) Tcl_GetUnicode(valuePtr);
- s2 = (char *) Tcl_GetUnicode(value2Ptr);
- if (
-#ifdef WORDS_BIGENDIAN
- 1
-#else
- checkEq
-#endif
- ) {
- memCmpFn = memcmp;
- s1len *= sizeof(Tcl_UniChar);
- s2len *= sizeof(Tcl_UniChar);
- } else {
- memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
- }
- }
- } else {
- /*
- * strcmp can't do a simple memcmp in order to handle the
- * special Tcl \xC0\x80 null encoding for utf-8.
- */
-
- s1 = TclGetStringFromObj(valuePtr, &s1len);
- s2 = TclGetStringFromObj(value2Ptr, &s2len);
- if (checkEq) {
- memCmpFn = memcmp;
- } else {
- memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
- }
- }
-
- if (checkEq && (s1len != s2len)) {
- match = 1;
- } else {
- /*
- * The comparison function should compare up to the minimum
- * byte length only.
- */
- match = memCmpFn(s1, s2,
- (size_t) ((s1len < s2len) ? s1len : s2len));
- if (match == 0) {
- match = s1len - s2len;
- }
- }
+ match = TclStringCmp(valuePtr, value2Ptr, checkEq, 0, -1);
}
/*
@@ -5645,31 +5560,58 @@ TEBCresume(
length = Tcl_GetCharLength(valuePtr);
TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx));
+ /* Every range of an empty value is an empty value */
+ if (length == 0) {
+ TRACE_APPEND(("\n"));
+ NEXT_INST_F(9, 0, 0);
+ }
+
+ /* Decode index operands. */
+
/*
- * Adjust indices for end-based indexing.
+ assert ( toIdx != TCL_INDEX_BEFORE );
+ assert ( toIdx != TCL_INDEX_AFTER);
+ *
+ * Extra safety for legacy bytecodes:
*/
-
- if (fromIdx < -1) {
- fromIdx += 1 + length;
- if (fromIdx < 0) {
- fromIdx = 0;
- }
- } else if (fromIdx >= length) {
- fromIdx = length;
+ if (toIdx == TCL_INDEX_BEFORE) {
+ goto emptyRange;
}
- if (toIdx < -1) {
- toIdx += 1 + length;
+ if (toIdx == TCL_INDEX_AFTER) {
+ toIdx = TCL_INDEX_END;
+ }
+
+ toIdx = TclIndexDecode(toIdx, length - 1);
+ if (toIdx < 0) {
+ goto emptyRange;
} else if (toIdx >= length) {
toIdx = length - 1;
}
+ assert ( toIdx >= 0 && toIdx < length );
+
/*
- * Check if we can do a sane substring.
+ assert ( fromIdx != TCL_INDEX_BEFORE );
+ assert ( fromIdx != TCL_INDEX_AFTER);
+ *
+ * Extra safety for legacy bytecodes:
*/
+ if (fromIdx == TCL_INDEX_BEFORE) {
+ fromIdx = TCL_INDEX_START;
+ }
+ if (fromIdx == TCL_INDEX_AFTER) {
+ goto emptyRange;
+ }
+
+ fromIdx = TclIndexDecode(fromIdx, length - 1);
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
if (fromIdx <= toIdx) {
objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx);
} else {
+ emptyRange:
TclNewObj(objResultPtr);
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
@@ -5677,18 +5619,18 @@ TEBCresume(
{
Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p;
- int length3;
+ int length3, endIdx;
Tcl_Obj *value3Ptr;
case INST_STR_REPLACE:
value3Ptr = POP_OBJECT();
valuePtr = OBJ_AT_DEPTH(2);
- length = Tcl_GetCharLength(valuePtr) - 1;
+ endIdx = Tcl_GetCharLength(valuePtr) - 1;
TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr),
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr)));
- if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
+ if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, endIdx,
&fromIdx) != TCL_OK
- || TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
+ || TclGetIntForIndexM(interp, OBJ_AT_TOS, endIdx,
&toIdx) != TCL_OK) {
TclDecrRefCount(value3Ptr);
TRACE_ERROR(interp);
@@ -5698,21 +5640,24 @@ TEBCresume(
(void) POP_OBJECT();
TclDecrRefCount(OBJ_AT_TOS);
(void) POP_OBJECT();
- if (fromIdx < 0) {
- fromIdx = 0;
- }
- if (fromIdx > toIdx || fromIdx > length) {
+ if ((toIdx < 0) ||
+ (fromIdx > endIdx) ||
+ (toIdx < fromIdx)) {
TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
TclDecrRefCount(value3Ptr);
NEXT_INST_F(1, 0, 0);
}
- if (toIdx > length) {
- toIdx = length;
+ if (fromIdx < 0) {
+ fromIdx = 0;
+ }
+
+ if (toIdx > endIdx) {
+ toIdx = endIdx;
}
- if (fromIdx == 0 && toIdx == length) {
+ if (fromIdx == 0 && toIdx == endIdx) {
TclDecrRefCount(OBJ_AT_TOS);
OBJ_AT_TOS = value3Ptr;
TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
@@ -5995,12 +5940,7 @@ TEBCresume(
value2Ptr = OBJ_AT_TOS; /* TrimSet */
string2 = TclGetStringFromObj(value2Ptr, &length2);
string1 = TclGetStringFromObj(valuePtr, &length);
- trim1 = TclTrimLeft(string1, length, string2, length2);
- if (trim1 < length) {
- trim2 = TclTrimRight(string1, length, string2, length2);
- } else {
- trim2 = 0;
- }
+ trim1 = TclTrim(string1, length, string2, length2, &trim2);
createTrimmedString:
/*
* Careful here; trim set often contains non-ASCII characters so we
@@ -6124,6 +6064,14 @@ TEBCresume(
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
+ /*
+ Try to determine, without triggering generation of a string
+ representation, whether one value is not a number.
+ */
+ if (TclCheckEmptyString(valuePtr) > 0 || TclCheckEmptyString(value2Ptr) > 0) {
+ goto stringCompare;
+ }
+
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK
|| GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) {
/*
diff --git a/tcl8.6/generic/tclFCmd.c b/tcl8.6/generic/tclFCmd.c
index bb814ea..fda2940 100644
--- a/tcl8.6/generic/tclFCmd.c
+++ b/tcl8.6/generic/tclFCmd.c
@@ -240,9 +240,13 @@ TclFileMakeDirsCmd(
break;
}
for (j = 0; j < pobjc; j++) {
+ int errCount = 2;
+
target = Tcl_FSJoinPath(split, j + 1);
Tcl_IncrRefCount(target);
+ createDir:
+
/*
* Call Tcl_FSStat() so that if target is a symlink that points to
* a directory we will create subdirectories in that directory.
@@ -269,23 +273,25 @@ TclFileMakeDirsCmd(
* subdirectory.
*/
- if (errno != EEXIST) {
- errfile = target;
- goto done;
- } else if ((Tcl_FSStat(target, &statBuf) == 0)
- && S_ISDIR(statBuf.st_mode)) {
- /*
- * It is a directory that wasn't there before, so keep
- * going without error.
- */
-
- Tcl_ResetResult(interp);
- } else {
- errfile = target;
- goto done;
+ if (errno == EEXIST) {
+ /* Be aware other workers could delete it immediately after
+ * creation, so give this worker still one chance (repeat once),
+ * see [270f78ca95] for description of the race-condition.
+ * Don't repeat the create always (to avoid endless loop). */
+ if (--errCount > 0) {
+ goto createDir;
+ }
+ /* Already tried, with delete in-between directly after
+ * creation, so just continue (assume created successful). */
+ goto nextPart;
}
+
+ /* return with error */
+ errfile = target;
+ goto done;
}
+ nextPart:
/*
* Forget about this sub-path.
*/
@@ -363,14 +369,7 @@ TclFileDeleteCmd(
*/
if (Tcl_FSLstat(objv[i], &statBuf) != 0) {
- /*
- * Trying to delete a file that does not exist is not considered
- * an error, just a no-op
- */
-
- if (errno != ENOENT) {
- result = TCL_ERROR;
- }
+ result = TCL_ERROR;
} else if (S_ISDIR(statBuf.st_mode)) {
/*
* We own a reference count on errorBuffer, if it was set as a
@@ -406,13 +405,20 @@ TclFileDeleteCmd(
}
if (result != TCL_OK) {
- result = TCL_ERROR;
/*
+ * Avoid possible race condition (file/directory deleted after call
+ * of lstat), so bypass ENOENT because not an error, just a no-op
+ */
+ if (errno == ENOENT) {
+ result = TCL_OK;
+ continue;
+ }
+ /*
* It is important that we break on error, otherwise we might end
* up owning reference counts on numerous errorBuffers.
*/
-
+ result = TCL_ERROR;
break;
}
}
diff --git a/tcl8.6/generic/tclFileName.c b/tcl8.6/generic/tclFileName.c
index 2136883..b566d7f 100644
--- a/tcl8.6/generic/tclFileName.c
+++ b/tcl8.6/generic/tclFileName.c
@@ -1904,7 +1904,7 @@ TclGlob(
}
/*
- * To process a [glob] invokation, this function may be called multiple
+ * To process a [glob] invocation, this function may be called multiple
* times. Each time, the previously discovered filenames are in the
* interpreter result. We stash that away here so the result is free for
* error messsages.
diff --git a/tcl8.6/generic/tclIO.c b/tcl8.6/generic/tclIO.c
index e74624f..d603d76 100644
--- a/tcl8.6/generic/tclIO.c
+++ b/tcl8.6/generic/tclIO.c
@@ -711,17 +711,18 @@ Tcl_SetStdChannel(
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ int init = channel ? 1 : -1;
switch (type) {
case TCL_STDIN:
- tsdPtr->stdinInitialized = 1;
+ tsdPtr->stdinInitialized = init;
tsdPtr->stdinChannel = channel;
break;
case TCL_STDOUT:
- tsdPtr->stdoutInitialized = 1;
+ tsdPtr->stdoutInitialized = init;
tsdPtr->stdoutChannel = channel;
break;
case TCL_STDERR:
- tsdPtr->stderrInitialized = 1;
+ tsdPtr->stderrInitialized = init;
tsdPtr->stderrChannel = channel;
break;
}
@@ -758,8 +759,8 @@ Tcl_GetStdChannel(
switch (type) {
case TCL_STDIN:
if (!tsdPtr->stdinInitialized) {
+ tsdPtr->stdinInitialized = -1;
tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN);
- tsdPtr->stdinInitialized = 1;
/*
* Artificially bump the refcount to ensure that the channel is
@@ -771,6 +772,7 @@ Tcl_GetStdChannel(
*/
if (tsdPtr->stdinChannel != NULL) {
+ tsdPtr->stdinInitialized = 1;
Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel);
}
}
@@ -778,9 +780,10 @@ Tcl_GetStdChannel(
break;
case TCL_STDOUT:
if (!tsdPtr->stdoutInitialized) {
+ tsdPtr->stdoutInitialized = -1;
tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT);
- tsdPtr->stdoutInitialized = 1;
if (tsdPtr->stdoutChannel != NULL) {
+ tsdPtr->stdoutInitialized = 1;
Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel);
}
}
@@ -788,9 +791,10 @@ Tcl_GetStdChannel(
break;
case TCL_STDERR:
if (!tsdPtr->stderrInitialized) {
+ tsdPtr->stderrInitialized = -1;
tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR);
- tsdPtr->stderrInitialized = 1;
if (tsdPtr->stderrChannel != NULL) {
+ tsdPtr->stderrInitialized = 1;
Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel);
}
}
@@ -1058,7 +1062,7 @@ CheckForStdChannelsBeingClosed(
ChannelState *statePtr = ((Channel *) chan)->state;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
- if (tsdPtr->stdinInitialized
+ if (tsdPtr->stdinInitialized == 1
&& tsdPtr->stdinChannel != NULL
&& statePtr == ((Channel *)tsdPtr->stdinChannel)->state) {
if (statePtr->refCount < 2) {
@@ -1066,7 +1070,7 @@ CheckForStdChannelsBeingClosed(
tsdPtr->stdinChannel = NULL;
return;
}
- } else if (tsdPtr->stdoutInitialized
+ } else if (tsdPtr->stdoutInitialized == 1
&& tsdPtr->stdoutChannel != NULL
&& statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) {
if (statePtr->refCount < 2) {
@@ -1074,7 +1078,7 @@ CheckForStdChannelsBeingClosed(
tsdPtr->stdoutChannel = NULL;
return;
}
- } else if (tsdPtr->stderrInitialized
+ } else if (tsdPtr->stderrInitialized == 1
&& tsdPtr->stderrChannel != NULL
&& statePtr == ((Channel *)tsdPtr->stderrChannel)->state) {
if (statePtr->refCount < 2) {
diff --git a/tcl8.6/generic/tclIOUtil.c b/tcl8.6/generic/tclIOUtil.c
index 19620e7..27acbbc 100644
--- a/tcl8.6/generic/tclIOUtil.c
+++ b/tcl8.6/generic/tclIOUtil.c
@@ -139,7 +139,6 @@ Tcl_FSRenameFileProc TclpObjRenameFile;
Tcl_FSCreateDirectoryProc TclpObjCreateDirectory;
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
-Tcl_FSUnloadFileProc TclpUnloadFile;
Tcl_FSLinkProc TclpObjLink;
Tcl_FSListVolumesProc TclpObjListVolumes;
@@ -3159,8 +3158,8 @@ Tcl_FSLoadFile(
* present and set to true (any integer > 0) then the unlink is skipped.
*/
-int
-TclSkipUnlink (Tcl_Obj* shlibFile)
+static int
+skipUnlink (Tcl_Obj* shlibFile)
{
/* Order of testing:
* 1. On hpux we generally want to skip unlink in general
@@ -3414,7 +3413,7 @@ Tcl_LoadFile(
*/
if (
- !TclSkipUnlink (copyToPtr) &&
+ !skipUnlink (copyToPtr) &&
(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
Tcl_DecrRefCount(copyToPtr);
@@ -3683,30 +3682,10 @@ Tcl_FSUnloadFile(
}
return TCL_ERROR;
}
- TclpUnloadFile(handle);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclpUnloadFile --
- *
- * Unloads a library given its handle
- *
- * This function was once filesystem-specific, but has been made portable by
- * having TclpDlopen return a structure that includes procedure pointers.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TclpUnloadFile(
- Tcl_LoadHandle handle)
-{
if (handle->unloadFileProcPtr != NULL) {
handle->unloadFileProcPtr(handle);
}
+ return TCL_OK;
}
/*
diff --git a/tcl8.6/generic/tclInt.decls b/tcl8.6/generic/tclInt.decls
index 2a3d2a0..e9af34a 100644
--- a/tcl8.6/generic/tclInt.decls
+++ b/tcl8.6/generic/tclInt.decls
@@ -1088,7 +1088,7 @@ declare 9 win {
}
# new for 8.4.20+/8.5.12+ Cygwin only
declare 10 win {
- Tcl_DirEntry *TclpReaddir(DIR *dir)
+ Tcl_DirEntry *TclpReaddir(TclDIR *dir)
}
# Removed in 8.3.1 (for Win32s only)
#declare 10 win {
@@ -1226,7 +1226,7 @@ declare 9 unix {
# Added in 8.4:
declare 10 unix {
- Tcl_DirEntry *TclpReaddir(DIR *dir)
+ Tcl_DirEntry *TclpReaddir(TclDIR *dir)
}
# Slots 11 and 12 are forwarders for functions that were promoted to
# generic Stubs
diff --git a/tcl8.6/generic/tclInt.h b/tcl8.6/generic/tclInt.h
index 91c8b96..432be7a 100644
--- a/tcl8.6/generic/tclInt.h
+++ b/tcl8.6/generic/tclInt.h
@@ -413,7 +413,7 @@ struct NamespacePathEntry {
*/
typedef struct EnsembleConfig {
- Namespace *nsPtr; /* The namspace backing this ensemble up. */
+ Namespace *nsPtr; /* The namespace backing this ensemble up. */
Tcl_Command token; /* The token for the command that provides
* ensemble support for the namespace, or NULL
* if the command has been deleted (or never
@@ -1813,7 +1813,7 @@ typedef struct Interp {
* unused space in interp was repurposed for
* pluggable bytecode optimizers. The core
* contains one optimizer, which can be
- * selectively overriden by extensions. */
+ * selectively overridden by extensions. */
} extra;
/*
@@ -2228,7 +2228,7 @@ typedef struct Interp {
* use the rand() or srand() functions.
* SAFE_INTERP: Non zero means that the current interp is a safe
* interp (i.e. it has only the safe commands installed,
- * less priviledge than a regular interp).
+ * less privilege than a regular interp).
* INTERP_DEBUG_FRAME: Used for switching on various extra interpreter
* debug/info mechanisms (e.g. info frame eval/uplevel
* tracing) which are performance intensive.
@@ -2369,7 +2369,7 @@ typedef struct List {
* be ignored if there is no string rep at
* all.*/
Tcl_Obj *elements; /* First list element; the struct is grown to
- * accomodate all elements. */
+ * accommodate all elements. */
} List;
#define LIST_MAX \
@@ -2491,13 +2491,13 @@ typedef struct List {
* tip of the path, so duplication of shared objects should be done along the
* way.
*
- * DICT_PATH_EXISTS indicates that we are performing an existance test and a
+ * DICT_PATH_EXISTS indicates that we are performing an existence test and a
* lookup failure should therefore not be an error. If (and only if) this flag
* is set, TclTraceDictPath() will return the special value
* DICT_PATH_NON_EXISTENT if the path is not traceable.
*
* DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set)
- * indicates that we are to create non-existant dictionaries on the path.
+ * indicates that we are to create non-existent dictionaries on the path.
*/
#define DICT_PATH_READ 0
@@ -2735,6 +2735,10 @@ MODULE_SCOPE long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS];
MODULE_SCOPE char * tclEmptyStringRep;
MODULE_SCOPE char tclEmptyString;
+enum CheckEmptyStringResult {
+ TCL_EMPTYSTRING_UNKNOWN = -1, TCL_EMPTYSTRING_NO, TCL_EMPTYSTRING_YES
+};
+
/*
*----------------------------------------------------------------
* Procedures shared among Tcl modules but not used by the outside world,
@@ -2750,6 +2754,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRPackageObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd;
@@ -2863,8 +2868,6 @@ MODULE_SCOPE void TclArgumentBCRelease(Tcl_Interp *interp,
CmdFrame *cfPtr);
MODULE_SCOPE void TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj,
CmdFrame **cfPtrPtr, int *wordPtr);
-MODULE_SCOPE int TclArraySet(Tcl_Interp *interp,
- Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj);
MODULE_SCOPE double TclBignumToDouble(const mp_int *bignum);
MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string,
int strLen, const unsigned char *pattern,
@@ -2872,8 +2875,11 @@ MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string,
MODULE_SCOPE double TclCeil(const mp_int *a);
MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan);
MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan);
+MODULE_SCOPE int TclCheckArrayTraces(Tcl_Interp *interp, Var *varPtr,
+ Var *arrayPtr, Tcl_Obj *name, int index);
MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp,
const char *value);
+MODULE_SCOPE int TclCheckEmptyString(Tcl_Obj *objPtr);
MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
Tcl_Channel chan);
MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
@@ -2887,6 +2893,19 @@ MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr,
Tcl_Obj *originObjPtr);
MODULE_SCOPE int TclConvertElement(const char *src, int length,
char *dst, int flags);
+MODULE_SCOPE Tcl_Command TclCreateObjCommandInNs (
+ Tcl_Interp *interp,
+ const char *cmdName,
+ Tcl_Namespace *nsPtr,
+ Tcl_ObjCmdProc *proc,
+ ClientData clientData,
+ Tcl_CmdDeleteProc *deleteProc);
+MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(
+ Tcl_Interp *interp,
+ const char *name,
+ Tcl_Namespace *nameNamespacePtr,
+ Tcl_Namespace *ensembleNamespacePtr,
+ int flags);
MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr);
MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp,
const char *dict, int dictLength,
@@ -2915,6 +2934,10 @@ MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
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 Tcl_Namespace * TclEnsureNamespace(
+ Tcl_Interp *interp,
+ Tcl_Namespace *namespacePtr);
+
MODULE_SCOPE void TclFinalizeAllocSubsystem(void);
MODULE_SCOPE void TclFinalizeAsync(void);
MODULE_SCOPE void TclFinalizeDoubleConversion(void);
@@ -2940,6 +2963,15 @@ MODULE_SCOPE double TclFloor(const mp_int *a);
MODULE_SCOPE void TclFormatNaN(double value, char *buffer);
MODULE_SCOPE int TclFSFileAttrIndex(Tcl_Obj *pathPtr,
const char *attributeName, int *indexPtr);
+MODULE_SCOPE Tcl_Command TclNRCreateCommandInNs (
+ Tcl_Interp *interp,
+ const char *cmdName,
+ Tcl_Namespace *nsPtr,
+ Tcl_ObjCmdProc *proc,
+ Tcl_ObjCmdProc *nreProc,
+ ClientData clientData,
+ Tcl_CmdDeleteProc *deleteProc);
+
MODULE_SCOPE int TclNREvalFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
const char *encodingName);
MODULE_SCOPE void TclFSUnloadTempFile(Tcl_LoadHandle loadHandle);
@@ -3123,6 +3155,12 @@ MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp,
Tcl_Obj *bad, Tcl_Obj *fix);
MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr,
int numBytes);
+
+typedef int (*memCmpFn_t)(const void*, const void*, size_t);
+MODULE_SCOPE int TclStringCmp (Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr,
+ int checkEq, int nocase, int reqlength);
+MODULE_SCOPE int TclStringCmpOpts (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
+ int *nocase, int *reqlength);
MODULE_SCOPE int TclStringMatch(const char *str, int strLen,
const char *pattern, int ptnLen, int flags);
MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj,
@@ -3139,6 +3177,8 @@ MODULE_SCOPE void TclSubstParse(Tcl_Interp *interp, const char *bytes,
MODULE_SCOPE int TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
int count, int *tokensLeftPtr, int line,
int *clNextOuter, const char *outerScript);
+MODULE_SCOPE int TclTrim(const char *bytes, int numBytes,
+ const char *trim, int numTrim, int *trimRight);
MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes,
const char *trim, int numTrim);
MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes,
@@ -3984,6 +4024,21 @@ MODULE_SCOPE unsigned TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
MODULE_SCOPE int TclFullFinalizationRequested(void);
/*
+ * Utility routines for encoding index values as integers. Used by both
+ * some of the command compilers and by [lsort] and [lsearch].
+ */
+
+MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ int before, int after, int *indexPtr);
+MODULE_SCOPE int TclIndexDecode(int encoded, int endValue);
+
+/* Constants used in index value encoding routines. */
+#define TCL_INDEX_END (-2)
+#define TCL_INDEX_BEFORE (-1)
+#define TCL_INDEX_START (0)
+#define TCL_INDEX_AFTER (INT_MAX)
+
+/*
*----------------------------------------------------------------
* Macros used by the Tcl core to create and release Tcl objects.
* TclNewObj(objPtr) creates a new object denoting an empty string.
@@ -4411,6 +4466,11 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
#define TclIsPureByteArray(objPtr) \
(((objPtr)->typePtr==&tclByteArrayType) && ((objPtr)->bytes==NULL))
+#define TclIsPureDict(objPtr) \
+ (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType))
+
+#define TclIsPureList(objPtr) \
+ (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclListType))
/*
*----------------------------------------------------------------
@@ -4432,7 +4492,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
/*
*----------------------------------------------------------------
- * Macro used by the Tcl core to increment a namespace's export export epoch
+ * Macro used by the Tcl core to increment a namespace's export epoch
* counter. The ANSI C "prototype" for this macro is:
*
* MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr);
diff --git a/tcl8.6/generic/tclIntPlatDecls.h b/tcl8.6/generic/tclIntPlatDecls.h
index ac06787..903327f 100644
--- a/tcl8.6/generic/tclIntPlatDecls.h
+++ b/tcl8.6/generic/tclIntPlatDecls.h
@@ -13,11 +13,6 @@
#ifndef _TCLINTPLATDECLS
#define _TCLINTPLATDECLS
-#ifdef _WIN32
-# define Tcl_DirEntry void
-# define DIR void
-#endif
-
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
@@ -72,7 +67,7 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout);
/* 9 */
EXTERN TclFile TclpCreateTempFile(const char *contents);
/* 10 */
-EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
+EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
/* 11 */
EXTERN struct tm * TclpLocaltime_unix(const time_t *clock);
/* 12 */
@@ -129,7 +124,7 @@ EXTERN int TclpGetPid(Tcl_Pid pid);
/* 9 */
EXTERN int TclWinGetPlatformId(void);
/* 10 */
-EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
+EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
/* 11 */
EXTERN void TclGetAndDetachPids(Tcl_Interp *interp,
Tcl_Channel chan);
@@ -206,7 +201,7 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout);
/* 9 */
EXTERN TclFile TclpCreateTempFile(const char *contents);
/* 10 */
-EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
+EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
/* 11 */
EXTERN struct tm * TclpLocaltime_unix(const time_t *clock);
/* 12 */
@@ -269,7 +264,7 @@ typedef struct TclIntPlatStubs {
TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
- Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+ Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
@@ -302,7 +297,7 @@ typedef struct TclIntPlatStubs {
int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, int optlen); /* 7 */
int (*tclpGetPid) (Tcl_Pid pid); /* 8 */
int (*tclWinGetPlatformId) (void); /* 9 */
- Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+ Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 11 */
int (*tclpCloseFile) (TclFile file); /* 12 */
Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 13 */
@@ -335,7 +330,7 @@ typedef struct TclIntPlatStubs {
TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
- Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+ Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
diff --git a/tcl8.6/generic/tclListObj.c b/tcl8.6/generic/tclListObj.c
index 3a1555d..e42567e 100644
--- a/tcl8.6/generic/tclListObj.c
+++ b/tcl8.6/generic/tclListObj.c
@@ -55,20 +55,22 @@ const Tcl_ObjType tclListType = {
*
* NewListIntRep --
*
- * Creates a list internal rep with space for objc elements. objc
- * must be > 0. If objv!=NULL, initializes with the first objc values
- * in that array. If objv==NULL, initalize list internal rep to have
- * 0 elements, with space to add objc more. Flag value "p" indicates
+ * Creates a 'List' structure with space for 'objc' elements. 'objc' must
+ * be > 0. If 'objv' is not NULL, The list is initialized with first
+ * 'objc' values in that array. Otherwise the list is initialized to have
+ * 0 elements, with space to add 'objc' more. Flag value 'p' indicates
* how to behave on failure.
*
- * Results:
- * A new List struct with refCount 0 is returned. If some failure
- * prevents this then if p=0, NULL is returned and otherwise the
- * routine panics.
+ * Value
*
- * Side effects:
- * The ref counts of the elements in objv are incremented since the
- * resulting list now refers to them.
+ * A new 'List' structure with refCount 0. If some failure
+ * prevents this NULL is returned if 'p' is 0 , and 'Tcl_Panic'
+ * is called if it is not.
+ *
+ * Effect
+ *
+ * The refCount of each value in 'objv' is incremented as it is added
+ * to the list.
*
*----------------------------------------------------------------------
*/
@@ -132,22 +134,10 @@ NewListIntRep(
/*
*----------------------------------------------------------------------
*
- * AttemptNewList --
- *
- * Creates a list internal rep with space for objc elements. objc
- * must be > 0. If objv!=NULL, initializes with the first objc values
- * in that array. If objv==NULL, initalize list internal rep to have
- * 0 elements, with space to add objc more.
- *
- * Results:
- * A new List struct with refCount 0 is returned. If some failure
- * prevents this then NULL is returned, and an error message is left
- * in the interp result, unless interp is NULL.
- *
- * Side effects:
- * The ref counts of the elements in objv are incremented since the
- * resulting list now refers to them.
+ * AttemptNewList --
*
+ * Like NewListIntRep, but additionally sets an error message on failure.
+ *
*----------------------------------------------------------------------
*/
@@ -179,23 +169,20 @@ AttemptNewList(
*
* Tcl_NewListObj --
*
- * This function is normally called when not debugging: i.e., when
- * TCL_MEM_DEBUG is not defined. It creates a new list object from an
- * (objc,objv) array: that is, each of the objc elements of the array
- * referenced by objv is inserted as an element into a new Tcl object.
+ * Creates a new list object and adds values to it. When TCL_MEM_DEBUG is
+ * defined, 'Tcl_DbNewListObj' is called instead.
*
- * When TCL_MEM_DEBUG is defined, this function just returns the result
- * of calling the debugging version Tcl_DbNewListObj.
+ * Value
*
- * Results:
- * A new list object is returned that is initialized from the object
- * pointers in objv. If objc is less than or equal to zero, an empty
- * object is returned. The new object's string representation is left
- * NULL. The resulting new list object has ref count 0.
+ * A new list 'Tcl_Obj' to which is appended values from 'objv', or if
+ * 'objc' is less than or equal to zero, a list 'Tcl_Obj' having no
+ * elements. The string representation of the new 'Tcl_Obj' is set to
+ * NULL. The refCount of the list is 0.
*
- * Side effects:
- * The ref counts of the elements in objv are incremented since the
- * resulting list now refers to them.
+ * Effect
+ *
+ * The refCount of each elements in 'objv' is incremented as it is added
+ * to the list.
*
*----------------------------------------------------------------------
*/
@@ -246,28 +233,14 @@ Tcl_NewListObj(
/*
*----------------------------------------------------------------------
*
- * Tcl_DbNewListObj --
- *
- * This function is normally called when debugging: i.e., when
- * TCL_MEM_DEBUG is defined. It creates new list objects. It is the same
- * as the Tcl_NewListObj function above except that it calls
- * Tcl_DbCkalloc directly with the file name and line number from its
- * caller. This simplifies debugging since then the [memory active]
- * command will report the correct file name and line number when
- * reporting objects that haven't been freed.
- *
- * When TCL_MEM_DEBUG is not defined, this function just returns the
- * result of calling Tcl_NewListObj.
- *
- * Results:
- * A new list object is returned that is initialized from the object
- * pointers in objv. If objc is less than or equal to zero, an empty
- * object is returned. The new object's string representation is left
- * NULL. The new list object has ref count 0.
- *
- * Side effects:
- * The ref counts of the elements in objv are incremented since the
- * resulting list now refers to them.
+ * Tcl_DbNewListObj --
+ *
+ * Like 'Tcl_NewListObj', but it calls Tcl_DbCkalloc directly with the
+ * file name and line number from its caller. This simplifies debugging
+ * since the [memory active] command will report the correct file
+ * name and line number when reporting objects that haven't been freed.
+ *
+ * When TCL_MEM_DEBUG is not defined, 'Tcl_NewListObj' is called instead.
*
*----------------------------------------------------------------------
*/
@@ -328,19 +301,8 @@ Tcl_DbNewListObj(
*
* Tcl_SetListObj --
*
- * Modify an object to be a list containing each of the objc elements of
- * the object array referenced by objv.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The object is made a list object and is initialized from the object
- * pointers in objv. If objc is less than or equal to zero, an empty
- * object is returned. The new object's string representation is left
- * NULL. The ref counts of the elements in objv are incremented since the
- * list now refers to them. The object's old string and internal
- * representations are freed and its type is set NULL.
+ * Like 'Tcl_NewListObj', but operates on an existing 'Tcl_Obj'instead of
+ * creating a new one.
*
*----------------------------------------------------------------------
*/
@@ -384,18 +346,20 @@ Tcl_SetListObj(
*
* TclListObjCopy --
*
- * Makes a "pure list" copy of a list value. This provides for the C
- * level a counterpart of the [lrange $list 0 end] command, while using
- * internals details to be as efficient as possible.
+ * Creates a new 'Tcl_Obj' which is a pure copy of a list value. This
+ * provides for the C level a counterpart of the [lrange $list 0 end]
+ * command, while using internals details to be as efficient as possible.
+ *
+ * Value
*
- * Results:
- * Normally returns a pointer to a new Tcl_Obj, that contains the same
- * list value as *listPtr does. The returned Tcl_Obj has a refCount of
- * zero. If *listPtr does not hold a list, NULL is returned, and if
- * interp is non-NULL, an error message is recorded there.
+ * The address of the new 'Tcl_Obj' which shares its internal
+ * representation with 'listPtr', and whose refCount is 0. If 'listPtr'
+ * is not actually a list, the value is NULL, and an error message is left
+ * in 'interp' if it is not NULL.
*
- * Side effects:
- * None.
+ * Effect
+ *
+ * 'listPtr' is converted to a list if it isn't one already.
*
*----------------------------------------------------------------------
*/
@@ -425,27 +389,30 @@ TclListObjCopy(
*
* Tcl_ListObjGetElements --
*
- * This function returns an (objc,objv) array of the elements in a list
- * object.
+ * Retreive the elements in a list 'Tcl_Obj'.
+ *
+ * Value
+ *
+ * TCL_OK
+ *
+ * A count of list elements is stored, 'objcPtr', And a pointer to the
+ * array of elements in the list is stored in 'objvPtr'.
+ *
+ * The elements accessible via 'objvPtr' should be treated as readonly
+ * and the refCount for each object is _not_ incremented; the caller
+ * must do that if it holds on to a reference. Furthermore, the
+ * pointer and length returned by this function may change as soon as
+ * any function is called on the list object. Be careful about
+ * retaining the pointer in a local data structure.
+ *
+ * TCL_ERROR
*
- * Results:
- * The return value is normally TCL_OK; in this case *objcPtr is set to
- * the count of list elements and *objvPtr is set to a pointer to an
- * array of (*objcPtr) pointers to each list element. If listPtr does not
- * refer to a list object and the object can not be converted to one,
- * TCL_ERROR is returned and an error message will be left in the
- * interpreter's result if interp is not NULL.
+ * 'listPtr' is not a valid list. An error message is left in the
+ * interpreter's result if 'interp' is not NULL.
*
- * The objects referenced by the returned array should be treated as
- * readonly and their ref counts are _not_ incremented; the caller must
- * do that if it holds on to a reference. Furthermore, the pointer and
- * length returned by this function may change as soon as any function is
- * called on the list object; be careful about retaining the pointer in a
- * local data structure.
+ * Effect
*
- * Side effects:
- * The possible conversion of the object referenced by listPtr
- * to a list object.
+ * 'listPtr' is converted to a list object if it isn't one already.
*
*----------------------------------------------------------------------
*/
@@ -486,20 +453,27 @@ Tcl_ListObjGetElements(
*
* Tcl_ListObjAppendList --
*
- * This function appends the elements in the list value referenced by
- * elemListPtr to the list value referenced by listPtr.
+ * Appends the elements of elemListPtr to those of listPtr.
*
- * Results:
- * The return value is normally TCL_OK. If listPtr or elemListPtr do not
- * refer to list values, TCL_ERROR is returned and an error message is
- * left in the interpreter's result if interp is not NULL.
+ * Value
*
- * Side effects:
- * The reference counts of the elements in elemListPtr are incremented
- * since the list now refers to them. listPtr and elemListPtr are
- * converted, if necessary, to list objects. Also, appending the new
- * elements may cause listObj's array of element pointers to grow.
- * listPtr's old string representation, if any, is invalidated.
+ * TCL_OK
+ *
+ * Success.
+ *
+ * TCL_ERROR
+ *
+ * 'listPtr' or 'elemListPtr' are not valid lists. An error
+ * message is left in the interpreter's result if 'interp' is not NULL.
+ *
+ * Effect
+ *
+ * The reference count of each element of 'elemListPtr' as it is added to
+ * 'listPtr'. 'listPtr' and 'elemListPtr' are converted to 'tclListType'
+ * if they are not already. Appending the new elements may cause the
+ * array of element pointers in 'listObj' to grow. If any objects are
+ * appended to 'listPtr'. Any preexisting string representation of
+ * 'listPtr' is invalidated.
*
*----------------------------------------------------------------------
*/
@@ -538,24 +512,27 @@ Tcl_ListObjAppendList(
*
* Tcl_ListObjAppendElement --
*
- * This function is a special purpose version of Tcl_ListObjAppendList:
- * it appends a single object referenced by objPtr to the list object
- * referenced by listPtr. If listPtr is not already a list object, an
- * attempt will be made to convert it to one.
- *
- * Results:
- * The return value is normally TCL_OK; in this case objPtr is added to
- * the end of listPtr's list. If listPtr does not refer to a list object
- * and the object can not be converted to one, TCL_ERROR is returned and
- * an error message will be left in the interpreter's result if interp is
- * not NULL.
- *
- * Side effects:
- * The ref count of objPtr is incremented since the list now refers to
- * it. listPtr will be converted, if necessary, to a list object. Also,
- * appending the new element may cause listObj's array of element
- * pointers to grow. listPtr's old string representation, if any, is
- * invalidated.
+ * Like 'Tcl_ListObjAppendList', but Appends a single value to a list.
+ *
+ * Value
+ *
+ * TCL_OK
+ *
+ * 'objPtr' is appended to the elements of 'listPtr'.
+ *
+ * TCL_ERROR
+ *
+ * listPtr does not refer to a list object and the object can not be
+ * converted to one. An error message will be left in the
+ * interpreter's result if interp is not NULL.
+ *
+ * Effect
+ *
+ * If 'listPtr' is not already of type 'tclListType', it is converted.
+ * The 'refCount' of 'objPtr' is incremented as it is added to 'listPtr'.
+ * Appending the new element may cause the the array of element pointers
+ * in 'listObj' to grow. Any preexisting string representation of
+ * 'listPtr' is invalidated.
*
*----------------------------------------------------------------------
*/
@@ -706,23 +683,27 @@ Tcl_ListObjAppendElement(
*
* Tcl_ListObjIndex --
*
- * This function returns a pointer to the index'th object from the list
- * referenced by listPtr. The first element has index 0. If index is
- * negative or greater than or equal to the number of elements in the
- * list, a NULL is returned. If listPtr is not a list object, an attempt
- * will be made to convert it to a list.
+ * Retrieve a pointer to the element of 'listPtr' at 'index'. The index
+ * of the first element is 0.
+ *
+ * Value
*
- * Results:
- * The return value is normally TCL_OK; in this case objPtrPtr is set to
- * the Tcl_Obj pointer for the index'th list element or NULL if index is
- * out of range. This object should be treated as readonly and its ref
- * count is _not_ incremented; the caller must do that if it holds on to
- * the reference. If listPtr does not refer to a list and can't be
- * converted to one, TCL_ERROR is returned and an error message is left
- * in the interpreter's result if interp is not NULL.
+ * TCL_OK
*
- * Side effects:
- * listPtr will be converted, if necessary, to a list object.
+ * A pointer to the element at 'index' is stored in 'objPtrPtr'. If
+ * 'index' is out of range, NULL is stored in 'objPtrPtr'. This
+ * object should be treated as readonly and its 'refCount' is _not_
+ * incremented. The caller must do that if it holds on to the
+ * reference.
+ *
+ * TCL_ERROR
+ *
+ * 'listPtr' is not a valid list. An an error message is left in the
+ * interpreter's result if 'interp' is not NULL.
+ *
+ * Effect
+ *
+ * If 'listPtr' is not already of type 'tclListType', it is converted.
*
*----------------------------------------------------------------------
*/
@@ -764,19 +745,20 @@ Tcl_ListObjIndex(
*
* Tcl_ListObjLength --
*
- * This function returns the number of elements in a list object. If the
- * object is not already a list object, an attempt will be made to
- * convert it to one.
+ * Retrieve the number of elements in a list.
+ *
+ * Value
*
- * Results:
- * The return value is normally TCL_OK; in this case *intPtr will be set
- * to the integer count of list elements. If listPtr does not refer to a
- * list object and the object can not be converted to one, TCL_ERROR is
- * returned and an error message will be left in the interpreter's result
- * if interp is not NULL.
+ * TCL_OK
*
- * Side effects:
- * The possible conversion of the argument object to a list object.
+ * A count of list elements is stored at the address provided by
+ * 'intPtr'. If 'listPtr' is not already of type 'tclListPtr', it is
+ * converted.
+ *
+ * TCL_ERROR
+ *
+ * 'listPtr' is not a valid list. An error message will be left in
+ * the interpreter's result if 'interp' is not NULL.
*
*----------------------------------------------------------------------
*/
@@ -812,35 +794,36 @@ Tcl_ListObjLength(
*
* Tcl_ListObjReplace --
*
- * This function replaces zero or more elements of the list referenced by
- * listPtr with the objects from an (objc,objv) array. The objc elements
- * of the array referenced by objv replace the count elements in listPtr
- * starting at first.
- *
- * If the argument first is zero or negative, it refers to the first
- * element. If first is greater than or equal to the number of elements
- * in the list, then no elements are deleted; the new elements are
- * appended to the list. Count gives the number of elements to replace.
- * If count is zero or negative then no elements are deleted; the new
- * elements are simply inserted before first.
- *
- * The argument objv refers to an array of objc pointers to the new
- * elements to be added to listPtr in place of those that were deleted.
- * If objv is NULL, no new elements are added. If listPtr is not a list
- * object, an attempt will be made to convert it to one.
- *
- * Results:
- * The return value is normally TCL_OK. If listPtr does not refer to a
- * list object and can not be converted to one, TCL_ERROR is returned and
- * an error message will be left in the interpreter's result if interp is
- * not NULL.
- *
- * Side effects:
- * The ref counts of the objc elements in objv are incremented since the
- * resulting list now refers to them. Similarly, the ref counts for
- * replaced objects are decremented. listPtr is converted, if necessary,
- * to a list object. listPtr's old string representation, if any, is
- * freed.
+ * Replace values in a list.
+ *
+ * If 'first' is zero or negative, it refers to the first element. If
+ * 'first' outside the range of elements in the list, no elements are
+ * deleted.
+ *
+ * If 'count' is zero or negative no elements are deleted, and any new
+ * elements are inserted at the beginning of the list.
+ *
+ * Value
+ *
+ * TCL_OK
+ *
+ * The first 'objc' values of 'objv' replaced 'count' elements in 'listPtr'
+ * starting at 'first'. If 'objc' 0, no new elements are added.
+ *
+ * TCL_ERROR
+ *
+ * 'listPtr' is not a valid list. An error message is left in the
+ * interpreter's result if 'interp' is not NULL.
+ *
+ * Effect
+ *
+ * If 'listPtr' is not of type 'tclListType', it is converted if possible.
+ *
+ * The 'refCount' of each element appended to the list is incremented.
+ * Similarly, the 'refCount' for each replaced element is decremented.
+ *
+ * If 'listPtr' is modified, any previous string representation is
+ * invalidated.
*
*----------------------------------------------------------------------
*/
@@ -1098,22 +1081,19 @@ Tcl_ListObjReplace(
*
* TclLindexList --
*
- * This procedure handles the 'lindex' command when objc==3.
+ * Implements the 'lindex' command when objc==3.
+ *
+ * Implemented entirely as a wrapper around 'TclLindexFlat'. Reconfigures
+ * the argument format into required form while taking care to manage
+ * shimmering so as to tend to keep the most useful intreps
+ * and/or avoid the most expensive conversions.
*
- * Results:
- * Returns a pointer to the object extracted, or NULL if an error
- * occurred. The returned object already includes one reference count for
- * the pointer returned.
+ * Value
*
- * Side effects:
- * None.
+ * A pointer to the specified element, with its 'refCount' incremented, or
+ * NULL if an error occurred.
*
- * Notes:
- * This procedure is implemented entirely as a wrapper around
- * TclLindexFlat. All it does is reconfigure the argument format into the
- * form required by TclLindexFlat, while taking care to manage shimmering
- * in such a way that we tend to keep the most useful intreps and/or
- * avoid the most expensive conversions.
+ * Notes
*
*----------------------------------------------------------------------
*/
@@ -1165,17 +1145,11 @@ TclLindexList(
return TclLindexFlat(interp, listPtr, 1, &argPtr);
}
- if (indexListCopy->typePtr == &tclListType) {
- List *listRepPtr = ListRepPtr(indexListCopy);
+ {
+ int indexCount = -1; /* Size of the array of list indices. */
+ Tcl_Obj **indices = NULL; /* Array of list indices. */
- listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount,
- &listRepPtr->elements);
- } else {
- int indexCount = -1; /* Size of the array of list indices. */
- Tcl_Obj **indices = NULL;
- /* Array of list indices. */
-
- Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
+ TclListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
listPtr = TclLindexFlat(interp, listPtr, indexCount, indices);
}
Tcl_DecrRefCount(indexListCopy);
@@ -1185,25 +1159,20 @@ TclLindexList(
/*
*----------------------------------------------------------------------
*
- * TclLindexFlat --
+ * TclLindexFlat --
*
- * This procedure is the core of the 'lindex' command, with all index
- * arguments presented as a flat list.
+ * The core of the 'lindex' command, with all index
+ * arguments presented as a flat list.
*
- * Results:
- * Returns a pointer to the object extracted, or NULL if an error
- * occurred. The returned object already includes one reference count for
- * the pointer returned.
+ * Value
*
- * Side effects:
- * None.
+ * A pointer to the object extracted, with its 'refCount' incremented, or
+ * NULL if an error occurred. Thus, the calling code will usually do
+ * something like:
+ *
+ * Tcl_SetObjResult(interp, result);
+ * Tcl_DecrRefCount(result);
*
- * Notes:
- * The reference count of the returned object includes one reference
- * corresponding to the pointer returned. Thus, the calling code will
- * usually do something like:
- * Tcl_SetObjResult(interp, result);
- * Tcl_DecrRefCount(result);
*
*----------------------------------------------------------------------
*/
@@ -1279,23 +1248,16 @@ TclLindexFlat(
*
* TclLsetList --
*
- * Core of the 'lset' command when objc == 4. Objv[2] may be either a
+ * The core of [lset] when objc == 4. Objv[2] may be either a
* scalar index or a list of indices.
*
- * Results:
- * Returns the new value of the list variable, or NULL if there was an
- * error. The returned object includes one reference count for the
- * pointer returned.
+ * Implemented entirely as a wrapper around 'TclLindexFlat', as described
+ * for 'TclLindexList'.
*
- * Side effects:
- * None.
+ * Value
*
- * Notes:
- * This procedure is implemented entirely as a wrapper around
- * TclLsetFlat. All it does is reconfigure the argument format into the
- * form required by TclLsetFlat, while taking care to manage shimmering
- * in such a way that we tend to keep the most useful intreps and/or
- * avoid the most expensive conversions.
+ * The new list, with the 'refCount' of 'valuPtr' incremented, or NULL if
+ * there was an error.
*
*----------------------------------------------------------------------
*/
@@ -1357,36 +1319,39 @@ TclLsetList(
*
* Core engine of the 'lset' command.
*
- * Results:
- * Returns the new value of the list variable, or NULL if an error
- * occurred. The returned object includes one reference count for the
- * pointer returned.
- *
- * Side effects:
- * On entry, the reference count of the variable value does not reflect
- * any references held on the stack. The first action of this function is
- * to determine whether the object is shared, and to duplicate it if it
- * is. The reference count of the duplicate is incremented. At this
- * point, the reference count will be 1 for either case, so that the
- * object will appear to be unshared.
- *
- * If an error occurs, and the object has been duplicated, the reference
- * count on the duplicate is decremented so that it is now 0: this
- * dismisses any memory that was allocated by this function.
- *
- * If no error occurs, the reference count of the original object is
- * incremented if the object has not been duplicated, and nothing is done
- * to a reference count of the duplicate. Now the reference count of an
- * unduplicated object is 2 (the returned pointer, plus the one stored in
- * the variable). The reference count of a duplicate object is 1,
- * reflecting that the returned pointer is the only active reference. The
- * caller is expected to store the returned value back in the variable
- * and decrement its reference count. (INST_STORE_* does exactly this.)
- *
- * Surgery is performed on the unshared list value to produce the result.
- * TclLsetFlat maintains a linked list of Tcl_Obj's whose string
+ * Value
+ *
+ * The resulting list
+ *
+ * The 'refCount' of 'valuePtr' is incremented. If 'listPtr' was not
+ * duplicated, its 'refCount' is incremented. The reference count of
+ * an unduplicated object is therefore 2 (one for the returned pointer
+ * and one for the variable that holds it). The reference count of a
+ * duplicate object is 1, reflecting that result is the only active
+ * reference. The caller is expected to store the result in the
+ * variable and decrement its reference count. (INST_STORE_* does
+ * exactly this.)
+ *
+ * NULL
+ *
+ * An error occurred. If 'listPtr' was duplicated, the reference
+ * count on the duplicate is decremented so that it is 0, causing any
+ * memory allocated by this function to be freed.
+ *
+ *
+ * Effect
+ *
+ * On entry, the reference count of 'listPtr' does not reflect any
+ * references held on the stack. The first action of this function is to
+ * determine whether 'listPtr' is shared and to create a duplicate
+ * unshared copy if it is. The reference count of the duplicate is
+ * incremented. At this point, the reference count is 1 in either case so
+ * that the object is considered unshared.
+ *
+ * The unshared list is altered directly to produce the result.
+ * 'TclLsetFlat' maintains a linked list of 'Tcl_Obj' values whose string
* representations must be spoilt by threading via 'ptr2' of the
- * two-pointer internal representation. On entry to TclLsetFlat, the
+ * two-pointer internal representation. On entry to 'TclLsetFlat', the
* values of 'ptr2' are immaterial; on exit, the 'ptr2' field of any
* Tcl_Obj that has been modified is set to NULL.
*
@@ -1601,26 +1566,38 @@ TclLsetFlat(
*
* TclListObjSetElement --
*
- * Set a single element of a list to a specified value
+ * Set a single element of a list to a specified value.
*
- * Results:
- * The return value is normally TCL_OK. If listPtr does not refer to a
- * list object and cannot be converted to one, TCL_ERROR is returned and
- * an error message will be left in the interpreter result if interp is
- * not NULL. Similarly, if index designates an element outside the range
- * [0..listLength-1], where listLength is the count of elements in the
- * list object designated by listPtr, TCL_ERROR is returned and an error
- * message is left in the interpreter result.
+ * It is the caller's responsibility to invalidate the string
+ * representation of the 'listPtr'.
*
- * Side effects:
- * Tcl_Panic if listPtr designates a shared object. Otherwise, attempts
- * to convert it to a list with a non-shared internal rep. Decrements the
- * ref count of the object at the specified index within the list,
- * replaces with the object designated by valuePtr, and increments the
- * ref count of the replacement object.
+ * Value
+ *
+ * TCL_OK
+ *
+ * Success.
+ *
+ * TCL_ERROR
+ *
+ * 'listPtr' does not refer to a list object and cannot be converted
+ * to one. An error message will be left in the interpreter result if
+ * interp is not NULL.
+ *
+ * TCL_ERROR
+ *
+ * An index designates an element outside the range [0..listLength-1],
+ * where 'listLength' is the count of elements in the list object
+ * designated by 'listPtr'. An error message is left in the
+ * interpreter result.
+ *
+ * Effect
+ *
+ * If 'listPtr' designates a shared object, 'Tcl_Panic' is called. If
+ * 'listPtr' is not already of type 'tclListType', it is converted and the
+ * internal representation is unshared. The 'refCount' of the element at
+ * 'index' is decremented and replaced in the list with the 'valuePtr',
+ * whose 'refCount' in turn is incremented.
*
- * It is the caller's responsibility to invalidate the string
- * representation of the object.
*
*----------------------------------------------------------------------
*/
@@ -1738,16 +1715,14 @@ TclListObjSetElement(
*
* FreeListInternalRep --
*
- * Deallocate the storage associated with a list object's internal
- * representation.
+ * Deallocate the storage associated with the internal representation of a
+ * a list object.
*
- * Results:
- * None.
+ * Effect
*
- * Side effects:
- * Frees listPtr's List* internal representation and sets listPtr's
- * internalRep.twoPtrValue.ptr1 to NULL. Decrements the ref counts of all
- * element objects, which may free them.
+ * The storage for the internal 'List' pointer of 'listPtr' is freed, the
+ * 'internalRep.twoPtrValue.ptr1' of 'listPtr' is set to NULL, and the 'refCount'
+ * of each element of the list is decremented.
*
*----------------------------------------------------------------------
*/
@@ -1776,14 +1751,12 @@ FreeListInternalRep(
*
* DupListInternalRep --
*
- * Initialize the internal representation of a list Tcl_Obj to share the
+ * Initialize the internal representation of a list 'Tcl_Obj' to share the
* internal representation of an existing list object.
*
- * Results:
- * None.
+ * Effect
*
- * Side effects:
- * The reference count of the List internal rep is incremented.
+ * The 'refCount' of the List internal rep is incremented.
*
*----------------------------------------------------------------------
*/
@@ -1803,16 +1776,20 @@ DupListInternalRep(
*
* SetListFromAny --
*
- * Attempt to generate a list internal form for the Tcl object "objPtr".
+ * Convert any object to a list.
*
- * Results:
- * The return value is TCL_OK or TCL_ERROR. If an error occurs during
- * conversion, an error message is left in the interpreter's result
- * unless "interp" is NULL.
+ * Value
+ *
+ * TCL_OK
+ *
+ * Success. The internal representation of 'objPtr' is set, and the type
+ * of 'objPtr' is 'tclListType'.
+ *
+ * TCL_ERROR
+ *
+ * An error occured during conversion. An error message is left in the
+ * interpreter's result if 'interp' is not NULL.
*
- * Side effects:
- * If no error occurs, a list is stored as "objPtr"s internal
- * representation.
*
*----------------------------------------------------------------------
*/
@@ -1937,18 +1914,16 @@ SetListFromAny(
*
* UpdateStringOfList --
*
- * Update the string representation for a list object. Note: This
- * function does not invalidate an existing old string rep so storage
- * will be lost if this has not already been done.
+ * Update the string representation for a list object.
+ *
+ * Any previously-exising string representation is not invalidated, so
+ * storage is lost if this has not been taken care of.
*
- * Results:
- * None.
+ * Effect
*
- * Side effects:
- * The object's string is set to a valid string that results from the
- * list-to-string conversion. This string will be empty if the list has
- * no elements. The list internal representation should not be NULL and
- * we assume it is not NULL.
+ * The string representation of 'listPtr' is set to the resulting string.
+ * This string will be empty if the list has no elements. It is assumed
+ * that the list internal representation is not NULL.
*
*----------------------------------------------------------------------
*/
@@ -2015,7 +1990,21 @@ UpdateStringOfList(
* Pass 2: copy into string rep buffer.
*/
+ /*
+ * We used to set the string length here, relying on a presumed
+ * guarantee that the number of bytes TclScanElement() calls reported
+ * to be needed was a precise count and not an over-estimate, so long
+ * as the same flag values were passed to TclConvertElement().
+ *
+ * Then we saw [35a8f1c04a], where a bug in TclScanElement() caused
+ * that guarantee to fail. Rather than trust there are no more bugs,
+ * we set the length after the loop based on what was actually written,
+ * an not on what was predicted.
+ *
listPtr->length = bytesNeeded - 1;
+ *
+ */
+
listPtr->bytes = ckalloc(bytesNeeded);
dst = listPtr->bytes;
for (i = 0; i < numElems; i++) {
@@ -2024,7 +2013,10 @@ UpdateStringOfList(
dst += TclConvertElement(elem, length, dst, flagPtr[i]);
*dst++ = ' ';
}
- listPtr->bytes[listPtr->length] = '\0';
+ dst[-1] = '\0';
+
+ /* Here is the safe setting of the string length. */
+ listPtr->length = dst - 1 - listPtr->bytes;
if (flagPtr != localFlags) {
ckfree(flagPtr);
diff --git a/tcl8.6/generic/tclNamesp.c b/tcl8.6/generic/tclNamesp.c
index a8d351f..2297de4 100644
--- a/tcl8.6/generic/tclNamesp.c
+++ b/tcl8.6/generic/tclNamesp.c
@@ -916,6 +916,11 @@ Tcl_DeleteNamespace(
Command *cmdPtr;
/*
+ * Ensure that this namespace doesn't get deallocated in the meantime.
+ */
+ nsPtr->refCount++;
+
+ /*
* Give anyone interested - notably TclOO - a chance to use this namespace
* normally despite the fact that the namespace is going to go. Allows the
* calling of destructors. Will only be called once (unless re-established
@@ -1047,16 +1052,7 @@ Tcl_DeleteNamespace(
#endif
Tcl_DeleteHashTable(&nsPtr->cmdTable);
- /*
- * If the reference count is 0, then discard the namespace.
- * Otherwise, mark it as "dead" so that it can't be used.
- */
-
- if (nsPtr->refCount == 0) {
- NamespaceFree(nsPtr);
- } else {
- nsPtr->flags |= NS_DEAD;
- }
+ nsPtr ->flags |= NS_DEAD;
} else {
/*
* Restore the ::errorInfo and ::errorCode traces.
@@ -1073,6 +1069,7 @@ Tcl_DeleteNamespace(
nsPtr->flags &= ~(NS_DYING|NS_KILLED);
}
}
+ TclNsDecrRefCount(nsPtr);
}
/*
@@ -2425,6 +2422,35 @@ TclGetNamespaceForQualName(
/*
*----------------------------------------------------------------------
*
+ * TclEnsureNamespace --
+ *
+ * Provide a namespace that is not deleted.
+ *
+ * Value
+ *
+ * namespacePtr, if it is not scheduled for deletion, or a pointer to a
+ * new namespace with the same name otherwise.
+ *
+ * Effect
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+Tcl_Namespace *
+TclEnsureNamespace(
+ Tcl_Interp *interp,
+ Tcl_Namespace *namespacePtr)
+{
+ Namespace *nsPtr = (Namespace *) namespacePtr;
+ if (!(nsPtr->flags & NS_DYING)) {
+ return namespacePtr;
+ }
+ return Tcl_CreateNamespace(interp, nsPtr->fullName, NULL, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* Tcl_FindNamespace --
*
* Searches for a namespace.
@@ -2639,7 +2665,7 @@ Tcl_FindCommand(
Namespace *nsPtr[2];
register int search;
- TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
+ TclGetNamespaceForQualName(interp, name, cxtNsPtr,
flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);
/*
diff --git a/tcl8.6/generic/tclOO.c b/tcl8.6/generic/tclOO.c
index f236ac9..39d3806 100644
--- a/tcl8.6/generic/tclOO.c
+++ b/tcl8.6/generic/tclOO.c
@@ -4,6 +4,7 @@
* This file contains the object-system core (NB: not Tcl_Obj, but ::oo)
*
* Copyright (c) 2005-2012 by Donal K. Fellows
+ * Copyright (c) 2017 by Nathan Coulter
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -55,11 +56,8 @@ static const struct {
* Function declarations for things defined in this file.
*/
-static Class * AllocClass(Tcl_Interp *interp, Object *useThisObj);
static Object * AllocObject(Tcl_Interp *interp, const char *nameStr,
- const char *nsNameStr);
-static void ClearMixins(Class *clsPtr);
-static void ClearSuperclasses(Class *clsPtr);
+ Namespace *nsPtr, const char *nsNameStr);
static int CloneClassMethod(Tcl_Interp *interp, Class *clsPtr,
Method *mPtr, Tcl_Obj *namePtr,
Method **newMPtrPtr);
@@ -71,6 +69,7 @@ static void DeletedHelpersNamespace(ClientData clientData);
static Tcl_NRPostProc FinalizeAlloc;
static Tcl_NRPostProc FinalizeNext;
static Tcl_NRPostProc FinalizeObjectCall;
+static void initClassPath(Tcl_Interp * interp, Class *clsPtr);
static int InitFoundation(Tcl_Interp *interp);
static void KillFoundation(ClientData clientData,
Tcl_Interp *interp);
@@ -79,9 +78,7 @@ static void ObjectNamespaceDeleted(ClientData clientData);
static void ObjectRenamedTrace(ClientData clientData,
Tcl_Interp *interp, const char *oldName,
const char *newName, int flags);
-static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr);
static inline void SquelchCachedName(Object *oPtr);
-static void SquelchedNsFirst(ClientData clientData);
static int PublicObjectCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
@@ -95,6 +92,8 @@ static int PrivateObjectCmd(ClientData clientData,
static int PrivateNRObjectCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv);
+static void RemoveClass(Class ** list, int num, int idx);
+static void RemoveObject(Object ** list, int num, int idx);
/*
* Methods in the oo::object and oo::class classes. First, we define a helper
@@ -227,10 +226,16 @@ MODULE_SCOPE const TclOOStubs tclOOStubs;
* ROOT_CLASS respectively.
*/
-#define Deleted(oPtr) (((Object *)(oPtr))->command == NULL)
+#define Deleted(oPtr) ((oPtr)->flags & OBJECT_DELETED)
#define IsRootObject(ocPtr) ((ocPtr)->flags & ROOT_OBJECT)
#define IsRootClass(ocPtr) ((ocPtr)->flags & ROOT_CLASS)
#define IsRoot(ocPtr) ((ocPtr)->flags & (ROOT_OBJECT|ROOT_CLASS))
+
+#define RemoveItem(type, lst, i) \
+ do { \
+ Remove ## type ((lst).list, (lst).num, i); \
+ (lst).num--; \
+ } while (0)
/*
* ----------------------------------------------------------------------
@@ -312,6 +317,10 @@ InitFoundation(
Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData));
Foundation *fPtr = ckalloc(sizeof(Foundation));
Tcl_Obj *namePtr, *argsPtr, *bodyPtr;
+
+ Class fakeCls;
+ Object fakeObject;
+
Tcl_DString buffer;
Command *cmdPtr;
int i;
@@ -378,24 +387,54 @@ InitFoundation(
* spliced manually.
*/
- fPtr->objectCls = AllocClass(interp,
- AllocObject(interp, "::oo::object", NULL));
- fPtr->classCls = AllocClass(interp,
- AllocObject(interp, "::oo::class", NULL));
- fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
- fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
- fPtr->objectCls->flags |= ROOT_OBJECT;
+ /* Stand up a phony class for bootstrapping. */
+ fPtr->objectCls = &fakeCls;
+ /* referenced in TclOOAllocClass to increment the refCount. */
+ fakeCls.thisPtr = &fakeObject;
+
+ fPtr->objectCls = TclOOAllocClass(interp,
+ AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL));
+ /* Corresponding TclOODecrRefCount in KillFoudation */
+ AddRef(fPtr->objectCls->thisPtr);
+
+ /* This is why it is unnecessary in this routine to replace the
+ * incremented reference count of fPtr->objectCls that was swallowed by
+ * fakeObject. */
fPtr->objectCls->superclasses.num = 0;
ckfree(fPtr->objectCls->superclasses.list);
fPtr->objectCls->superclasses.list = NULL;
+
+ /* special initialization for the primordial objects */
+ fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
+ fPtr->objectCls->flags |= ROOT_OBJECT;
+
+ fPtr->classCls = TclOOAllocClass(interp,
+ AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL));
+ /* Corresponding TclOODecrRefCount in KillFoudation */
+ AddRef(fPtr->classCls->thisPtr);
+
+ /*
+ * Increment reference counts for each reference because these
+ * relationships can be dynamically changed.
+ *
+ * Corresponding TclOODecrRefCount for all incremented refcounts is in
+ * KillFoundation.
+ */
+
+ /* Rewire bootstrapped objects. */
+ fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
+ AddRef(fPtr->classCls->thisPtr);
+ TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
+
fPtr->classCls->thisPtr->selfCls = fPtr->classCls;
+ AddRef(fPtr->classCls->thisPtr);
+ TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
+
fPtr->classCls->thisPtr->flags |= ROOT_CLASS;
fPtr->classCls->flags |= ROOT_CLASS;
- TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
- TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
+
+ /* Standard initialization for new Objects */
TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
- AddRef(fPtr->objectCls->thisPtr);
- AddRef(fPtr->objectCls);
/*
* Basic method declarations for the core classes.
@@ -521,13 +560,14 @@ KillFoundation(
{
Foundation *fPtr = GetFoundation(interp);
- DelRef(fPtr->objectCls->thisPtr);
- DelRef(fPtr->objectCls);
TclDecrRefCount(fPtr->unknownMethodNameObj);
TclDecrRefCount(fPtr->constructorName);
TclDecrRefCount(fPtr->destructorName);
TclDecrRefCount(fPtr->clonedName);
TclDecrRefCount(fPtr->defineName);
+ TclOODecrRefCount(fPtr->objectCls->thisPtr);
+ TclOODecrRefCount(fPtr->classCls->thisPtr);
+
ckfree(fPtr);
}
@@ -537,8 +577,11 @@ KillFoundation(
* AllocObject --
*
* Allocate an object of basic type. Does not splice the object into its
- * class's instance list. The caller must set the classPtr on the object,
- * either to a class or to NULL.
+ * class's instance list. The caller must set the classPtr on the object
+ * to either a class or NULL, call TclOOAddToInstances to add the object
+ * to the class's instance list, and if the object itself is a class, use
+ * call TclOOAddToSubclasses() to add it to the right class's list of
+ * subclasses.
*
* ----------------------------------------------------------------------
*/
@@ -551,6 +594,8 @@ AllocObject(
* if the OO system should pick the object
* name itself (equal to the namespace
* name). */
+ Namespace *nsPtr, /* The namespace to create the object in,
+ or NULL if *nameStr is NULL */
const char *nsNameStr) /* The name of the namespace to create, or
* NULL if the OO system should pick a unique
* name itself. If this is non-NULL but names
@@ -561,7 +606,7 @@ AllocObject(
Object *oPtr;
Command *cmdPtr;
CommandTrace *tracePtr;
- int creationEpoch, ignored;
+ int creationEpoch;
oPtr = ckalloc(sizeof(Object));
memset(oPtr, 0, sizeof(Object));
@@ -579,8 +624,7 @@ AllocObject(
*/
if (nsNameStr != NULL) {
- oPtr->namespacePtr = Tcl_CreateNamespace(interp, nsNameStr, oPtr,
- ObjectNamespaceDeleted);
+ oPtr->namespacePtr = Tcl_CreateNamespace(interp, nsNameStr, oPtr, NULL);
if (oPtr->namespacePtr != NULL) {
creationEpoch = ++fPtr->tsdPtr->nsCount;
goto configNamespace;
@@ -592,8 +636,7 @@ AllocObject(
char objName[10 + TCL_INTEGER_SPACE];
sprintf(objName, "::oo::Obj%d", ++fPtr->tsdPtr->nsCount);
- oPtr->namespacePtr = Tcl_CreateNamespace(interp, objName, oPtr,
- ObjectNamespaceDeleted);
+ oPtr->namespacePtr = Tcl_CreateNamespace(interp, objName, oPtr, NULL);
if (oPtr->namespacePtr != NULL) {
creationEpoch = fPtr->tsdPtr->nsCount;
break;
@@ -608,12 +651,16 @@ AllocObject(
Tcl_ResetResult(interp);
}
+
+ configNamespace:
+
+ ((Namespace *)oPtr->namespacePtr)->refCount++;
+
/*
* Make the namespace know about the helper commands. This grants access
* to the [self] and [next] commands.
*/
- configNamespace:
if (fPtr->helpersNs != NULL) {
TclSetNsPath((Namespace *) oPtr->namespacePtr, 1, &fPtr->helpersNs);
}
@@ -633,16 +680,22 @@ AllocObject(
* access variables in it. [Bug 2950259]
*/
- ((Namespace *) oPtr->namespacePtr)->earlyDeleteProc = SquelchedNsFirst;
+ ((Namespace *) oPtr->namespacePtr)->earlyDeleteProc = ObjectNamespaceDeleted;
/*
* Fill in the rest of the non-zero/NULL parts of the structure.
*/
oPtr->fPtr = fPtr;
- oPtr->selfCls = fPtr->objectCls;
oPtr->creationEpoch = creationEpoch;
- oPtr->refCount = 1;
+
+ /*
+ * An object starts life with a refCount of 2 to mark the two stages of
+ * destruction it occur: A call to ObjectRenamedTrace(), and a call to
+ * ObjectNamespaceDeleted().
+ */
+ oPtr->refCount = 2;
+
oPtr->flags = USE_CLASS_CACHE;
/*
@@ -652,23 +705,15 @@ AllocObject(
*/
if (!nameStr) {
- oPtr->command = Tcl_CreateObjCommand(interp,
- oPtr->namespacePtr->fullName, PublicObjectCmd, oPtr, NULL);
- } else if (nameStr[0] == ':' && nameStr[1] == ':') {
- oPtr->command = Tcl_CreateObjCommand(interp, nameStr,
- PublicObjectCmd, oPtr, NULL);
- } else {
- Tcl_DString buffer;
-
- Tcl_DStringInit(&buffer);
- Tcl_DStringAppend(&buffer,
- Tcl_GetCurrentNamespace(interp)->fullName, -1);
- TclDStringAppendLiteral(&buffer, "::");
- Tcl_DStringAppend(&buffer, nameStr, -1);
- oPtr->command = Tcl_CreateObjCommand(interp,
- Tcl_DStringValue(&buffer), PublicObjectCmd, oPtr, NULL);
- Tcl_DStringFree(&buffer);
+ nameStr = oPtr->namespacePtr->name;
+ nsPtr = (Namespace *)oPtr->namespacePtr;
+ if (nsPtr->parentPtr != NULL) {
+ nsPtr = nsPtr->parentPtr;
+ }
+
}
+ oPtr->command = TclCreateObjCommandInNs(interp, nameStr,
+ (Tcl_Namespace *)nsPtr, PublicObjectCmd, oPtr, NULL);
/*
* Add the NRE command and trace directly. While this breaks a number of
@@ -684,26 +729,8 @@ AllocObject(
tracePtr->nextPtr = NULL;
tracePtr->refCount = 1;
- /*
- * Access the namespace command table directly when creating "my" to avoid
- * a bottleneck in string manipulation. Another abstraction-buster.
- */
-
- cmdPtr = ckalloc(sizeof(Command));
- memset(cmdPtr, 0, sizeof(Command));
- cmdPtr->nsPtr = (Namespace *) oPtr->namespacePtr;
- cmdPtr->hPtr = Tcl_CreateHashEntry(&cmdPtr->nsPtr->cmdTable, "my",
- &ignored);
- cmdPtr->refCount = 1;
- cmdPtr->objProc = PrivateObjectCmd;
- cmdPtr->deleteProc = MyDeleted;
- cmdPtr->objClientData = cmdPtr->deleteData = oPtr;
- cmdPtr->proc = TclInvokeObjectCommand;
- cmdPtr->clientData = cmdPtr;
- cmdPtr->nreProc = PrivateNRObjectCmd;
- Tcl_SetHashValue(cmdPtr->hPtr, cmdPtr);
- oPtr->myCommand = (Tcl_Command) cmdPtr;
-
+ oPtr->myCommand = TclNRCreateCommandInNs(interp, "my", oPtr->namespacePtr,
+ PrivateObjectCmd, PrivateNRObjectCmd, oPtr, MyDeleted);
return oPtr;
}
@@ -754,30 +781,6 @@ MyDeleted(
/*
* ----------------------------------------------------------------------
*
- * SquelchedNsFirst --
- *
- * This callback is triggered when the object's namespace is deleted by
- * any mechanism. It deletes the object's public command if it has not
- * already been deleted, so ensuring that destructors get run at an
- * appropriate time. [Bug 2950259]
- *
- * ----------------------------------------------------------------------
- */
-
-static void
-SquelchedNsFirst(
- ClientData clientData)
-{
- Object *oPtr = clientData;
-
- if (oPtr->command) {
- Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
- }
-}
-
-/*
- * ----------------------------------------------------------------------
- *
* ObjectRenamedTrace --
*
* This callback is triggered when the object is deleted by any
@@ -797,8 +800,6 @@ ObjectRenamedTrace(
int flags) /* Why was the object deleted? */
{
Object *oPtr = clientData;
- Foundation *fPtr = oPtr->fPtr;
-
/*
* If this is a rename and not a delete of the object, we just flush the
* cache of the object name.
@@ -810,142 +811,106 @@ ObjectRenamedTrace(
}
/*
- * Oh dear, the object really is being deleted. Handle this by running the
- * destructors and deleting the object's namespace, which in turn causes
- * the real object structures to be deleted.
- *
- * Note that it is possible for the namespace to be deleted before the
- * command. Because of that case, we must take care here to mark the
- * command as being deleted so that if we return here we don't run into
- * reentrancy problems.
- *
- * We also do not run destructors on the core class objects when the
- * interpreter is being deleted; their incestuous nature causes problems
- * in that case when the destructor is partially deleted before the uses
- * of it have gone. [Bug 2949397]
- */
-
- AddRef(oPtr);
- AddRef(fPtr->classCls);
- AddRef(fPtr->objectCls);
- AddRef(fPtr->classCls->thisPtr);
- AddRef(fPtr->objectCls->thisPtr);
- oPtr->command = NULL;
-
- if (!(oPtr->flags & DESTRUCTOR_CALLED) && !Tcl_InterpDeleted(interp)) {
- CallContext *contextPtr =
- TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, NULL);
- int result;
- Tcl_InterpState state;
-
- oPtr->flags |= DESTRUCTOR_CALLED;
- if (contextPtr != NULL) {
- contextPtr->callPtr->flags |= DESTRUCTOR;
- contextPtr->skip = 0;
- state = Tcl_SaveInterpState(interp, TCL_OK);
- result = Tcl_NRCallObjProc(interp, TclOOInvokeContext,
- contextPtr, 0, NULL);
- if (result != TCL_OK) {
- Tcl_BackgroundException(interp, result);
- }
- Tcl_RestoreInterpState(interp, state);
- TclOODeleteContext(contextPtr);
- }
- }
-
- /*
- * OK, the destructor's been run. Time to splat the class data (if any)
- * and nuke the namespace (which triggers the final crushing of the object
- * structure itself).
- *
- * The class of objects needs some special care; if it is deleted (and
- * we're not killing the whole interpreter) we force the delete of the
- * class of classes now as well. Due to the incestuous nature of those two
- * classes, if one goes the other must too and yet the tangle can
- * sometimes not go away automatically; we force it here. [Bug 2962664]
- */
-
- if (!Tcl_InterpDeleted(interp) && IsRootObject(oPtr)
- && !Deleted(fPtr->classCls->thisPtr)) {
- Tcl_DeleteCommandFromToken(interp, fPtr->classCls->thisPtr->command);
- }
-
- if (oPtr->classPtr != NULL) {
- AddRef(oPtr->classPtr);
- ReleaseClassContents(interp, oPtr);
- }
-
- /*
* The namespace is only deleted if it hasn't already been deleted. [Bug
- * 2950259]
+ * 2950259].
*/
- if (((Namespace *) oPtr->namespacePtr)->earlyDeleteProc != NULL) {
+ if (!Deleted(oPtr)) {
Tcl_DeleteNamespace(oPtr->namespacePtr);
}
- if (oPtr->classPtr) {
- DelRef(oPtr->classPtr);
- }
- DelRef(fPtr->classCls->thisPtr);
- DelRef(fPtr->objectCls->thisPtr);
- DelRef(fPtr->classCls);
- DelRef(fPtr->objectCls);
- DelRef(oPtr);
+ oPtr->command = NULL;
+ TclOODecrRefCount(oPtr);
+ return;
}
/*
* ----------------------------------------------------------------------
*
- * ClearMixins, ClearSuperclasses --
+ * TclOODeleteDescendants --
*
- * Utility functions for correctly clearing the list of mixins or
- * superclasses of a class. Will ckfree() the list storage.
+ * Delete all descendants of a particular class.
*
* ----------------------------------------------------------------------
*/
-static void
-ClearMixins(
- Class *clsPtr)
+void
+TclOODeleteDescendants(
+ Tcl_Interp *interp, /* The interpreter containing the class. */
+ Object *oPtr) /* The object representing the class. */
{
- int i;
- Class *mixinPtr;
+ Class *clsPtr = oPtr->classPtr, *subclassPtr, *mixinSubclassPtr;
+ Object *instancePtr;
- if (clsPtr->mixins.num == 0) {
- return;
+ /*
+ * Squelch classes that this class has been mixed into.
+ */
+
+ if (clsPtr->mixinSubs.num > 0) {
+ while (clsPtr->mixinSubs.num > 0) {
+ mixinSubclassPtr = clsPtr->mixinSubs.list[clsPtr->mixinSubs.num-1];
+ /* This condition also covers the case where mixinSubclassPtr ==
+ * clsPtr
+ */
+ if (!Deleted(mixinSubclassPtr->thisPtr)
+ && !(mixinSubclassPtr->thisPtr->flags & DONT_DELETE)) {
+ Tcl_DeleteCommandFromToken(interp,
+ mixinSubclassPtr->thisPtr->command);
+ }
+ TclOORemoveFromMixinSubs(mixinSubclassPtr, clsPtr);
+ }
+ }
+ if (clsPtr->mixinSubs.size > 0) {
+ ckfree(clsPtr->mixinSubs.list);
+ clsPtr->mixinSubs.size = 0;
}
+ /*
+ * Squelch subclasses of this class.
+ */
- FOREACH(mixinPtr, clsPtr->mixins) {
- TclOORemoveFromMixinSubs(clsPtr, mixinPtr);
+ if (clsPtr->subclasses.num > 0) {
+ while (clsPtr->subclasses.num > 0) {
+ subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num-1];
+ if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)
+ && !(subclassPtr->thisPtr->flags & DONT_DELETE)) {
+ Tcl_DeleteCommandFromToken(interp,
+ subclassPtr->thisPtr->command);
+ }
+ TclOORemoveFromSubclasses(subclassPtr, clsPtr);
+ }
+ }
+ if (clsPtr->subclasses.size > 0) {
+ ckfree(clsPtr->subclasses.list);
+ clsPtr->subclasses.list = NULL;
+ clsPtr->subclasses.size = 0;
}
- ckfree(clsPtr->mixins.list);
- clsPtr->mixins.list = NULL;
- clsPtr->mixins.num = 0;
-}
-static void
-ClearSuperclasses(
- Class *clsPtr)
-{
- int i;
- Class *superPtr;
+ /*
+ * Squelch instances of this class (includes objects we're mixed into).
+ */
- if (clsPtr->superclasses.num == 0) {
- return;
+ if (clsPtr->instances.num > 0) {
+ while (clsPtr->instances.num > 0) {
+ instancePtr = clsPtr->instances.list[clsPtr->instances.num-1];
+ /* This condition also covers the case where instancePtr == oPtr */
+ if (!Deleted(instancePtr) && !IsRoot(instancePtr) &&
+ !(instancePtr->flags & DONT_DELETE)) {
+ Tcl_DeleteCommandFromToken(interp, instancePtr->command);
+ }
+ TclOORemoveFromInstances(instancePtr, clsPtr);
+ }
}
-
- FOREACH(superPtr, clsPtr->superclasses) {
- TclOORemoveFromSubclasses(clsPtr, superPtr);
+ if (clsPtr->instances.size > 0) {
+ ckfree(clsPtr->instances.list);
+ clsPtr->instances.list = NULL;
+ clsPtr->instances.size = 0;
}
- ckfree(clsPtr->superclasses.list);
- clsPtr->superclasses.list = NULL;
- clsPtr->superclasses.num = 0;
}
+
/*
* ----------------------------------------------------------------------
*
- * ReleaseClassContents --
+ * TclOOReleaseClassContents --
*
* Tear down the special class data structure, including deleting all
* dependent classes and objects.
@@ -953,16 +918,17 @@ ClearSuperclasses(
* ----------------------------------------------------------------------
*/
-static void
-ReleaseClassContents(
+void
+TclOOReleaseClassContents(
Tcl_Interp *interp, /* The interpreter containing the class. */
Object *oPtr) /* The object representing the class. */
{
FOREACH_HASH_DECLS;
- int i;
- Class *clsPtr = oPtr->classPtr, *mixinSubclassPtr, *subclassPtr;
- Object *instancePtr;
+ int i;
+ Class *clsPtr = oPtr->classPtr, *tmpClsPtr;
+ Method *mPtr;
Foundation *fPtr = oPtr->fPtr;
+ Tcl_Obj *variableObj;
/*
* Sanity check!
@@ -975,121 +941,8 @@ ReleaseClassContents(
} else if (IsRootObject(oPtr)) {
Tcl_Panic("deleting class structure for non-deleted %s",
"::oo::object");
- } else {
- Tcl_Panic("deleting class structure for non-deleted %s",
- "general object");
- }
- }
-
- /*
- * Lock a number of dependent objects until we've stopped putting our
- * fingers in them.
- */
-
- FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) {
- if (mixinSubclassPtr != NULL) {
- AddRef(mixinSubclassPtr);
- AddRef(mixinSubclassPtr->thisPtr);
- }
- }
- FOREACH(subclassPtr, clsPtr->subclasses) {
- if (subclassPtr != NULL && !IsRoot(subclassPtr)) {
- AddRef(subclassPtr);
- AddRef(subclassPtr->thisPtr);
- }
- }
- if (!IsRootClass(oPtr)) {
- FOREACH(instancePtr, clsPtr->instances) {
- int j;
- if (instancePtr->selfCls == clsPtr) {
- instancePtr->flags |= CLASS_GONE;
- }
- for(j=0 ; j<instancePtr->mixins.num ; j++) {
- Class *mixin = instancePtr->mixins.list[j];
- if (mixin == clsPtr) {
- instancePtr->mixins.list[j] = NULL;
- }
- }
- if (instancePtr != NULL && !IsRoot(instancePtr)) {
- AddRef(instancePtr);
- }
- }
- }
-
- /*
- * Squelch classes that this class has been mixed into.
- */
-
- FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) {
- if (!Deleted(mixinSubclassPtr->thisPtr)) {
- Tcl_DeleteCommandFromToken(interp,
- mixinSubclassPtr->thisPtr->command);
- }
- ClearMixins(mixinSubclassPtr);
- DelRef(mixinSubclassPtr->thisPtr);
- DelRef(mixinSubclassPtr);
- }
- if (clsPtr->mixinSubs.list != NULL) {
- ckfree(clsPtr->mixinSubs.list);
- clsPtr->mixinSubs.list = NULL;
- clsPtr->mixinSubs.num = 0;
- }
-
- /*
- * Squelch subclasses of this class.
- */
-
- FOREACH(subclassPtr, clsPtr->subclasses) {
- if (IsRoot(subclassPtr)) {
- continue;
- }
- if (!Deleted(subclassPtr->thisPtr)) {
- Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command);
- }
- ClearSuperclasses(subclassPtr);
- DelRef(subclassPtr->thisPtr);
- DelRef(subclassPtr);
- }
- if (clsPtr->subclasses.list != NULL) {
- ckfree(clsPtr->subclasses.list);
- clsPtr->subclasses.list = NULL;
- clsPtr->subclasses.num = 0;
- }
-
- /*
- * Squelch instances of this class (includes objects we're mixed into).
- */
-
- if (!IsRootClass(oPtr)) {
- FOREACH(instancePtr, clsPtr->instances) {
- if (instancePtr == NULL || IsRoot(instancePtr)) {
- continue;
- }
- if (!Deleted(instancePtr)) {
- Tcl_DeleteCommandFromToken(interp, instancePtr->command);
- /*
- * Tcl_DeleteCommandFromToken() may have done to whole
- * job for us. Roll back and check again.
- */
- i--;
- continue;
- }
- DelRef(instancePtr);
}
}
- if (clsPtr->instances.list != NULL) {
- ckfree(clsPtr->instances.list);
- clsPtr->instances.list = NULL;
- clsPtr->instances.num = 0;
- }
-
- /*
- * Special: We delete these after everything else.
- */
-
- if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) {
- Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command);
- }
/*
* Squelch method implementation chain caches.
@@ -1125,6 +978,7 @@ ReleaseClassContents(
TclDecrRefCount(filterObj);
}
ckfree(clsPtr->filters.list);
+ clsPtr->filters.list = NULL;
clsPtr->filters.num = 0;
}
@@ -1143,6 +997,44 @@ ReleaseClassContents(
ckfree(clsPtr->metadataPtr);
clsPtr->metadataPtr = NULL;
}
+
+ if (clsPtr->mixins.num) {
+ FOREACH(tmpClsPtr, clsPtr->mixins) {
+ TclOORemoveFromMixinSubs(clsPtr, tmpClsPtr);
+ TclOODecrRefCount(tmpClsPtr->thisPtr);
+ }
+ ckfree(clsPtr->mixins.list);
+ clsPtr->mixins.list = NULL;
+ clsPtr->mixins.num = 0;
+ }
+
+ if (clsPtr->superclasses.num > 0) {
+ FOREACH(tmpClsPtr, clsPtr->superclasses) {
+ TclOORemoveFromSubclasses(clsPtr, tmpClsPtr);
+ TclOODecrRefCount(tmpClsPtr->thisPtr);
+ }
+ ckfree(clsPtr->superclasses.list);
+ clsPtr->superclasses.num = 0;
+ clsPtr->superclasses.list = NULL;
+ }
+
+ FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) {
+ TclOODelMethodRef(mPtr);
+ }
+ Tcl_DeleteHashTable(&clsPtr->classMethods);
+ TclOODelMethodRef(clsPtr->constructorPtr);
+ TclOODelMethodRef(clsPtr->destructorPtr);
+
+ FOREACH(variableObj, clsPtr->variables) {
+ TclDecrRefCount(variableObj);
+ }
+ if (i) {
+ ckfree(clsPtr->variables.list);
+ }
+
+ if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) {
+ Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command);
+ }
}
/*
@@ -1164,22 +1056,81 @@ ObjectNamespaceDeleted(
* being deleted. */
{
Object *oPtr = clientData;
+ Foundation *fPtr = oPtr->fPtr;
FOREACH_HASH_DECLS;
- Class *clsPtr = oPtr->classPtr, *mixinPtr;
+ Class *mixinPtr;
Method *mPtr;
Tcl_Obj *filterObj, *variableObj;
+ Tcl_Interp *interp = oPtr->fPtr->interp;
int i;
+ if (Deleted(oPtr)) {
+ /* To do: Can ObjectNamespaceDeleted ever be called twice? If not,
+ * this guard could be removed.
+ */
+ return;
+ }
+
+ /*
+ * One rule for the teardown routines is that if an object is in the
+ * process of being deleted, nothing else may modify its bookeeping
+ * records. This is the flag that
+ */
+ oPtr->flags |= OBJECT_DELETED;
+
+ /* Let the dominoes fall */
+ if (oPtr->classPtr) {
+ TclOODeleteDescendants(interp, oPtr);
+ }
+
+ /*
+ * We do not run destructors on the core class objects when the
+ * interpreter is being deleted; their incestuous nature causes problems
+ * in that case when the destructor is partially deleted before the uses
+ * of it have gone. [Bug 2949397]
+ */
+ if (!Tcl_InterpDeleted(interp) && !(oPtr->flags & DESTRUCTOR_CALLED)) {
+ CallContext *contextPtr =
+ TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, NULL);
+ int result;
+
+ Tcl_InterpState state;
+ oPtr->flags |= DESTRUCTOR_CALLED;
+
+ if (contextPtr != NULL) {
+ contextPtr->callPtr->flags |= DESTRUCTOR;
+ contextPtr->skip = 0;
+ state = Tcl_SaveInterpState(interp, TCL_OK);
+ result = Tcl_NRCallObjProc(interp, TclOOInvokeContext,
+ contextPtr, 0, NULL);
+ if (result != TCL_OK) {
+ Tcl_BackgroundException(interp, result);
+ }
+ Tcl_RestoreInterpState(interp, state);
+ TclOODeleteContext(contextPtr);
+ }
+ }
+
/*
* Instruct everyone to no longer use any allocated fields of the object.
- * Also delete the commands that refer to the object at this point (if
- * they still exist) because otherwise their references to the object
- * point into freed memory, allowing crashes.
+ * Also delete the command that refers to the object at this point (if
+ * it still exists) because otherwise its pointer to the object
+ * points into freed memory.
*/
- if (oPtr->command) {
+ if (((Command *)oPtr->command)->flags && CMD_IS_DELETED) {
+ /*
+ * Something has already started the command deletion process. We can
+ * go ahead and clean up the the namespace,
+ */
+ } else {
+ /*
+ * The namespace must have been deleted directly. Delete the command
+ * as well.
+ */
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
}
+
if (oPtr->myCommand) {
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand);
}
@@ -1189,17 +1140,17 @@ ObjectNamespaceDeleted(
* methods on the object.
*/
- if (!IsRootObject(oPtr) && !(oPtr->flags & CLASS_GONE)) {
- TclOORemoveFromInstances(oPtr, oPtr->selfCls);
- }
+ /* To do: Should this be protected with a * !IsRoot() condition? */
+ TclOORemoveFromInstances(oPtr, oPtr->selfCls);
- FOREACH(mixinPtr, oPtr->mixins) {
- if (mixinPtr) {
+ if (oPtr->mixins.num > 0) {
+ FOREACH(mixinPtr, oPtr->mixins) {
TclOORemoveFromInstances(oPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
+ }
+ if (oPtr->mixins.list != NULL) {
+ ckfree(oPtr->mixins.list);
}
- }
- if (i) {
- ckfree(oPtr->mixins.list);
}
FOREACH(filterObj, oPtr->filters) {
@@ -1243,71 +1194,73 @@ ObjectNamespaceDeleted(
}
/*
- * If this was a class, there's additional deletion work to do.
+ * Because an object can be a class that is an instance of itself, the
+ * class object's class structure should only be cleaned after most of
+ * the cleanup on the object is done.
+ *
+ * The class of objects needs some special care; if it is deleted (and
+ * we're not killing the whole interpreter) we force the delete of the
+ * class of classes now as well. Due to the incestuous nature of those two
+ * classes, if one goes the other must too and yet the tangle can
+ * sometimes not go away automatically; we force it here. [Bug 2962664]
*/
- if (clsPtr != NULL) {
- Tcl_ObjectMetadataType *metadataTypePtr;
- ClientData value;
-
- if (clsPtr->metadataPtr != NULL) {
- FOREACH_HASH(metadataTypePtr, value, clsPtr->metadataPtr) {
- metadataTypePtr->deleteProc(value);
- }
- Tcl_DeleteHashTable(clsPtr->metadataPtr);
- ckfree(clsPtr->metadataPtr);
- clsPtr->metadataPtr = NULL;
- }
+ if (IsRootObject(oPtr) && !Deleted(fPtr->classCls->thisPtr)
+ && !Tcl_InterpDeleted(interp)) {
- FOREACH(filterObj, clsPtr->filters) {
- TclDecrRefCount(filterObj);
- }
- if (i) {
- ckfree(clsPtr->filters.list);
- clsPtr->filters.num = 0;
- }
-
- ClearMixins(clsPtr);
-
- ClearSuperclasses(clsPtr);
-
- if (clsPtr->subclasses.list) {
- ckfree(clsPtr->subclasses.list);
- clsPtr->subclasses.num = 0;
- }
- if (clsPtr->instances.list) {
- ckfree(clsPtr->instances.list);
- clsPtr->instances.num = 0;
- }
- if (clsPtr->mixinSubs.list) {
- ckfree(clsPtr->mixinSubs.list);
- clsPtr->mixinSubs.num = 0;
- }
-
- FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) {
- TclOODelMethodRef(mPtr);
- }
- Tcl_DeleteHashTable(&clsPtr->classMethods);
- TclOODelMethodRef(clsPtr->constructorPtr);
- TclOODelMethodRef(clsPtr->destructorPtr);
-
- FOREACH(variableObj, clsPtr->variables) {
- TclDecrRefCount(variableObj);
- }
- if (i) {
- ckfree(clsPtr->variables.list);
- }
+ Tcl_DeleteCommandFromToken(interp, fPtr->classCls->thisPtr->command);
+ }
- DelRef(clsPtr);
+ if (oPtr->classPtr != NULL) {
+ TclOOReleaseClassContents(interp, oPtr);
}
/*
* Delete the object structure itself.
*/
- DelRef(oPtr);
+ TclNsDecrRefCount((Namespace *)oPtr->namespacePtr);
+ oPtr->namespacePtr = NULL;
+ TclOODecrRefCount(oPtr->selfCls->thisPtr);
+ oPtr->selfCls = NULL;
+ TclOODecrRefCount(oPtr);
+ return;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODecrRef --
+ *
+ * Decrement the refcount of an object and deallocate storage then object
+ * is no longer referenced. Returns 1 if storage was deallocated, and 0
+ * otherwise.
+ *
+ * ----------------------------------------------------------------------
+ */
+int TclOODecrRefCount(Object *oPtr) {
+ if (oPtr->refCount-- <= 1) {
+ if (oPtr->classPtr != NULL) {
+ ckfree(oPtr->classPtr);
+ }
+ ckfree(oPtr);
+ return 1;
+ }
+ return 0;
}
+/* setting the "empty" location to NULL makes debugging a little easier */
+#define REMOVEBODY { \
+ for (; idx < num - 1; idx++) { \
+ list[idx] = list[idx+1]; \
+ } \
+ list[idx] = NULL; \
+ return; \
+}
+void RemoveClass(Class **list, int num, int idx) REMOVEBODY
+
+void RemoveObject(Object **list, int num, int idx) REMOVEBODY
+
/*
* ----------------------------------------------------------------------
*
@@ -1319,36 +1272,24 @@ ObjectNamespaceDeleted(
* ----------------------------------------------------------------------
*/
-void
+int
TclOORemoveFromInstances(
Object *oPtr, /* The instance to remove. */
Class *clsPtr) /* The class (possibly) containing the
* reference to the instance. */
{
- int i;
+ int i, res = 0;
Object *instPtr;
FOREACH(instPtr, clsPtr->instances) {
if (oPtr == instPtr) {
- goto removeInstance;
- }
- }
- return;
-
- removeInstance:
- if (Deleted(clsPtr->thisPtr)) {
- if (!IsRootClass(clsPtr)) {
- DelRef(clsPtr->instances.list[i]);
- }
- clsPtr->instances.list[i] = NULL;
- } else {
- clsPtr->instances.num--;
- if (i < clsPtr->instances.num) {
- clsPtr->instances.list[i] =
- clsPtr->instances.list[clsPtr->instances.num];
+ RemoveItem(Object, clsPtr->instances, i);
+ TclOODecrRefCount(oPtr);
+ res++;
+ break;
}
- clsPtr->instances.list[clsPtr->instances.num] = NULL;
}
+ return res;
}
/*
@@ -1369,9 +1310,6 @@ TclOOAddToInstances(
* assumed that the class is not already
* present as an instance in the class. */
{
- if (Deleted(clsPtr->thisPtr)) {
- return;
- }
if (clsPtr->instances.num >= clsPtr->instances.size) {
clsPtr->instances.size += ALLOC_CHUNK;
if (clsPtr->instances.size == ALLOC_CHUNK) {
@@ -1382,6 +1320,42 @@ TclOOAddToInstances(
}
}
clsPtr->instances.list[clsPtr->instances.num++] = oPtr;
+ AddRef(oPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOORemoveFromMixins --
+ *
+ * Utility function to remove a class from the list of mixins within an
+ * object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOORemoveFromMixins(
+ Class *mixinPtr, /* The mixin to remove. */
+ Object *oPtr) /* The object (possibly) containing the
+ * reference to the mixin. */
+{
+ int i, res = 0;
+ Class *mixPtr;
+
+ FOREACH(mixPtr, oPtr->mixins) {
+ if (mixinPtr == mixPtr) {
+ RemoveItem(Class, oPtr->mixins, i);
+ TclOODecrRefCount(mixPtr->thisPtr);
+ res++;
+ break;
+ }
+ }
+ if (oPtr->mixins.num == 0) {
+ ckfree(oPtr->mixins.list);
+ oPtr->mixins.list = NULL;
+ }
+ return res;
}
/*
@@ -1390,36 +1364,28 @@ TclOOAddToInstances(
* TclOORemoveFromSubclasses --
*
* Utility function to remove a class from the list of subclasses within
- * another class.
+ * another class. Returns the number of removals performed.
*
* ----------------------------------------------------------------------
*/
-void
+int
TclOORemoveFromSubclasses(
Class *subPtr, /* The subclass to remove. */
- Class *superPtr) /* The superclass to (possibly) remove the
+ Class *superPtr) /* The superclass to possibly remove the
* subclass reference from. */
{
- int i;
+ int i, res = 0;
Class *subclsPtr;
FOREACH(subclsPtr, superPtr->subclasses) {
if (subPtr == subclsPtr) {
- goto removeSubclass;
+ RemoveItem(Class, superPtr->subclasses, i);
+ TclOODecrRefCount(subPtr->thisPtr);
+ res++;
}
}
- return;
-
- removeSubclass:
- if (!Deleted(superPtr->thisPtr)) {
- superPtr->subclasses.num--;
- if (i < superPtr->subclasses.num) {
- superPtr->subclasses.list[i] =
- superPtr->subclasses.list[superPtr->subclasses.num];
- }
- superPtr->subclasses.list[superPtr->subclasses.num] = NULL;
- }
+ return res;
}
/*
@@ -1446,13 +1412,14 @@ TclOOAddToSubclasses(
if (superPtr->subclasses.num >= superPtr->subclasses.size) {
superPtr->subclasses.size += ALLOC_CHUNK;
if (superPtr->subclasses.size == ALLOC_CHUNK) {
- superPtr->subclasses.list = ckalloc(sizeof(Class*) * ALLOC_CHUNK);
+ superPtr->subclasses.list = ckalloc(sizeof(Class *) * ALLOC_CHUNK);
} else {
superPtr->subclasses.list = ckrealloc(superPtr->subclasses.list,
sizeof(Class *) * superPtr->subclasses.size);
}
}
superPtr->subclasses.list[superPtr->subclasses.num++] = subPtr;
+ AddRef(subPtr->thisPtr);
}
/*
@@ -1466,31 +1433,24 @@ TclOOAddToSubclasses(
* ----------------------------------------------------------------------
*/
-void
+int
TclOORemoveFromMixinSubs(
Class *subPtr, /* The subclass to remove. */
- Class *superPtr) /* The superclass to (possibly) remove the
+ Class *superPtr) /* The superclass to possibly remove the
* subclass reference from. */
{
- int i;
+ int i, res = 0;
Class *subclsPtr;
FOREACH(subclsPtr, superPtr->mixinSubs) {
if (subPtr == subclsPtr) {
- goto removeSubclass;
- }
- }
- return;
-
- removeSubclass:
- if (!Deleted(superPtr->thisPtr)) {
- superPtr->mixinSubs.num--;
- if (i < superPtr->mixinSubs.num) {
- superPtr->mixinSubs.list[i] =
- superPtr->mixinSubs.list[superPtr->mixinSubs.num];
+ RemoveItem(Class, superPtr->mixinSubs, i);
+ TclOODecrRefCount(subPtr->thisPtr);
+ res++;
+ break;
}
- superPtr->mixinSubs.list[superPtr->mixinSubs.num] = NULL;
}
+ return res;
}
/*
@@ -1524,62 +1484,37 @@ TclOOAddToMixinSubs(
}
}
superPtr->mixinSubs.list[superPtr->mixinSubs.num++] = subPtr;
+ AddRef(subPtr->thisPtr);
}
/*
* ----------------------------------------------------------------------
*
- * AllocClass --
+ * TclOOAllocClass --
*
- * Allocate a basic class. Does not splice the class object into its
- * class's instance list.
+ * Allocate a basic class. Does not add class to its class's instance
+ * list.
*
* ----------------------------------------------------------------------
*/
-static Class *
-AllocClass(
+Class *
+TclOOAllocClass(
Tcl_Interp *interp, /* Interpreter within which to allocate the
* class. */
Object *useThisObj) /* Object that is to act as the class
- * representation, or NULL if a new object
- * (with automatic name) is to be used. */
+ * representation. */
{
Foundation *fPtr = GetFoundation(interp);
Class *clsPtr = ckalloc(sizeof(Class));
- /*
- * Make an object if we haven't been given one.
- */
-
memset(clsPtr, 0, sizeof(Class));
- if (useThisObj == NULL) {
- clsPtr->thisPtr = AllocObject(interp, NULL, NULL);
- } else {
- clsPtr->thisPtr = useThisObj;
- }
+ clsPtr->thisPtr = useThisObj;
/*
* Configure the namespace path for the class's object.
*/
-
- if (fPtr->helpersNs != NULL) {
- Tcl_Namespace *path[2];
-
- path[0] = fPtr->helpersNs;
- path[1] = fPtr->ooNs;
- TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 2, path);
- } else {
- TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 1,
- &fPtr->ooNs);
- }
-
- /*
- * Class objects inherit from the class of classes unless they inherit
- * from some subclass of it. Enforce this right now.
- */
-
- clsPtr->thisPtr->selfCls = fPtr->classCls;
+ initClassPath(interp, clsPtr);
/*
* Classes are subclasses of oo::object, i.e. the objects they create are
@@ -1589,6 +1524,7 @@ AllocClass(
clsPtr->superclasses.num = 1;
clsPtr->superclasses.list = ckalloc(sizeof(Class *));
clsPtr->superclasses.list[0] = fPtr->objectCls;
+ AddRef(fPtr->objectCls->thisPtr);
/*
* Finish connecting the class structure to the object structure.
@@ -1601,10 +1537,22 @@ AllocClass(
* fields.
*/
- clsPtr->refCount = 1;
Tcl_InitObjHashTable(&clsPtr->classMethods);
return clsPtr;
}
+static void
+initClassPath(Tcl_Interp *interp, Class *clsPtr) {
+ Foundation *fPtr = GetFoundation(interp);
+ if (fPtr->helpersNs != NULL) {
+ Tcl_Namespace *path[2];
+ path[0] = fPtr->helpersNs;
+ path[1] = fPtr->ooNs;
+ TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 2, path);
+ } else {
+ TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 1,
+ &fPtr->ooNs);
+ }
+}
/*
* ----------------------------------------------------------------------
@@ -1615,7 +1563,6 @@ AllocClass(
*
* ----------------------------------------------------------------------
*/
-
Tcl_Object
Tcl_NewObjectInstance(
Tcl_Interp *interp, /* Interpreter context. */
@@ -1632,54 +1579,15 @@ Tcl_NewObjectInstance(
* constructor. */
{
register Class *classPtr = (Class *) cls;
- Foundation *fPtr = GetFoundation(interp);
Object *oPtr;
+ ClientData clientData[4];
- /*
- * Check if we're going to create an object over an existing command;
- * that's not allowed.
- */
-
- if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
- TCL_NAMESPACE_ONLY)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't create object \"%s\": command already exists with"
- " that name", nameStr));
- Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL);
- return NULL;
- }
+ oPtr = TclNewObjectInstanceCommon(interp, classPtr, nameStr, nsNameStr);
+ if (oPtr == NULL) {return NULL;}
/*
- * Create the object.
- */
-
- oPtr = AllocObject(interp, nameStr, nsNameStr);
- oPtr->selfCls = classPtr;
- TclOOAddToInstances(oPtr, classPtr);
-
- /*
- * Check to see if we're really creating a class. If so, allocate the
- * class structure as well.
- */
-
- if (TclOOIsReachable(fPtr->classCls, classPtr)) {
- /*
- * Is a class, so attach a class structure. Note that the AllocClass
- * function splices the structure into the object, so we don't have
- * to. Once that's done, we need to repatch the object to have the
- * right class since AllocClass interferes with that.
- */
-
- AllocClass(interp, oPtr);
- oPtr->selfCls = classPtr;
- TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
- } else {
- oPtr->classPtr = NULL;
- }
-
- /*
- * Run constructors, except when objc < 0 (a special flag case used for
- * object cloning only).
+ * Run constructors, except when objc < 0, which is a special flag case
+ * used for object cloning only.
*/
if (objc >= 0) {
@@ -1695,7 +1603,7 @@ Tcl_NewObjectInstance(
contextPtr->skip = skip;
/*
- * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+ * Adjust the ensemble tracking record if necessary. [Bug 3514761]
*/
isRoot = TclInitRewriteEnsemble(interp, skip, skip, objv);
@@ -1706,36 +1614,15 @@ Tcl_NewObjectInstance(
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
- * errors by accident...) [Bug 2903011]
- */
+ clientData[0] = contextPtr;
+ clientData[1] = oPtr;
+ clientData[2] = state;
+ clientData[3] = &oPtr;
- if (result != TCL_ERROR && Deleted(oPtr)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "object deleted in constructor", -1));
- Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL);
- result = TCL_ERROR;
- }
- TclOODeleteContext(contextPtr);
+ result = FinalizeAlloc(clientData, interp, result);
if (result != TCL_OK) {
- Tcl_DiscardInterpState(state);
-
- /*
- * Take care to not delete a deleted object; that would be
- * bad. [Bug 2903011] Also take care to make sure that we have
- * the name of the command before we delete it. [Bug
- * 9dd1bd7a74]
- */
-
- if (!Deleted(oPtr)) {
- (void) TclOOObjectName(interp, oPtr);
- Tcl_DeleteCommandFromToken(interp, oPtr->command);
- }
return NULL;
}
- Tcl_RestoreInterpState(interp, state);
}
}
@@ -1760,50 +1647,12 @@ TclNRNewObjectInstance(
* successful allocation. */
{
register Class *classPtr = (Class *) cls;
- Foundation *fPtr = GetFoundation(interp);
CallContext *contextPtr;
Tcl_InterpState state;
Object *oPtr;
- /*
- * Check if we're going to create an object over an existing command;
- * that's not allowed.
- */
-
- if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
- TCL_NAMESPACE_ONLY)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't create object \"%s\": command already exists with"
- " that name", nameStr));
- Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL);
- return TCL_ERROR;
- }
-
- /*
- * Create the object.
- */
-
- oPtr = AllocObject(interp, nameStr, nsNameStr);
- oPtr->selfCls = classPtr;
- TclOOAddToInstances(oPtr, classPtr);
-
- /*
- * Check to see if we're really creating a class. If so, allocate the
- * class structure as well.
- */
-
- if (TclOOIsReachable(fPtr->classCls, classPtr)) {
- /*
- * Is a class, so attach a class structure. Note that the AllocClass
- * function splices the structure into the object, so we don't have
- * to. Once that's done, we need to repatch the object to have the
- * right class since AllocClass interferes with that.
- */
-
- AllocClass(interp, oPtr);
- oPtr->selfCls = classPtr;
- TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
- }
+ oPtr = TclNewObjectInstanceCommon(interp, classPtr, nameStr, nsNameStr);
+ if (oPtr == NULL) {return TCL_ERROR;}
/*
* Run constructors, except when objc < 0 (a special flag case used for
@@ -1825,7 +1674,7 @@ TclNRNewObjectInstance(
contextPtr->skip = skip;
/*
- * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+ * Adjust the ensemble tracking record if necessary. [Bug 3514761]
*/
if (TclInitRewriteEnsemble(interp, skip, skip, objv)) {
@@ -1836,13 +1685,80 @@ TclNRNewObjectInstance(
* Fire off the constructors non-recursively.
*/
- AddRef(oPtr);
TclNRAddCallback(interp, FinalizeAlloc, contextPtr, oPtr, state,
objectPtr);
TclPushTailcallPoint(interp);
return TclOOInvokeContext(contextPtr, interp, objc, objv);
}
+
+Object *
+TclNewObjectInstanceCommon(
+ Tcl_Interp *interp,
+ Class *classPtr,
+ const char *nameStr,
+ const char *nsNameStr)
+{
+ Tcl_HashEntry *hPtr;
+ Foundation *fPtr = GetFoundation(interp);
+ Object *oPtr;
+ const char *simpleName = NULL;
+ Namespace *nsPtr = NULL, *dummy,
+ *inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
+ int isNew;
+
+ if (nameStr) {
+ TclGetNamespaceForQualName(interp, nameStr, inNsPtr, TCL_CREATE_NS_IF_UNKNOWN,
+ &nsPtr, &dummy, &dummy, &simpleName);
+
+ /*
+ * Disallow creation of an object over an existing command.
+ */
+
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, simpleName, &isNew);
+ if (isNew) {
+ /* Just kidding */
+ Tcl_DeleteHashEntry(hPtr);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't create object \"%s\": command already exists with"
+ " that name", nameStr));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL);
+ return NULL;
+ }
+ }
+
+ /*
+ * Create the object.
+ */
+
+ oPtr = AllocObject(interp, simpleName, nsPtr, nsNameStr);
+ oPtr->selfCls = classPtr;
+ AddRef(classPtr->thisPtr);
+ TclOOAddToInstances(oPtr, classPtr);
+ /*
+ * Check to see if we're really creating a class. If so, allocate the
+ * class structure as well.
+ */
+
+ if (TclOOIsReachable(fPtr->classCls, classPtr)) {
+ /*
+ * Is a class, so attach a class structure. Note that the
+ * TclOOAllocClass function splices the structure into the object, so
+ * we don't have to. Once that's done, we need to repatch the object
+ * to have the right class since TclOOAllocClass interferes with that.
+ */
+
+ TclOOAllocClass(interp, oPtr);
+ TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
+ } else {
+ oPtr->classPtr = NULL;
+ }
+ return oPtr;
+}
+
+
+
static int
FinalizeAlloc(
ClientData data[],
@@ -1855,9 +1771,8 @@ FinalizeAlloc(
Tcl_Object *objectPtr = data[3];
/*
- * 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 errors by accident...)
- * [Bug 2903011]
+ * Ensure an error if the object was deleted in the constructor.
+ * Don't want to lose errors by accident. [Bug 2903011]
*/
if (result != TCL_ERROR && Deleted(oPtr)) {
@@ -1866,7 +1781,6 @@ FinalizeAlloc(
Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL);
result = TCL_ERROR;
}
- TclOODeleteContext(contextPtr);
if (result != TCL_OK) {
Tcl_DiscardInterpState(state);
@@ -1880,12 +1794,14 @@ FinalizeAlloc(
(void) TclOOObjectName(interp, oPtr);
Tcl_DeleteCommandFromToken(interp, oPtr->command);
}
- DelRef(oPtr);
+ /* This decrements the refcount of oPtr */
+ TclOODeleteContext(contextPtr);
return TCL_ERROR;
}
Tcl_RestoreInterpState(interp, state);
*objectPtr = (Tcl_Object) oPtr;
- DelRef(oPtr);
+ /* This decrements the refcount of oPtr */
+ TclOODeleteContext(contextPtr);
return TCL_OK;
}
@@ -1955,16 +1871,22 @@ Tcl_CopyObjectInstance(
* Copy the object's mixin references to the new object.
*/
- FOREACH(mixinPtr, o2Ptr->mixins) {
- if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
- TclOORemoveFromInstances(o2Ptr, mixinPtr);
+ if (o2Ptr->mixins.num != 0) {
+ FOREACH(mixinPtr, o2Ptr->mixins) {
+ if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
+ TclOORemoveFromInstances(o2Ptr, mixinPtr);
+ }
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
+ ckfree(o2Ptr->mixins.list);
}
DUPLICATE(o2Ptr->mixins, oPtr->mixins, Class *);
FOREACH(mixinPtr, o2Ptr->mixins) {
if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
TclOOAddToInstances(o2Ptr, mixinPtr);
}
+ /* For the reference just created in DUPLICATE */
+ AddRef(mixinPtr->thisPtr);
}
/*
@@ -1993,8 +1915,7 @@ Tcl_CopyObjectInstance(
*/
o2Ptr->flags = oPtr->flags & ~(
- OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
-
+ OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
/*
* Copy the object's metadata.
*/
@@ -2043,6 +1964,7 @@ Tcl_CopyObjectInstance(
FOREACH(superPtr, cls2Ptr->superclasses) {
TclOORemoveFromSubclasses(cls2Ptr, superPtr);
+ TclOODecrRefCount(superPtr->thisPtr);
}
if (cls2Ptr->superclasses.num) {
cls2Ptr->superclasses.list = ckrealloc(cls2Ptr->superclasses.list,
@@ -2056,6 +1978,11 @@ Tcl_CopyObjectInstance(
cls2Ptr->superclasses.num = clsPtr->superclasses.num;
FOREACH(superPtr, cls2Ptr->superclasses) {
TclOOAddToSubclasses(cls2Ptr, superPtr);
+
+ /* For the new item in cls2Ptr->superclasses that memcpy just
+ * created
+ */
+ AddRef(superPtr->thisPtr);
}
/*
@@ -2081,15 +2008,18 @@ Tcl_CopyObjectInstance(
* references to the duplicate).
*/
- FOREACH(mixinPtr, cls2Ptr->mixins) {
- TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr);
- }
if (cls2Ptr->mixins.num != 0) {
+ FOREACH(mixinPtr, cls2Ptr->mixins) {
+ TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
+ }
ckfree(clsPtr->mixins.list);
}
DUPLICATE(cls2Ptr->mixins, clsPtr->mixins, Class *);
FOREACH(mixinPtr, cls2Ptr->mixins) {
TclOOAddToMixinSubs(cls2Ptr, mixinPtr);
+ /* For the copy just created in DUPLICATE */
+ AddRef(mixinPtr->thisPtr);
}
/*
@@ -2435,7 +2365,7 @@ Tcl_ObjectSetMetadata(
*
* PublicObjectCmd, PrivateObjectCmd, TclOOInvokeObject --
*
- * Main entry point for object invokations. The Public* and Private*
+ * Main entry point for object invocations. The Public* and Private*
* wrapper functions (implementations of both object instance commands
* and [my]) are just thin wrappers round the main TclOOObjectCmdCore
* function. Note that the core is function is NRE-aware.
@@ -2520,8 +2450,8 @@ TclOOInvokeObject(
*
* TclOOObjectCmdCore, FinalizeObjectCall --
*
- * Main function for object invokations. Does call chain creation,
- * management and invokation. The function FinalizeObjectCall exists to
+ * Main function for object invocations. Does call chain creation,
+ * management and invocation. The function FinalizeObjectCall exists to
* clean up after the non-recursive processing of TclOOObjectCmdCore.
*
* ----------------------------------------------------------------------
@@ -2533,7 +2463,7 @@ TclOOObjectCmdCore(
Tcl_Interp *interp, /* The interpreter containing the object. */
int objc, /* How many arguments are being passed in. */
Tcl_Obj *const *objv, /* The array of arguments. */
- int flags, /* Whether this is an invokation through the
+ int flags, /* Whether this is an invocation through the
* public or the private command interface. */
Class *startCls) /* Where to start in the call chain, or NULL
* if we are to start at the front with
@@ -2722,7 +2652,7 @@ Tcl_ObjectContextInvokeNext(
* call context while we process the body. However, need to adjust the
* argument-skip control because we're guaranteed to have a single prefix
* arg (i.e., 'next') and not the variable amount that can happen because
- * method invokations (i.e., '$obj meth' and 'my meth'), constructors
+ * method invocations (i.e., '$obj meth' and 'my meth'), constructors
* (i.e., '$cls new' and '$cls create obj') and destructors (no args at
* all) come through the same code.
*/
@@ -2791,7 +2721,7 @@ TclNRObjectContextInvokeNext(
* call context while we process the body. However, need to adjust the
* argument-skip control because we're guaranteed to have a single prefix
* arg (i.e., 'next') and not the variable amount that can happen because
- * method invokations (i.e., '$obj meth' and 'my meth'), constructors
+ * method invocations (i.e., '$obj meth' and 'my meth'), constructors
* (i.e., '$cls new' and '$cls create obj') and destructors (no args at
* all) come through the same code.
*/
@@ -3006,7 +2936,7 @@ int
Tcl_ObjectDeleted(
Tcl_Object object)
{
- return Deleted(object) ? 1 : 0;
+ return ((Object *)object)->command == NULL;
}
Tcl_Object
diff --git a/tcl8.6/generic/tclOOBasic.c b/tcl8.6/generic/tclOOBasic.c
index b2c06a7..d874cba 100644
--- a/tcl8.6/generic/tclOOBasic.c
+++ b/tcl8.6/generic/tclOOBasic.c
@@ -1206,22 +1206,10 @@ TclOOCopyObjectCmd(
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, NULL, NULL);
} else {
const char *name, *namespaceName;
- Tcl_DString buffer;
name = TclGetString(objv[2]);
- Tcl_DStringInit(&buffer);
if (name[0] == '\0') {
name = NULL;
- } else if (name[0]!=':' || name[1]!=':') {
- Interp *iPtr = (Interp *) interp;
-
- if (iPtr->varFramePtr != NULL) {
- Tcl_DStringAppend(&buffer,
- iPtr->varFramePtr->nsPtr->fullName, -1);
- }
- TclDStringAppendLiteral(&buffer, "::");
- Tcl_DStringAppend(&buffer, name, -1);
- name = Tcl_DStringValue(&buffer);
}
/*
@@ -1243,7 +1231,6 @@ TclOOCopyObjectCmd(
}
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, namespaceName);
- Tcl_DStringFree(&buffer);
}
if (o2Ptr == NULL) {
diff --git a/tcl8.6/generic/tclOOCall.c b/tcl8.6/generic/tclOOCall.c
index 3e4f561..a46b8bc 100644
--- a/tcl8.6/generic/tclOOCall.c
+++ b/tcl8.6/generic/tclOOCall.c
@@ -110,7 +110,8 @@ TclOODeleteContext(
TclOODeleteChain(contextPtr->callPtr);
if (oPtr != NULL) {
TclStackFree(oPtr->fPtr->interp, contextPtr);
- DelRef(oPtr);
+ /* Corresponding AddRef() in TclOO.c/TclOOObjectCmdCore */
+ TclOODecrRefCount(oPtr);
}
}
@@ -233,7 +234,7 @@ FreeMethodNameRep(
* TclOOInvokeContext --
*
* Invokes a single step along a method call-chain context. Note that the
- * invokation of a step along the chain can cause further steps along the
+ * invocation of a step along the chain can cause further steps along the
* chain to be invoked. Note that this function is written to be as light
* in stack usage as possible.
*
@@ -830,7 +831,7 @@ AddMethodToCallChain(
* Call chain semantics states that methods come as *late* in the
* call chain as possible. This is done by copying down the
* following methods. Note that this does not change the number of
- * method invokations in the call chain; it just rearranges them.
+ * method invocations in the call chain; it just rearranges them.
*/
Class *declCls = callPtr->chain[i].filterDeclarer;
@@ -935,7 +936,7 @@ IsStillValid(
* TclOOGetCallContext --
*
* Responsible for constructing the call context, an ordered list of all
- * method implementations to be called as part of a method invokation.
+ * method implementations to be called as part of a method invocation.
* This method is central to the whole operation of the OO system.
*
* ----------------------------------------------------------------------
@@ -1171,6 +1172,7 @@ TclOOGetCallContext(
returnContext:
contextPtr = TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
contextPtr->oPtr = oPtr;
+ /* Corresponding TclOODecrRefCount() in TclOODeleteContext */
AddRef(oPtr);
contextPtr->callPtr = callPtr;
contextPtr->skip = 2;
@@ -1442,7 +1444,6 @@ AddSimpleClassChainToCallContext(
if (flags & CONSTRUCTOR) {
AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters,
filterDecl, flags);
-
} else if (flags & DESTRUCTOR) {
AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters,
filterDecl, flags);
@@ -1517,7 +1518,7 @@ TclOORenderCallChain(
/*
* Do the actual construction of the descriptions. They consist of a list
* of triples that describe the details of how a method is understood. For
- * each triple, the first word is the type of invokation ("method" is
+ * each triple, the first word is the type of invocation ("method" is
* normal, "unknown" is special because it adds the method name as an
* extra argument when handled by some method types, and "filter" is
* special because it's a filter method). The second word is the name of
diff --git a/tcl8.6/generic/tclOODefineCmds.c b/tcl8.6/generic/tclOODefineCmds.c
index e953dc0..0271a43 100644
--- a/tcl8.6/generic/tclOODefineCmds.c
+++ b/tcl8.6/generic/tclOODefineCmds.c
@@ -326,9 +326,8 @@ TclOOObjectSetMixins(
if (numMixins == 0) {
if (oPtr->mixins.num != 0) {
FOREACH(mixinPtr, oPtr->mixins) {
- if (mixinPtr) {
- TclOORemoveFromInstances(oPtr, mixinPtr);
- }
+ TclOORemoveFromInstances(oPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
ckfree(oPtr->mixins.list);
oPtr->mixins.num = 0;
@@ -340,6 +339,7 @@ TclOOObjectSetMixins(
if (mixinPtr && mixinPtr != oPtr->selfCls) {
TclOORemoveFromInstances(oPtr, mixinPtr);
}
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
oPtr->mixins.list = ckrealloc(oPtr->mixins.list,
sizeof(Class *) * numMixins);
@@ -352,6 +352,8 @@ TclOOObjectSetMixins(
FOREACH(mixinPtr, oPtr->mixins) {
if (mixinPtr != oPtr->selfCls) {
TclOOAddToInstances(oPtr, mixinPtr);
+ /* For the new copy created by memcpy */
+ AddRef(mixinPtr->thisPtr);
}
}
}
@@ -381,6 +383,7 @@ TclOOClassSetMixins(
if (classPtr->mixins.num != 0) {
FOREACH(mixinPtr, classPtr->mixins) {
TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
ckfree(classPtr->mixins.list);
classPtr->mixins.num = 0;
@@ -389,6 +392,7 @@ TclOOClassSetMixins(
if (classPtr->mixins.num != 0) {
FOREACH(mixinPtr, classPtr->mixins) {
TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+ TclOODecrRefCount(mixinPtr->thisPtr);
}
classPtr->mixins.list = ckrealloc(classPtr->mixins.list,
sizeof(Class *) * numMixins);
@@ -399,6 +403,8 @@ TclOOClassSetMixins(
memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
FOREACH(mixinPtr, classPtr->mixins) {
TclOOAddToMixinSubs(classPtr, mixinPtr);
+ /* For the new copy created by memcpy */
+ AddRef(mixinPtr->thisPtr);
}
}
BumpGlobalEpoch(interp, classPtr);
@@ -914,7 +920,7 @@ TclOODefineObjCmd(
} else {
result = MagicDefinitionInvoke(interp, fPtr->defineNs, 2, objc, objv);
}
- DelRef(oPtr);
+ TclOODecrRefCount(oPtr);
/*
* Restore the previous "current" namespace.
@@ -981,7 +987,7 @@ TclOOObjDefObjCmd(
} else {
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 2, objc, objv);
}
- DelRef(oPtr);
+ TclOODecrRefCount(oPtr);
/*
* Restore the previous "current" namespace.
@@ -1048,7 +1054,7 @@ TclOODefineSelfObjCmd(
} else {
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 1, objc, objv);
}
- DelRef(oPtr);
+ TclOODecrRefCount(oPtr);
/*
* Restore the previous "current" namespace.
@@ -1078,6 +1084,7 @@ TclOODefineClassObjCmd(
Object *oPtr;
Class *clsPtr;
Foundation *fPtr = TclOOGetFoundation(interp);
+ int wasClass, willBeClass;
/*
* Parse the context to get the object to operate on.
@@ -1113,19 +1120,10 @@ TclOODefineClassObjCmd(
if (clsPtr == NULL) {
return TCL_ERROR;
}
-
- /*
- * Apply semantic checks. In particular, classes and non-classes are not
- * interchangable (too complicated to do the conversion!) so we must
- * produce an error if any attempt is made to swap from one to the other.
- */
-
- if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "may not change a %sclass object into a %sclass object",
- (oPtr->classPtr==NULL ? "non-" : ""),
- (oPtr->classPtr==NULL ? "" : "non-")));
- Tcl_SetErrorCode(interp, "TCL", "OO", "TRANSMUTATION", NULL);
+ if (oPtr == clsPtr->thisPtr) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "may not change classes into an instance of themselves", -1));
+ Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
return TCL_ERROR;
}
@@ -1133,13 +1131,38 @@ TclOODefineClassObjCmd(
* Set the object's class.
*/
+ wasClass = (oPtr->classPtr != NULL);
+ willBeClass = (TclOOIsReachable(fPtr->classCls, clsPtr));
+
if (oPtr->selfCls != clsPtr) {
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
+ TclOODecrRefCount(oPtr->selfCls->thisPtr);
oPtr->selfCls = clsPtr;
+ AddRef(oPtr->selfCls->thisPtr);
TclOOAddToInstances(oPtr, oPtr->selfCls);
- if (!(clsPtr->thisPtr->flags & OBJECT_DELETED)) {
- oPtr->flags &= ~CLASS_GONE;
+
+ /*
+ * Create or delete the class guts if necessary.
+ */
+
+ if (wasClass && !willBeClass) {
+ /*
+ * This is the most global of all epochs. Bump it! No cache can be
+ * trusted!
+ */
+
+ TclOORemoveFromMixins(oPtr->classPtr, oPtr);
+ oPtr->fPtr->epoch++;
+ oPtr->flags |= DONT_DELETE;
+ TclOODeleteDescendants(interp, oPtr);
+ oPtr->flags &= ~DONT_DELETE;
+ TclOOReleaseClassContents(interp, oPtr);
+ ckfree(oPtr->classPtr);
+ oPtr->classPtr = NULL;
+ } else if (!wasClass && willBeClass) {
+ TclOOAllocClass(interp, oPtr);
}
+
if (oPtr->classPtr != NULL) {
BumpGlobalEpoch(interp, oPtr->classPtr);
} else {
@@ -1551,69 +1574,6 @@ TclOODefineMethodObjCmd(
/*
* ----------------------------------------------------------------------
*
- * TclOODefineMixinObjCmd --
- * Implementation of the "mixin" subcommand of the "oo::define" and
- * "oo::objdefine" commands.
- *
- * ----------------------------------------------------------------------
- */
-
-int
-TclOODefineMixinObjCmd(
- ClientData clientData,
- Tcl_Interp *interp,
- const int objc,
- Tcl_Obj *const *objv)
-{
- int isInstanceMixin = (clientData != NULL);
- Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
- Class **mixins;
- int i;
-
- if (oPtr == NULL) {
- return TCL_ERROR;
- }
- if (!isInstanceMixin && !oPtr->classPtr) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "attempt to misuse API", -1));
- Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
- return TCL_ERROR;
- }
- mixins = TclStackAlloc(interp, sizeof(Class *) * (objc-1));
-
- for (i=1 ; i<objc ; i++) {
- Class *clsPtr = GetClassInOuterContext(interp, objv[i],
- "may only mix in classes");
-
- if (clsPtr == NULL) {
- goto freeAndError;
- }
- if (!isInstanceMixin && TclOOIsReachable(oPtr->classPtr, clsPtr)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "may not mix a class into itself", -1));
- Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
- goto freeAndError;
- }
- mixins[i-1] = clsPtr;
- }
-
- if (isInstanceMixin) {
- TclOOObjectSetMixins(oPtr, objc-1, mixins);
- } else {
- TclOOClassSetMixins(interp, oPtr->classPtr, objc-1, mixins);
- }
-
- TclStackFree(interp, mixins);
- return TCL_OK;
-
- freeAndError:
- TclStackFree(interp, mixins);
- return TCL_ERROR;
-}
-
-/*
- * ----------------------------------------------------------------------
- *
* TclOODefineRenameMethodObjCmd --
* Implementation of the "renamemethod" subcommand of the "oo::define"
* and "oo::objdefine" commands.
@@ -2022,6 +1982,7 @@ ClassMixinSet(
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
"may only mix in classes");
if (mixins[i] == NULL) {
+ i--;
goto freeAndError;
}
if (TclOOIsReachable(oPtr->classPtr, mixins[i])) {
@@ -2139,16 +2100,19 @@ ClassSuperSet(
if (superc == 0) {
superclasses = ckrealloc(superclasses, sizeof(Class *));
- superclasses[0] = oPtr->fPtr->objectCls;
- superc = 1;
if (TclOOIsReachable(oPtr->fPtr->classCls, oPtr->classPtr)) {
superclasses[0] = oPtr->fPtr->classCls;
+ } else {
+ superclasses[0] = oPtr->fPtr->objectCls;
}
+ superc = 1;
+ AddRef(superclasses[0]->thisPtr);
} else {
for (i=0 ; i<superc ; i++) {
superclasses[i] = GetClassInOuterContext(interp, superv[i],
"only a class can be a superclass");
if (superclasses[i] == NULL) {
+ i--;
goto failedAfterAlloc;
}
for (j=0 ; j<i ; j++) {
@@ -2165,9 +2129,15 @@ ClassSuperSet(
"attempt to form circular dependency graph", -1));
Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL);
failedAfterAlloc:
- ckfree((char *) superclasses);
+ for (; i > 0; i--) {
+ TclOODecrRefCount(superclasses[i]->thisPtr);
+ }
+ ckfree(superclasses);
return TCL_ERROR;
}
+ /* Corresponding TclOODecrRefCount() is near the end of this
+ * function */
+ AddRef(superclasses[i]->thisPtr);
}
}
@@ -2181,6 +2151,7 @@ ClassSuperSet(
if (oPtr->classPtr->superclasses.num != 0) {
FOREACH(superPtr, oPtr->classPtr->superclasses) {
TclOORemoveFromSubclasses(oPtr->classPtr, superPtr);
+ TclOODecrRefCount(superPtr->thisPtr);
}
ckfree((char *) oPtr->classPtr->superclasses.list);
}
diff --git a/tcl8.6/generic/tclOOInt.h b/tcl8.6/generic/tclOOInt.h
index b75ffdb..e59fe8a 100644
--- a/tcl8.6/generic/tclOOInt.h
+++ b/tcl8.6/generic/tclOOInt.h
@@ -149,8 +149,8 @@ typedef struct Object {
struct Foundation *fPtr; /* The basis for the object system. Putting
* this here allows the avoidance of quite a
* lot of hash lookups on the critical path
- * for object invokation and creation. */
- Tcl_Namespace *namespacePtr;/* This object's tame namespace. */
+ * for object invocation and creation. */
+ Tcl_Namespace *namespacePtr;/* This object's namespace. */
Tcl_Command command; /* Reference to this object's public
* command. */
Tcl_Command myCommand; /* Reference to this object's internal
@@ -162,12 +162,12 @@ typedef struct Object {
/* Classes mixed into this object. */
LIST_STATIC(Tcl_Obj *) filters;
/* List of filter names. */
- struct Class *classPtr; /* All classes have this non-NULL; it points
- * to the class structure. Everything else has
- * this NULL. */
+ struct Class *classPtr; /* This is non-NULL for all classes, and NULL
+ * for everything else. It points to the class
+ * structure. */
int refCount; /* Number of strong references to this object.
* Note that there may be many more weak
- * references; this mechanism is there to
+ * references; this mechanism exists to
* avoid Tcl_Preserve. */
int flags;
int creationEpoch; /* Unique value to make comparisons of objects
@@ -193,9 +193,10 @@ typedef struct Object {
* destroyed. */
#define DESTRUCTOR_CALLED 2 /* Flag to say that the destructor has been
* called. */
-#define CLASS_GONE 4 /* Indicates that the class of this object has
- * been deleted, and so the object should not
- * attempt to remove itself from its class. */
+#define CLASS_GONE 4 /* Obsolete. Indicates that the class of this
+ * object has been deleted, and so the object
+ * should not attempt to remove itself from its
+ * class. */
#define ROOT_OBJECT 0x1000 /* Flag to say that this object is the root of
* the class hierarchy and should be treated
* specially during teardown. */
@@ -213,6 +214,7 @@ typedef struct Object {
* other spots). */
#define FORCE_UNKNOWN 0x10000 /* States that we are *really* looking up the
* unknown method handler at that point. */
+#define DONT_DELETE 0x20000 /* Inhibit deletion of this object. */
/*
* And the definition of a class. Note that every class also has an associated
@@ -222,10 +224,6 @@ typedef struct Object {
typedef struct Class {
Object *thisPtr; /* Reference to the object associated with
* this class. */
- int refCount; /* Number of strong references to this class.
- * Weak references are not counted; the
- * purpose of this is to avoid Tcl_Preserve as
- * that is quite slow. */
int flags; /* Assorted flags. */
LIST_STATIC(struct Class *) superclasses;
/* List of superclasses, used for generation
@@ -323,7 +321,7 @@ typedef struct Foundation {
} Foundation;
/*
- * A call context structure is built when a method is called. They contain the
+ * A call context structure is built when a method is called. It contains the
* chain of method implementations that are to be invoked by a particular
* call, and the process of calling walks the chain, with the [next] command
* proceeding to the next entry in the chain.
@@ -334,7 +332,7 @@ typedef struct Foundation {
struct MInvoke {
Method *mPtr; /* Reference to the method implementation
* record. */
- int isFilter; /* Whether this is a filter invokation. */
+ int isFilter; /* Whether this is a filter invocation. */
Class *filterDeclarer; /* What class decided to add the filter; if
* NULL, it was added by the object. */
};
@@ -487,15 +485,24 @@ MODULE_SCOPE int TclOO_Object_VarName(ClientData clientData,
MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr);
MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr);
MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr);
+MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp,
+ Object *useThisObj);
MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
Tcl_Class cls, const char *nameStr,
const char *nsNameStr, int objc,
Tcl_Obj *const *objv, int skip,
Tcl_Object *objectPtr);
+MODULE_SCOPE Object * TclNewObjectInstanceCommon(Tcl_Interp *interp,
+ Class *classPtr,
+ const char *nameStr,
+ const char *nsNameStr);
+MODULE_SCOPE int TclOODecrRefCount(Object *oPtr);
MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr);
MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr);
MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr);
MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr);
+MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp,
+ Object *oPtr);
MODULE_SCOPE void TclOODelMethodRef(Method *method);
MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr,
Tcl_Obj *methodNameObj, int flags,
@@ -521,10 +528,13 @@ MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp,
MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
const DeclaredClassMethod *dcm);
MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
-MODULE_SCOPE void TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
-MODULE_SCOPE void TclOORemoveFromMixinSubs(Class *subPtr,
+MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp,
+ Object *oPtr);
+MODULE_SCOPE int TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
+MODULE_SCOPE int TclOORemoveFromMixins(Class *mixinPtr, Object *oPtr);
+MODULE_SCOPE int TclOORemoveFromMixinSubs(Class *subPtr,
Class *mixinPtr);
-MODULE_SCOPE void TclOORemoveFromSubclasses(Class *subPtr,
+MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr,
Class *superPtr);
MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp,
CallChain *callPtr);
@@ -539,18 +549,21 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
#include "tclOOIntDecls.h"
/*
+ * Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
+ */
+
+#define AddRef(ptr) ((ptr)->refCount++)
+
+/*
* A convenience macro for iterating through the lists used in the internal
- * memory management of objects. This is a bit gnarly because we want to do
- * the assignment of the picked-out value only when the body test succeeds,
- * but we cannot rely on the assigned value being useful, forcing us to do
- * some nasty stuff with the comma operator. The compiler's optimizer should
- * be able to sort it all out!
- *
+ * memory management of objects.
* REQUIRES DECLARATION: int i;
*/
#define FOREACH(var,ary) \
- for(i=0 ; (i<(ary).num?((var=(ary).list[i]),1):0) ; i++)
+ for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \
+ continue; \
+ } else if (var = (ary).list[i], 1)
/*
* Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
@@ -585,17 +598,6 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
} \
} while(0)
-/*
- * Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
- */
-
-#define AddRef(ptr) ((ptr)->refCount++)
-#define DelRef(ptr) do { \
- if ((ptr)->refCount-- <= 1) { \
- ckfree((char *) (ptr)); \
- } \
- } while(0)
-
#endif /* TCL_OO_INTERNAL_H */
/*
diff --git a/tcl8.6/generic/tclObj.c b/tcl8.6/generic/tclObj.c
index 3bf5b8e..a75ecdd 100644
--- a/tcl8.6/generic/tclObj.c
+++ b/tcl8.6/generic/tclObj.c
@@ -2467,23 +2467,26 @@ Tcl_SetIntObj(
*
* Tcl_GetIntFromObj --
*
- * Attempt to return an int from the Tcl object "objPtr". If the object
- * is not already an int, an attempt will be made to convert it to one.
+ * Retrieve the integer value of 'objPtr'.
*
- * Integer and long integer objects share the same "integer" type
- * implementation. We store all integers as longs and Tcl_GetIntFromObj
- * checks whether the current value of the long can be represented by an
- * int.
+ * Value
*
- * Results:
- * The return value is a standard Tcl object result. If an error occurs
- * during conversion or if the long integer held by the object can not be
- * represented by an int, an error message is left in the interpreter's
- * result unless "interp" is NULL.
+ * TCL_OK
*
- * Side effects:
- * If the object is not already an int, the conversion will free any old
- * internal representation.
+ * Success.
+ *
+ * TCL_ERROR
+ *
+ * An error occurred during conversion or the integral value can not
+ * be represented as an integer (it might be too large). An error
+ * message is left in the interpreter's result if 'interp' is not
+ * NULL.
+ *
+ * Effect
+ *
+ * 'objPtr' is converted to an integer if necessary if it is not one
+ * already. The conversion frees any previously-existing internal
+ * representation.
*
*----------------------------------------------------------------------
*/
diff --git a/tcl8.6/generic/tclParse.c b/tcl8.6/generic/tclParse.c
index f2cf322..f26f933 100644
--- a/tcl8.6/generic/tclParse.c
+++ b/tcl8.6/generic/tclParse.c
@@ -991,7 +991,13 @@ TclParseBackslash(
if (readPtr != NULL) {
*readPtr = count;
}
- return Tcl_UniCharToUtf(result, dst);
+ count = Tcl_UniCharToUtf(result, dst);
+#if TCL_UTF_MAX > 3
+ if (!count) {
+ count = Tcl_UniCharToUtf(-1, dst);
+ }
+#endif
+ return count;
}
/*
diff --git a/tcl8.6/generic/tclPkg.c b/tcl8.6/generic/tclPkg.c
index 4f6faa8..d4080c2 100644
--- a/tcl8.6/generic/tclPkg.c
+++ b/tcl8.6/generic/tclPkg.c
@@ -49,6 +49,18 @@ typedef struct Package {
const void *clientData; /* Client data. */
} Package;
+typedef struct Require {
+ void * clientDataPtr;
+ const char *name;
+ Package *pkgPtr;
+ char *versionToProvide;
+} Require;
+
+typedef struct RequireProcArgs {
+ const char *name;
+ void *clientDataPtr;
+} RequireProcArgs;
+
/*
* Prototypes for functions defined in this file:
*/
@@ -69,9 +81,15 @@ static void AddRequirementsToResult(Tcl_Interp *interp, int reqc,
static void AddRequirementsToDString(Tcl_DString *dstring,
int reqc, Tcl_Obj *const reqv[]);
static Package * FindPackage(Tcl_Interp *interp, const char *name);
-static const char * PkgRequireCore(Tcl_Interp *interp, const char *name,
- int reqc, Tcl_Obj *const reqv[],
- void *clientDataPtr);
+static int PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result);
+static int TclNRPkgRequireProc(ClientData clientData, Tcl_Interp *interp, int reqc, Tcl_Obj *const reqv[]);
+static int SelectPackage(ClientData data[], Tcl_Interp *interp, int result);
+static int SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result);
+static int TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result);
/*
* Helper macros.
@@ -299,7 +317,10 @@ Tcl_PkgRequireEx(
*/
if (version == NULL) {
- result = PkgRequireCore(interp, name, 0, NULL, clientDataPtr);
+ if (Tcl_PkgRequireProc(interp, name, 0, NULL, clientDataPtr) == TCL_OK) {
+ result = Tcl_GetStringResult(interp);
+ Tcl_ResetResult(interp);
+ }
} else {
if (exact && TCL_OK
!= CheckVersionAndConvert(interp, version, NULL, NULL)) {
@@ -310,10 +331,12 @@ Tcl_PkgRequireEx(
Tcl_AppendStringsToObj(ov, "-", version, NULL);
}
Tcl_IncrRefCount(ov);
- result = PkgRequireCore(interp, name, 1, &ov, clientDataPtr);
+ if (Tcl_PkgRequireProc(interp, name, 1, &ov, clientDataPtr) == TCL_OK) {
+ result = Tcl_GetStringResult(interp);
+ Tcl_ResetResult(interp);
+ }
TclDecrRefCount(ov);
}
-
return result;
}
@@ -328,354 +351,414 @@ Tcl_PkgRequireProc(
* available. */
void *clientDataPtr)
{
- const char *result =
- PkgRequireCore(interp, name, reqc, reqv, clientDataPtr);
+ RequireProcArgs args;
+ args.name = name;
+ args.clientDataPtr = clientDataPtr;
+ return Tcl_NRCallObjProc(interp, TclNRPkgRequireProc, (void *)&args, reqc, reqv);
+}
- if (result == NULL) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
+static int
+TclNRPkgRequireProc(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int reqc,
+ Tcl_Obj *const reqv[]) {
+ RequireProcArgs *args = clientData;
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)args->name, INT2PTR(reqc), (void *)reqv, args->clientDataPtr);
return TCL_OK;
}
-static const char *
-PkgRequireCore(
- Tcl_Interp *interp, /* Interpreter in which package is now
- * available. */
- const char *name, /* Name of desired package. */
- int reqc, /* Requirements constraining the desired
- * version. */
- Tcl_Obj *const reqv[], /* 0 means to use the latest version
- * available. */
- void *clientDataPtr)
+static int
+PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result)
{
- Interp *iPtr = (Interp *) interp;
- Package *pkgPtr;
- PkgAvail *availPtr, *bestPtr, *bestStablePtr;
- char *availVersion, *bestVersion, *bestStableVersion;
- /* Internal rep. of versions */
- int availStable, code, satisfies, pass;
- char *script, *pkgVersionI;
+ const char *name = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj *const *reqv = data[2];
+ int code = CheckAllRequirements(interp, reqc, reqv);
+ Require *reqPtr;
+ if (code != TCL_OK) {
+ return code;
+ }
+ reqPtr = ckalloc(sizeof(Require));
+ Tcl_NRAddCallback(interp, PkgRequireCoreCleanup, reqPtr, NULL, NULL, NULL);
+ reqPtr->clientDataPtr = data[3];
+ reqPtr->name = name;
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ if (reqPtr->pkgPtr->version == NULL) {
+ Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreStep1);
+ } else {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ }
+ return TCL_OK;
+}
+
+static int
+PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result) {
Tcl_DString command;
+ char *script;
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if (reqPtr->pkgPtr->version == NULL) {
+ /*
+ * The package is not in the database. If there is a "package unknown"
+ * command, invoke it.
+ */
- if (TCL_OK != CheckAllRequirements(interp, reqc, reqv)) {
- return NULL;
+ script = ((Interp *) interp)->packageUnknown;
+ if (script == NULL) {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ } else {
+ Tcl_DStringInit(&command);
+ Tcl_DStringAppend(&command, script, -1);
+ Tcl_DStringAppendElement(&command, name);
+ AddRequirementsToDString(&command, reqc, reqv);
+
+ Tcl_NRAddCallback(interp, PkgRequireCoreStep2, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ Tcl_NREvalObj(interp,
+ Tcl_NewStringObj(Tcl_DStringValue(&command), Tcl_DStringLength(&command)),
+ TCL_EVAL_GLOBAL
+ );
+ Tcl_DStringFree(&command);
+ }
+ return TCL_OK;
+ } else {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ }
+ return TCL_OK;
+}
+
+static int
+PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if ((result != TCL_OK) && (result != TCL_ERROR)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad return code: %d", result));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+ result = TCL_ERROR;
+ }
+ if (result == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp,
+ "\n (\"package unknown\" script)");
+ return result;
+ }
+ Tcl_ResetResult(interp);
+ /* pkgPtr may now be invalid, so refresh it. */
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreFinal);
+ return TCL_OK;
+}
+
+static int
+PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]), satisfies;
+ Tcl_Obj **const reqv = data[2];
+ char *pkgVersionI;
+ void *clientDataPtr = reqPtr->clientDataPtr;
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if (reqPtr->pkgPtr->version == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't find package %s", name));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
+ AddRequirementsToResult(interp, reqc, reqv);
+ return TCL_ERROR;
}
/*
- * It can take up to three passes to find the package: one pass to run the
- * "package unknown" script, one to run the "package ifneeded" script for
- * a specific version, and a final pass to lookup the package loaded by
- * the "package ifneeded" script.
+ * Ensure that the provided version meets the current requirements.
*/
- for (pass=1 ;; pass++) {
- pkgPtr = FindPackage(interp, name);
- if (pkgPtr->version != NULL) {
- break;
- }
+ if (reqc != 0) {
+ CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pkgVersionI, NULL);
+ satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
- /*
- * Check whether we're already attempting to load some version of this
- * package (circular dependency detection).
- */
+ ckfree(pkgVersionI);
- if (pkgPtr->clientData != NULL) {
+ if (!satisfies) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "circular package dependency:"
- " attempt to provide %s %s requires %s",
- name, (char *) pkgPtr->clientData, name));
+ "version conflict for package \"%s\": have %s, need",
+ name, reqPtr->pkgPtr->version));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
+ NULL);
AddRequirementsToResult(interp, reqc, reqv);
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
- return NULL;
+ return TCL_ERROR;
}
+ }
- /*
- * The package isn't yet present. Search the list of available
- * versions and invoke the script for the best available version. We
- * are actually locating the best, and the best stable version. One of
- * them is then chosen based on the selection mode.
- */
+ if (clientDataPtr) {
+ const void **ptr = (const void **) clientDataPtr;
- bestPtr = NULL;
- bestStablePtr = NULL;
- bestVersion = NULL;
- bestStableVersion = NULL;
+ *ptr = reqPtr->pkgPtr->clientData;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(reqPtr->pkgPtr->version, -1));
+ return TCL_OK;
+}
- for (availPtr = pkgPtr->availPtr; availPtr != NULL;
- availPtr = availPtr->nextPtr) {
- if (CheckVersionAndConvert(interp, availPtr->version,
- &availVersion, &availStable) != TCL_OK) {
- /*
- * The provided version number has invalid syntax. This
- * should not happen. This should have been caught by the
- * 'package ifneeded' registering the package.
- */
+static int
+PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result) {
+ ckfree(data[0]);
+ return result;
+}
- continue;
- }
-
- /* Check satisfaction of requirements before considering the current version further. */
- if (reqc > 0) {
- satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
- if (!satisfies) {
- ckfree(availVersion);
- availVersion = NULL;
- continue;
- }
- }
-
- if (bestPtr != NULL) {
- int res = CompareVersions(availVersion, bestVersion, NULL);
+
+static int
+SelectPackage(ClientData data[], Tcl_Interp *interp, int result) {
+ PkgAvail *availPtr, *bestPtr, *bestStablePtr;
+ char *availVersion, *bestVersion, *bestStableVersion;
+ /* Internal rep. of versions */
+ int availStable, satisfies;
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name;
+ Package *pkgPtr = reqPtr->pkgPtr;
+ Interp *iPtr = (Interp *) interp;
- /*
- * Note: Used internal reps in the comparison!
- */
+ /*
+ * Check whether we're already attempting to load some version of this
+ * package (circular dependency detection).
+ */
- if (res > 0) {
- /*
- * The version of the package sought is better than the
- * currently selected version.
- */
- ckfree(bestVersion);
- bestVersion = NULL;
- goto newbest;
- }
- } else {
- newbest:
- /* We have found a version which is better than our max. */
+ if (pkgPtr->clientData != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "circular package dependency:"
+ " attempt to provide %s %s requires %s",
+ name, (char *) pkgPtr->clientData, name));
+ AddRequirementsToResult(interp, reqc, reqv);
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
+ return TCL_ERROR;
+ }
- bestPtr = availPtr;
- CheckVersionAndConvert(interp, bestPtr->version, &bestVersion, NULL);
- }
+ /*
+ * The package isn't yet present. Search the list of available
+ * versions and invoke the script for the best available version. We
+ * are actually locating the best, and the best stable version. One of
+ * them is then chosen based on the selection mode.
+ */
+
+ bestPtr = NULL;
+ bestStablePtr = NULL;
+ bestVersion = NULL;
+ bestStableVersion = NULL;
+
+ for (availPtr = pkgPtr->availPtr; availPtr != NULL;
+ availPtr = availPtr->nextPtr) {
+ if (CheckVersionAndConvert(interp, availPtr->version,
+ &availVersion, &availStable) != TCL_OK) {
+ /*
+ * The provided version number has invalid syntax. This
+ * should not happen. This should have been caught by the
+ * 'package ifneeded' registering the package.
+ */
+
+ continue;
+ }
- if (!availStable) {
+ /* Check satisfaction of requirements before considering the current version further. */
+ if (reqc > 0) {
+ satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
+ if (!satisfies) {
ckfree(availVersion);
availVersion = NULL;
continue;
}
+ }
+
+ if (bestPtr != NULL) {
+ int res = CompareVersions(availVersion, bestVersion, NULL);
- if (bestStablePtr != NULL) {
- int res = CompareVersions(availVersion, bestStableVersion, NULL);
+ /*
+ * Note: Used internal reps in the comparison!
+ */
+ if (res > 0) {
/*
- * Note: Used internal reps in the comparison!
+ * The version of the package sought is better than the
+ * currently selected version.
*/
-
- if (res > 0) {
- /*
- * This stable version of the package sought is better
- * than the currently selected stable version.
- */
- ckfree(bestStableVersion);
- bestStableVersion = NULL;
- goto newstable;
- }
- } else {
- newstable:
- /* We have found a stable version which is better than our max stable. */
- bestStablePtr = availPtr;
- CheckVersionAndConvert(interp, bestStablePtr->version, &bestStableVersion, NULL);
+ ckfree(bestVersion);
+ bestVersion = NULL;
+ goto newbest;
}
+ } else {
+ newbest:
+ /* We have found a version which is better than our max. */
- ckfree(availVersion);
- availVersion = NULL;
- } /* end for */
-
- /*
- * Clean up memorized internal reps, if any.
- */
-
- if (bestVersion != NULL) {
- ckfree(bestVersion);
- bestVersion = NULL;
+ bestPtr = availPtr;
+ CheckVersionAndConvert(interp, bestPtr->version, &bestVersion, NULL);
}
- if (bestStableVersion != NULL) {
- ckfree(bestStableVersion);
- bestStableVersion = NULL;
+ if (!availStable) {
+ ckfree(availVersion);
+ availVersion = NULL;
+ continue;
}
- /*
- * Now choose a version among the two best. For 'latest' we simply
- * take (actually keep) the best. For 'stable' we take the best
- * stable, if there is any, or the best if there is nothing stable.
- */
+ if (bestStablePtr != NULL) {
+ int res = CompareVersions(availVersion, bestStableVersion, NULL);
- if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
- && (bestStablePtr != NULL)) {
- bestPtr = bestStablePtr;
- }
-
- if (bestPtr != NULL) {
/*
- * We found an ifneeded script for the package. Be careful while
- * executing it: this could cause reentrancy, so (a) protect the
- * script itself from deletion and (b) don't assume that bestPtr
- * will still exist when the script completes.
+ * Note: Used internal reps in the comparison!
*/
- char *versionToProvide = bestPtr->version;
- script = bestPtr->script;
-
- pkgPtr->clientData = versionToProvide;
- Tcl_Preserve(script);
- Tcl_Preserve(versionToProvide);
- code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
- Tcl_Release(script);
-
- pkgPtr = FindPackage(interp, name);
- if (code == TCL_OK) {
- Tcl_ResetResult(interp);
- if (pkgPtr->version == NULL) {
- code = TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " no version of package %s provided",
- name, versionToProvide, name));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
- NULL);
- } else {
- char *pvi, *vi;
-
- if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi,
- NULL) != TCL_OK) {
- code = TCL_ERROR;
- } else if (CheckVersionAndConvert(interp,
- versionToProvide, &vi, NULL) != TCL_OK) {
- ckfree(pvi);
- code = TCL_ERROR;
- } else {
- int res = CompareVersions(pvi, vi, NULL);
-
- ckfree(pvi);
- ckfree(vi);
- if (res != 0) {
- code = TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " package %s %s provided instead",
- name, versionToProvide,
- name, pkgPtr->version));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
- "WRONGPROVIDE", NULL);
- }
- }
- }
- } else if (code != TCL_ERROR) {
- Tcl_Obj *codePtr = Tcl_NewIntObj(code);
-
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " bad return code: %s",
- name, versionToProvide, TclGetString(codePtr)));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
- TclDecrRefCount(codePtr);
- code = TCL_ERROR;
- }
-
- if (code == TCL_ERROR) {
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (\"package ifneeded %s %s\" script)",
- name, versionToProvide));
- }
- Tcl_Release(versionToProvide);
-
- if (code != TCL_OK) {
+ if (res > 0) {
/*
- * Take a non-TCL_OK code from the script as an indication the
- * package wasn't loaded properly, so the package system
- * should not remember an improper load.
- *
- * This is consistent with our returning NULL. If we're not
- * willing to tell our caller we got a particular version, we
- * shouldn't store that version for telling future callers
- * either.
+ * This stable version of the package sought is better
+ * than the currently selected stable version.
*/
-
- if (pkgPtr->version != NULL) {
- ckfree(pkgPtr->version);
- pkgPtr->version = NULL;
- }
- pkgPtr->clientData = NULL;
- return NULL;
+ ckfree(bestStableVersion);
+ bestStableVersion = NULL;
+ goto newstable;
}
-
- break;
+ } else {
+ newstable:
+ /* We have found a stable version which is better than our max stable. */
+ bestStablePtr = availPtr;
+ CheckVersionAndConvert(interp, bestStablePtr->version, &bestStableVersion, NULL);
}
- /*
- * The package is not in the database. If there is a "package unknown"
- * command, invoke it (but only on the first pass; after that, we
- * should not get here in the first place).
- */
+ ckfree(availVersion);
+ availVersion = NULL;
+ } /* end for */
- if (pass > 1) {
- break;
- }
+ /*
+ * Clean up memorized internal reps, if any.
+ */
- script = ((Interp *) interp)->packageUnknown;
- if (script != NULL) {
- Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, script, -1);
- Tcl_DStringAppendElement(&command, name);
- AddRequirementsToDString(&command, reqc, reqv);
-
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
- Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
- Tcl_DStringFree(&command);
-
- if ((code != TCL_OK) && (code != TCL_ERROR)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad return code: %d", code));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
- code = TCL_ERROR;
- }
- if (code == TCL_ERROR) {
- Tcl_AddErrorInfo(interp,
- "\n (\"package unknown\" script)");
- return NULL;
- }
- Tcl_ResetResult(interp);
- }
+ if (bestVersion != NULL) {
+ ckfree(bestVersion);
+ bestVersion = NULL;
}
- if (pkgPtr->version == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't find package %s", name));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
- AddRequirementsToResult(interp, reqc, reqv);
- return NULL;
+ if (bestStableVersion != NULL) {
+ ckfree(bestStableVersion);
+ bestStableVersion = NULL;
}
/*
- * At this point we know that the package is present. Make sure that the
- * provided version meets the current requirements.
+ * Now choose a version among the two best. For 'latest' we simply
+ * take (actually keep) the best. For 'stable' we take the best
+ * stable, if there is any, or the best if there is nothing stable.
*/
- if (reqc != 0) {
- CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL);
- satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
+ if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
+ && (bestStablePtr != NULL)) {
+ bestPtr = bestStablePtr;
+ }
- ckfree(pkgVersionI);
+ if (bestPtr == NULL) {
+ Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ } else {
+ /*
+ * We found an ifneeded script for the package. Be careful while
+ * executing it: this could cause reentrancy, so (a) protect the
+ * script itself from deletion and (b) don't assume that bestPtr
+ * will still exist when the script completes.
+ */
- if (!satisfies) {
+ char *versionToProvide = bestPtr->version;
+
+ pkgPtr->clientData = versionToProvide;
+ Tcl_Preserve(versionToProvide);
+ reqPtr->versionToProvide = versionToProvide;
+ Tcl_NRAddCallback(interp, SelectPackageFinal, reqPtr, INT2PTR(reqc), (void *)reqv, data[3]);
+ Tcl_NREvalObj(interp, Tcl_NewStringObj(bestPtr->script, -1), TCL_EVAL_GLOBAL);
+ }
+ return TCL_OK;
+}
+
+static int
+SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name;
+ char *versionToProvide = reqPtr->versionToProvide;
+
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ if (result == TCL_OK) {
+ Tcl_ResetResult(interp);
+ if (reqPtr->pkgPtr->version == NULL) {
+ result = TCL_ERROR;
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "version conflict for package \"%s\": have %s, need",
- name, pkgPtr->version));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
+ "attempt to provide package %s %s failed:"
+ " no version of package %s provided",
+ name, versionToProvide, name));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
NULL);
- AddRequirementsToResult(interp, reqc, reqv);
- return NULL;
+ } else {
+ char *pvi, *vi;
+
+ if (CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pvi,
+ NULL) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (CheckVersionAndConvert(interp,
+ versionToProvide, &vi, NULL) != TCL_OK) {
+ ckfree(pvi);
+ result = TCL_ERROR;
+ } else {
+ int res = CompareVersions(pvi, vi, NULL);
+
+ ckfree(pvi);
+ ckfree(vi);
+ if (res != 0) {
+ result = TCL_ERROR;
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "attempt to provide package %s %s failed:"
+ " package %s %s provided instead",
+ name, versionToProvide,
+ name, reqPtr->pkgPtr->version));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
+ "WRONGPROVIDE", NULL);
+ }
+ }
}
+ } else if (result != TCL_ERROR) {
+ Tcl_Obj *codePtr = Tcl_NewIntObj(result);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "attempt to provide package %s %s failed:"
+ " bad return code: %s",
+ name, versionToProvide, TclGetString(codePtr)));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+ TclDecrRefCount(codePtr);
+ result = TCL_ERROR;
}
- if (clientDataPtr) {
- const void **ptr = (const void **) clientDataPtr;
+ if (result == TCL_ERROR) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"package ifneeded %s %s\" script)",
+ name, versionToProvide));
+ }
+ Tcl_Release(versionToProvide);
- *ptr = pkgPtr->clientData;
+ if (result != TCL_OK) {
+ /*
+ * Take a non-TCL_OK code from the script as an indication the
+ * package wasn't loaded properly, so the package system
+ * should not remember an improper load.
+ *
+ * This is consistent with our returning NULL. If we're not
+ * willing to tell our caller we got a particular version, we
+ * shouldn't store that version for telling future callers
+ * either.
+ */
+
+ if (reqPtr->pkgPtr->version != NULL) {
+ ckfree(reqPtr->pkgPtr->version);
+ reqPtr->pkgPtr->version = NULL;
+ }
+ reqPtr->pkgPtr->clientData = NULL;
+ return result;
}
- return pkgPtr->version;
+
+ Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ return TCL_OK;
}
/*
@@ -781,10 +864,19 @@ Tcl_PkgPresentEx(
*
*----------------------------------------------------------------------
*/
+int
+Tcl_PackageObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ return Tcl_NRCallObjProc(interp, TclNRPackageObjCmd, NULL, objc, objv);
+}
/* ARGSUSED */
int
-Tcl_PackageObjCmd(
+TclNRPackageObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
@@ -801,7 +893,7 @@ Tcl_PackageObjCmd(
PKG_VSATISFIES
};
Interp *iPtr = (Interp *) interp;
- int optionIndex, exact, i, satisfies;
+ int optionIndex, exact, i, newobjc, satisfies;
PkgAvail *availPtr, *prevPtr;
Package *pkgPtr;
Tcl_HashEntry *hPtr;
@@ -810,6 +902,7 @@ Tcl_PackageObjCmd(
const char *version;
const char *argv2, *argv3, *argv4;
char *iva = NULL, *ivb = NULL;
+ Tcl_Obj *objvListPtr, **newObjvPtr;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
@@ -1016,7 +1109,6 @@ Tcl_PackageObjCmd(
argv2 = TclGetString(objv[2]);
if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
Tcl_Obj *ov;
- int res;
if (objc != 5) {
goto requireSyntax;
@@ -1036,17 +1128,38 @@ Tcl_PackageObjCmd(
Tcl_AppendStringsToObj(ov, "-", version, NULL);
version = NULL;
argv3 = TclGetString(objv[3]);
+ Tcl_IncrRefCount(objv[3]);
+
+ objvListPtr = Tcl_NewListObj(0, NULL);
+ Tcl_IncrRefCount(objvListPtr);
+ Tcl_ListObjAppendElement(interp, objvListPtr, ov);
+ Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
- Tcl_IncrRefCount(ov);
- res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL);
- TclDecrRefCount(ov);
- return res;
+ Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[3], objvListPtr, NULL, NULL);
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv3, INT2PTR(newobjc), newObjvPtr, NULL);
+ return TCL_OK;
} else {
+ int i, newobjc = objc-3;
+ Tcl_Obj *const *newobjv = objv + 3;
if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
return TCL_ERROR;
}
+ objvListPtr = Tcl_NewListObj(0, NULL);
+ Tcl_IncrRefCount(objvListPtr);
+ Tcl_IncrRefCount(objv[2]);
+ for (i = 0; i < newobjc; i++) {
+
+ /*
+ * Tcl_Obj structures may have come from another interpreter,
+ * so duplicate them.
+ */
- return Tcl_PkgRequireProc(interp, argv2, objc-3, objv+3, NULL);
+ Tcl_ListObjAppendElement(interp, objvListPtr, Tcl_DuplicateObj(newobjv[i]));
+ }
+ Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
+ Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[2], objvListPtr, NULL, NULL);
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv2, INT2PTR(newobjc), newObjvPtr, NULL);
+ return TCL_OK;
}
break;
case PKG_UNKNOWN: {
@@ -1186,6 +1299,13 @@ Tcl_PackageObjCmd(
}
return TCL_OK;
}
+
+static int
+TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result) {
+ TclDecrRefCount((Tcl_Obj *)data[0]);
+ TclDecrRefCount((Tcl_Obj *)data[1]);
+ return result;
+}
/*
*----------------------------------------------------------------------
diff --git a/tcl8.6/generic/tclProc.c b/tcl8.6/generic/tclProc.c
index 5c68e17..533b817 100644
--- a/tcl8.6/generic/tclProc.c
+++ b/tcl8.6/generic/tclProc.c
@@ -124,11 +124,10 @@ Tcl_ProcObjCmd(
{
register Interp *iPtr = (Interp *) interp;
Proc *procPtr;
- const char *fullName;
- const char *procName, *procArgs, *procBody;
+ const char *procName;
+ const char *simpleName, *procArgs, *procBody;
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
Tcl_Command cmd;
- Tcl_DString ds;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "name args body");
@@ -141,29 +140,21 @@ Tcl_ProcObjCmd(
* namespace.
*/
- fullName = TclGetString(objv[1]);
- TclGetNamespaceForQualName(interp, fullName, NULL, 0,
- &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
+ procName = TclGetString(objv[1]);
+ TclGetNamespaceForQualName(interp, procName, NULL, 0,
+ &nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
if (nsPtr == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create procedure \"%s\": unknown namespace",
- fullName));
+ procName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
return TCL_ERROR;
}
- if (procName == NULL) {
+ if (simpleName == NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"can't create procedure \"%s\": bad procedure name",
- fullName));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
- return TCL_ERROR;
- }
- if ((nsPtr != iPtr->globalNsPtr)
- && (procName != NULL) && (procName[0] == ':')) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't create procedure \"%s\" in non-global namespace with"
- " name starting with \":\"", procName));
+ procName));
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
return TCL_ERROR;
}
@@ -172,31 +163,16 @@ Tcl_ProcObjCmd(
* Create the data structure to represent the procedure.
*/
- if (TclCreateProc(interp, nsPtr, procName, objv[2], objv[3],
+ if (TclCreateProc(interp, nsPtr, simpleName, objv[2], objv[3],
&procPtr) != TCL_OK) {
Tcl_AddErrorInfo(interp, "\n (creating proc \"");
- Tcl_AddErrorInfo(interp, procName);
+ Tcl_AddErrorInfo(interp, simpleName);
Tcl_AddErrorInfo(interp, "\")");
return TCL_ERROR;
}
- /*
- * Now create a command for the procedure. This will initially be in the
- * current namespace unless the procedure's name included namespace
- * qualifiers. To create the new command in the right namespace, we
- * generate a fully qualified name for it.
- */
-
- Tcl_DStringInit(&ds);
- if (nsPtr != iPtr->globalNsPtr) {
- Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
- TclDStringAppendLiteral(&ds, "::");
- }
- Tcl_DStringAppend(&ds, procName, -1);
-
- cmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), TclObjInterpProc,
- TclNRInterpProc, procPtr, TclProcDeleteProc);
- Tcl_DStringFree(&ds);
+ cmd = TclNRCreateCommandInNs(interp, simpleName, (Tcl_Namespace *) nsPtr,
+ TclObjInterpProc, TclNRInterpProc, procPtr, TclProcDeleteProc);
/*
* Now initialize the new procedure's cmdPtr field. This will be used
@@ -393,13 +369,13 @@ TclCreateProc(
Proc **procPtrPtr) /* Returns: pointer to proc data. */
{
Interp *iPtr = (Interp *) interp;
- const char **argArray = NULL;
register Proc *procPtr;
- int i, length, result, numArgs;
- const char *args, *bytes, *p;
+ int i, result, numArgs, plen;
+ const char *bytes, *argname, *argnamei;
+ char argnamelast;
register CompiledLocal *localPtr = NULL;
- Tcl_Obj *defPtr;
+ Tcl_Obj *defPtr, *errorObj, **argArray;
int precompiled = 0;
if (bodyPtr->typePtr == &tclProcBodyType) {
@@ -436,6 +412,7 @@ TclCreateProc(
*/
if (Tcl_IsShared(bodyPtr)) {
+ int length;
Tcl_Obj *sharedBodyPtr = bodyPtr;
bytes = TclGetStringFromObj(bodyPtr, &length);
@@ -473,12 +450,9 @@ TclCreateProc(
* argument specifier. If the body is precompiled, processing is limited
* to checking that the parsed argument is consistent with the one stored
* in the Proc.
- *
- * THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULS.
*/
- args = TclGetStringFromObj(argsPtr, &length);
- result = Tcl_SplitList(interp, args, &numArgs, &argArray);
+ result = Tcl_ListObjGetElements(interp , argsPtr ,&numArgs ,&argArray);
if (result != TCL_OK) {
goto procError;
}
@@ -501,28 +475,28 @@ TclCreateProc(
for (i = 0; i < numArgs; i++) {
int fieldCount, nameLength, valueLength;
- const char **fieldValues;
+ Tcl_Obj **fieldValues;
/*
* Now divide the specifier up into name and default.
*/
- result = Tcl_SplitList(interp, argArray[i], &fieldCount,
+ result = Tcl_ListObjGetElements(interp, argArray[i], &fieldCount,
&fieldValues);
if (result != TCL_OK) {
goto procError;
}
if (fieldCount > 2) {
- ckfree(fieldValues);
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "too many fields in argument specifier \"%s\"",
- argArray[i]));
+ errorObj = Tcl_NewStringObj(
+ "too many fields in argument specifier \"", -1);
+ Tcl_AppendObjToObj(errorObj, argArray[i]);
+ Tcl_AppendToObj(errorObj, "\"", -1);
+ Tcl_SetObjResult(interp, errorObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
- if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
- ckfree(fieldValues);
+ if ((fieldCount == 0) || (fieldValues[0]->length == 0)) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"argument with no name", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
@@ -530,9 +504,11 @@ TclCreateProc(
goto procError;
}
- nameLength = strlen(fieldValues[0]);
+ argname = Tcl_GetStringFromObj(fieldValues[0], &plen);
+ nameLength = Tcl_NumUtfChars(argname, plen);
if (fieldCount == 2) {
- valueLength = strlen(fieldValues[1]);
+ const char * value = TclGetString(fieldValues[1]);
+ valueLength = Tcl_NumUtfChars(value, fieldValues[1]->length);
} else {
valueLength = 0;
}
@@ -541,33 +517,28 @@ TclCreateProc(
* Check that the formal parameter name is a scalar.
*/
- p = fieldValues[0];
- while (*p != '\0') {
- if (*p == '(') {
- const char *q = p;
- do {
- q++;
- } while (*q != '\0');
- q--;
- if (*q == ')') { /* We have an array element. */
+ argnamei = argname;
+ argnamelast = argname[plen-1];
+ while (plen--) {
+ if (argnamei[0] == '(') {
+ if (argnamelast == ')') { /* We have an array element. */
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"formal parameter \"%s\" is an array element",
- fieldValues[0]));
- ckfree(fieldValues);
+ Tcl_GetString(fieldValues[0])));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
- } else if ((*p == ':') && (*(p+1) == ':')) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "formal parameter \"%s\" is not a simple name",
- fieldValues[0]));
- ckfree(fieldValues);
+ } else if ((argnamei[0] == ':') && (argnamei[1] == ':')) {
+ errorObj = Tcl_NewStringObj("formal parameter \"", -1);
+ Tcl_AppendObjToObj(errorObj, fieldValues[0]);
+ Tcl_AppendToObj(errorObj, "\" is not a simple name", -1);
+ Tcl_SetObjResult(interp, errorObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"FORMALARGUMENTFORMAT", NULL);
goto procError;
}
- p++;
+ argnamei = Tcl_UtfNext(argnamei);
}
if (precompiled) {
@@ -583,7 +554,7 @@ TclCreateProc(
*/
if ((localPtr->nameLength != nameLength)
- || (strcmp(localPtr->name, fieldValues[0]))
+ || (Tcl_UtfNcmp(localPtr->name, argname, nameLength))
|| (localPtr->frameIndex != i)
|| !(localPtr->flags & VAR_ARGUMENT)
|| (localPtr->defValuePtr == NULL && fieldCount == 2)
@@ -591,7 +562,6 @@ TclCreateProc(
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"procedure \"%s\": formal parameter %d is "
"inconsistent with precompiled body", procName, i));
- ckfree(fieldValues);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"BYTECODELIES", NULL);
goto procError;
@@ -607,12 +577,13 @@ TclCreateProc(
&tmpLength);
if ((valueLength != tmpLength) ||
- strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "procedure \"%s\": formal parameter \"%s\" has "
- "default value inconsistent with precompiled body",
- procName, fieldValues[0]));
- ckfree(fieldValues);
+ Tcl_UtfNcmp(Tcl_GetString(fieldValues[1]), tmpPtr, tmpLength)) {
+ errorObj = Tcl_ObjPrintf(
+ "procedure \"%s\": formal parameter \"" ,procName);
+ Tcl_AppendObjToObj(errorObj, fieldValues[0]);
+ Tcl_AppendToObj(errorObj, "\" has "
+ "default value inconsistent with precompiled body", -1);
+ Tcl_SetObjResult(interp, errorObj);
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
"BYTECODELIES", NULL);
goto procError;
@@ -632,7 +603,7 @@ TclCreateProc(
* local variables for the argument.
*/
- localPtr = ckalloc(TclOffset(CompiledLocal, name) + nameLength+1);
+ localPtr = ckalloc(TclOffset(CompiledLocal, name) + fieldValues[0]->length +1);
if (procPtr->firstLocalPtr == NULL) {
procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
} else {
@@ -646,13 +617,12 @@ TclCreateProc(
localPtr->resolveInfo = NULL;
if (fieldCount == 2) {
- localPtr->defValuePtr =
- Tcl_NewStringObj(fieldValues[1], valueLength);
+ localPtr->defValuePtr = fieldValues[1];
Tcl_IncrRefCount(localPtr->defValuePtr);
} else {
localPtr->defValuePtr = NULL;
}
- memcpy(localPtr->name, fieldValues[0], nameLength + 1);
+ memcpy(localPtr->name, argname, fieldValues[0]->length + 1);
if ((i == numArgs - 1)
&& (localPtr->nameLength == 4)
&& (localPtr->name[0] == 'a')
@@ -660,12 +630,9 @@ TclCreateProc(
localPtr->flags |= VAR_IS_ARGS;
}
}
-
- ckfree(fieldValues);
}
*procPtrPtr = procPtr;
- ckfree(argArray);
return TCL_OK;
procError:
@@ -686,9 +653,6 @@ TclCreateProc(
}
ckfree(procPtr);
}
- if (argArray != NULL) {
- ckfree(argArray);
- }
return TCL_ERROR;
}
@@ -1071,7 +1035,6 @@ ProcWrongNumArgs(
{
CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
register Proc *procPtr = framePtr->procPtr;
- register Var *defPtr;
int localCt = procPtr->numCompiledLocals, numArgs, i;
Tcl_Obj **desiredObjs;
const char *final = NULL;
@@ -1095,23 +1058,26 @@ ProcWrongNumArgs(
}
Tcl_IncrRefCount(desiredObjs[0]);
- defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt);
- for (i=1 ; i<=numArgs ; i++, defPtr++) {
- Tcl_Obj *argObj;
- Tcl_Obj *namePtr = localName(framePtr, i-1);
-
- if (defPtr->value.objPtr != NULL) {
- TclNewObj(argObj);
- Tcl_AppendStringsToObj(argObj, "?", TclGetString(namePtr), "?", NULL);
- } else if (defPtr->flags & VAR_IS_ARGS) {
- numArgs--;
- final = "?arg ...?";
- break;
- } else {
- argObj = namePtr;
- Tcl_IncrRefCount(namePtr);
+ if (localCt > 0) {
+ register Var *defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt);
+
+ for (i=1 ; i<=numArgs ; i++, defPtr++) {
+ Tcl_Obj *argObj;
+ Tcl_Obj *namePtr = localName(framePtr, i-1);
+
+ if (defPtr->value.objPtr != NULL) {
+ TclNewObj(argObj);
+ Tcl_AppendStringsToObj(argObj, "?", TclGetString(namePtr), "?", NULL);
+ } else if (defPtr->flags & VAR_IS_ARGS) {
+ numArgs--;
+ final = "?arg ...?";
+ break;
+ } else {
+ argObj = namePtr;
+ Tcl_IncrRefCount(namePtr);
+ }
+ desiredObjs[i] = argObj;
}
- desiredObjs[i] = argObj;
}
Tcl_ResetResult(interp);
diff --git a/tcl8.6/generic/tclStringObj.c b/tcl8.6/generic/tclStringObj.c
index 0f238cf..493378c 100644
--- a/tcl8.6/generic/tclStringObj.c
+++ b/tcl8.6/generic/tclStringObj.c
@@ -434,6 +434,7 @@ Tcl_GetCharLength(
return length;
}
+
/*
* OK, need to work with the object as a string.
*/
@@ -464,6 +465,50 @@ Tcl_GetCharLength(
}
return numChars;
}
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCheckEmptyString --
+ *
+ * Determine whether the string value of an object is or would be the
+ * empty string, without generating a string representation.
+ *
+ * Results:
+ * Returns 1 if empty, 0 if not, and -1 if unknown.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+TclCheckEmptyString (
+ Tcl_Obj *objPtr
+) {
+ int length = -1;
+
+ if (objPtr->bytes == tclEmptyStringRep) {
+ return TCL_EMPTYSTRING_YES;
+ }
+
+ if (TclIsPureList(objPtr)) {
+ Tcl_ListObjLength(NULL, objPtr, &length);
+ return length == 0;
+ }
+
+ if (TclIsPureDict(objPtr)) {
+ Tcl_DictObjSize(NULL, objPtr, &length);
+ return length == 0;
+ }
+
+ if (objPtr->bytes == NULL) {
+ return TCL_EMPTYSTRING_UNKNOWN;
+ }
+ return objPtr->length == 0;
+}
/*
*----------------------------------------------------------------------
@@ -533,7 +578,7 @@ Tcl_GetUniChar(
*
* Get the Unicode form of the String object. If the object is not
* already a String object, it will be converted to one. If the String
- * object does not have a Unicode rep, then one is create from the UTF
+ * object does not have a Unicode rep, then one is created from the UTF
* string format.
*
* Results:
@@ -667,6 +712,17 @@ Tcl_GetRange(
stringPtr = GET_STRING(objPtr);
}
+#if TCL_UTF_MAX == 4
+ /* See: bug [11ae2be95dac9417] */
+ if ((first>0) && ((stringPtr->unicode[first]&0xFC00) == 0xDC00)
+ && ((stringPtr->unicode[first-1]&0xFC00) == 0xD800)) {
+ ++first;
+ }
+ if ((last+1<stringPtr->numChars) && ((stringPtr->unicode[last+1]&0xFC00) == 0xDC00)
+ && ((stringPtr->unicode[last]&0xFC00) == 0xD800)) {
+ ++last;
+ }
+#endif
return Tcl_NewUnicodeObj(stringPtr->unicode + first, last-first+1);
}
@@ -1820,6 +1876,11 @@ Tcl_AppendFormatToObj(
width = 0;
if (isdigit(UCHAR(ch))) {
width = strtoul(format, &end, 10);
+ if (width < 0) {
+ msg = overflow;
+ errCode = "OVERFLOW";
+ goto errorMsg;
+ }
format = end;
step = TclUtfToUniChar(format, &ch);
} else if (ch == '*') {
@@ -1940,6 +2001,12 @@ Tcl_AppendFormatToObj(
goto error;
}
length = Tcl_UniCharToUtf(code, buf);
+#if TCL_UTF_MAX > 3
+ if (!length) {
+ /* Special case for handling upper surrogates. */
+ length = Tcl_UniCharToUtf(-1, buf);
+ }
+#endif
segment = Tcl_NewStringObj(buf, length);
Tcl_IncrRefCount(segment);
allocSegment = 1;
diff --git a/tcl8.6/generic/tclStubInit.c b/tcl8.6/generic/tclStubInit.c
index b185f04..cbf4084 100644
--- a/tcl8.6/generic/tclStubInit.c
+++ b/tcl8.6/generic/tclStubInit.c
@@ -12,6 +12,10 @@
#include "tclInt.h"
#include "tommath.h"
+#ifdef __CYGWIN__
+# include <wchar.h>
+#endif
+
#ifdef __GNUC__
#pragma GCC dependency "tcl.decls"
#pragma GCC dependency "tclInt.decls"
@@ -106,8 +110,6 @@ static unsigned short TclWinNToHS(unsigned short ns) {
# define TclWinFlushDirtyChannels doNothing
# define TclWinResetInterfaces doNothing
-static Tcl_Encoding winTCharEncoding;
-
static int
TclpIsAtty(int fd)
{
@@ -127,7 +129,7 @@ void *TclWinGetTclInstance()
{
void *hInstance = NULL;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- (const char *)&winTCharEncoding, &hInstance);
+ (const char *)&TclpIsAtty, &hInstance);
return hInstance;
}
@@ -186,11 +188,11 @@ Tcl_WinUtfToTChar(
int len,
Tcl_DString *dsPtr)
{
- if (!winTCharEncoding) {
- winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+ Tcl_DStringInit(dsPtr);
+ if (!string) {
+ return NULL;
}
- return Tcl_UtfToExternalDString(winTCharEncoding,
- string, len, dsPtr);
+ return (char *)Tcl_UtfToUniCharDString(string, len, dsPtr);
}
char *
@@ -199,11 +201,16 @@ Tcl_WinTCharToUtf(
int len,
Tcl_DString *dsPtr)
{
- if (!winTCharEncoding) {
- winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+ Tcl_DStringInit(dsPtr);
+ if (!string) {
+ return NULL;
+ }
+ if (len < 0) {
+ len = wcslen((wchar_t *)string);
+ } else {
+ len /= 2;
}
- return Tcl_ExternalToUtfDString(winTCharEncoding,
- string, len, dsPtr);
+ return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr);
}
#if defined(TCL_WIDE_INT_IS_LONG)
diff --git a/tcl8.6/generic/tclTest.c b/tcl8.6/generic/tclTest.c
index 8a59b83..45cca5a 100644
--- a/tcl8.6/generic/tclTest.c
+++ b/tcl8.6/generic/tclTest.c
@@ -5234,7 +5234,7 @@ TestmainthreadCmd(
const char **argv) /* Argument strings. */
{
if (argc == 1) {
- Tcl_Obj *idObj = Tcl_NewLongObj((long)(size_t)Tcl_GetCurrentThread());
+ Tcl_Obj *idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
Tcl_SetObjResult(interp, idObj);
return TCL_OK;
@@ -5631,8 +5631,8 @@ TestChannelCmd(
return TCL_ERROR;
}
- TclFormatInt(buf, (size_t) Tcl_GetChannelThread(chan));
- Tcl_AppendResult(interp, buf, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
+ (Tcl_WideInt) (size_t) Tcl_GetChannelThread(chan)));
return TCL_OK;
}
diff --git a/tcl8.6/generic/tclThreadTest.c b/tcl8.6/generic/tclThreadTest.c
index fcf3880..35b3fc3 100644
--- a/tcl8.6/generic/tclThreadTest.c
+++ b/tcl8.6/generic/tclThreadTest.c
@@ -174,7 +174,6 @@ TclThread_Init(
Tcl_CreateObjCommand(interp, "testthread", ThreadObjCmd, NULL, NULL);
return TCL_OK;
}
-
/*
*----------------------------------------------------------------------
@@ -248,7 +247,7 @@ ThreadObjCmd(
switch ((enum options)option) {
case THREAD_CANCEL: {
- long id;
+ Tcl_WideInt id;
const char *result;
int flags, arg;
@@ -264,7 +263,7 @@ ThreadObjCmd(
arg++;
}
}
- if (Tcl_GetLongFromObj(interp, objv[arg], &id) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
return TCL_ERROR;
}
arg++;
@@ -1158,6 +1157,14 @@ ThreadExitProc(
Tcl_MutexLock(&threadMutex);
+ if (self == errorThreadId) {
+ if (errorProcString) { /* Extra safety */
+ ckfree(errorProcString);
+ errorProcString = NULL;
+ }
+ errorThreadId = 0;
+ }
+
if (threadEvalScript) {
ckfree(threadEvalScript);
threadEvalScript = NULL;
diff --git a/tcl8.6/generic/tclTrace.c b/tcl8.6/generic/tclTrace.c
index 4e74c54..d48761b 100644
--- a/tcl8.6/generic/tclTrace.c
+++ b/tcl8.6/generic/tclTrace.c
@@ -191,8 +191,10 @@ Tcl_TraceObjCmd(
Tcl_Obj *const objv[]) /* Argument objects. */
{
int optionIndex;
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
const char *name;
const char *flagOps, *p;
+#endif
/* Main sub commands to 'trace' */
static const char *const traceOptions[] = {
"add", "info", "remove",
@@ -365,12 +367,14 @@ Tcl_TraceObjCmd(
}
return TCL_OK;
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
badVarOps:
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"bad operations \"%s\": should be one or more of rwua",
flagOps));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "BADOPS", NULL);
return TCL_ERROR;
+#endif
}
/*
@@ -912,9 +916,11 @@ TraceVariableObjCmd(
+ 1 + length);
ctvarPtr->traceCmdInfo.flags = flags;
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
if (objv[0] == NULL) {
ctvarPtr->traceCmdInfo.flags |= TCL_TRACE_OLD_STYLE;
}
+#endif
ctvarPtr->traceCmdInfo.length = length;
flags |= TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT;
memcpy(ctvarPtr->traceCmdInfo.command, command, length+1);
@@ -939,7 +945,11 @@ TraceVariableObjCmd(
TraceVarInfo *tvarPtr = clientData;
if ((tvarPtr->length == length)
- && ((tvarPtr->flags & ~TCL_TRACE_OLD_STYLE)==flags)
+ && ((tvarPtr->flags
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+& ~TCL_TRACE_OLD_STYLE
+#endif
+ )==flags)
&& (strncmp(command, tvarPtr->command,
(size_t) length) == 0)) {
Tcl_UntraceVar2(interp, name, NULL,
@@ -2468,6 +2478,47 @@ TclVarTraceExists(
/*
*----------------------------------------------------------------------
*
+ * TclCheckArrayTraces --
+ *
+ * This function is invoked to when we operate on an array variable,
+ * to allow any array traces to fire.
+ *
+ * Results:
+ * Returns TCL_OK to indicate normal operation. Returns TCL_ERROR if
+ * invocation of a trace function indicated an error. When TCL_ERROR is
+ * returned, then error information is left in interp.
+ *
+ * Side effects:
+ * Almost anything can happen, depending on trace; this function itself
+ * doesn't have any side effects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCheckArrayTraces(
+ Tcl_Interp *interp,
+ Var *varPtr,
+ Var *arrayPtr,
+ Tcl_Obj *name,
+ int index)
+{
+ int code = TCL_OK;
+
+ if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+ && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+ Interp *iPtr = (Interp *)interp;
+
+ code = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, name, NULL,
+ (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY| TCL_TRACE_ARRAY),
+ /* leaveErrMsg */ 1, index);
+ }
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclCallVarTraces --
*
* This function is invoked to find and invoke relevant trace functions
diff --git a/tcl8.6/generic/tclUniData.c b/tcl8.6/generic/tclUniData.c
index 9f05230..faca93d 100644
--- a/tcl8.6/generic/tclUniData.c
+++ b/tcl8.6/generic/tclUniData.c
@@ -42,22 +42,22 @@ static const unsigned short pageMap[] = {
4384, 4416, 1344, 4448, 4480, 4512, 4544, 1344, 4576, 4608, 4640, 4672,
1344, 4704, 4736, 4768, 4800, 4832, 1344, 4864, 4896, 4928, 4960, 1344,
4992, 5024, 5056, 5088, 1824, 1824, 5120, 5152, 5184, 5216, 5248, 5280,
- 1344, 5312, 1344, 5344, 5376, 5408, 5440, 1824, 5472, 5504, 5536, 5568,
- 5600, 5632, 5664, 5600, 704, 5696, 224, 224, 224, 224, 5728, 224, 224,
- 224, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080,
- 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, 6464,
- 6496, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6560, 6592, 4928,
- 6624, 6656, 6688, 6720, 6752, 4928, 6784, 6816, 6848, 6880, 6912, 6944,
- 6976, 4928, 4928, 4928, 4928, 4928, 7008, 7040, 7072, 4928, 4928, 4928,
- 7104, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7136, 7168, 4928, 7200,
- 7232, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 6528, 6528, 6528,
- 6528, 7264, 6528, 7296, 7328, 6528, 6528, 6528, 6528, 6528, 6528, 6528,
- 6528, 4928, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616, 7648,
+ 1344, 5312, 1344, 5344, 5376, 5408, 5440, 5472, 5504, 5536, 5568, 5600,
+ 5632, 5664, 5696, 5632, 704, 5728, 224, 224, 224, 224, 5760, 224, 224,
+ 224, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, 6112,
+ 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, 6464, 6496,
+ 6528, 6560, 6560, 6560, 6560, 6560, 6560, 6560, 6560, 6592, 6624, 4928,
+ 6656, 6688, 6720, 6752, 6784, 4928, 6816, 6848, 6880, 6912, 6944, 6976,
+ 7008, 4928, 4928, 4928, 4928, 4928, 7040, 7072, 7104, 4928, 4928, 4928,
+ 7136, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7168, 7200, 4928, 7232,
+ 7264, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 6560, 6560, 6560,
+ 6560, 7296, 6560, 7328, 7360, 6560, 6560, 6560, 6560, 6560, 6560, 6560,
+ 6560, 4928, 7392, 7424, 7456, 7488, 4928, 7520, 7552, 7584, 7616, 7648,
7680, 224, 224, 224, 7712, 7744, 7776, 1344, 7808, 7840, 7872, 7872,
704, 7904, 7936, 7968, 1824, 8000, 4928, 4928, 8032, 4928, 4928, 4928,
4928, 4928, 4928, 8064, 8096, 8128, 8160, 3232, 1344, 8192, 4192, 1344,
- 8224, 8256, 8288, 1344, 1344, 8320, 8352, 4928, 8384, 8416, 8448, 8480,
- 4928, 8448, 8512, 4928, 8416, 4928, 4928, 4928, 4928, 4928, 4928, 4928,
+ 8224, 8256, 8288, 1344, 1344, 8320, 8352, 4928, 8384, 7552, 8416, 8448,
+ 4928, 8416, 8480, 4928, 7552, 4928, 4928, 4928, 4928, 4928, 4928, 4928,
4928, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -130,7 +130,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,
- 1792, 8544, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 8512, 8544, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 8576, 4928, 8608, 5408, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -203,37 +203,37 @@ static const unsigned short pageMap[] = {
1344, 11520, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 7840, 4704, 10272, 1824, 1824, 1824, 1824,
11552, 11584, 11616, 11648, 4736, 11680, 1824, 11712, 11744, 11776,
- 1824, 1824, 1344, 11808, 11840, 6848, 11872, 11904, 11936, 11968, 12000,
+ 1824, 1824, 1344, 11808, 11840, 6880, 11872, 11904, 11936, 11968, 12000,
1824, 12032, 12064, 1344, 12096, 12128, 12160, 12192, 12224, 1824,
- 1824, 1344, 1344, 12256, 1824, 12288, 12320, 12352, 12384, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12416, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12448,
- 12480, 12512, 12544, 5248, 12576, 12608, 12640, 12672, 12704, 12736,
- 12768, 5248, 12800, 12832, 12864, 12896, 12928, 1824, 1824, 12960,
- 12992, 13024, 13056, 13088, 2368, 13120, 13152, 1824, 1824, 1824, 1824,
- 1344, 13184, 13216, 1824, 1344, 13248, 13280, 1824, 1824, 1824, 1824,
- 1824, 1344, 13312, 13344, 1824, 1344, 13376, 13408, 13440, 1344, 13472,
- 13504, 1824, 13536, 13568, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 13600, 13632, 13664, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 13696, 13728, 13760, 1344, 13792, 13824, 1344,
- 13856, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 13888, 13920,
- 13952, 13984, 14016, 14048, 1824, 1824, 14080, 14112, 14144, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344,
+ 1824, 1344, 1344, 12256, 1824, 12288, 12320, 12352, 12384, 1344, 12416,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12448, 1824,
+ 1824, 1824, 1824, 12000, 12480, 12512, 1824, 1824, 1824, 1824, 1824,
+ 12544, 12576, 12608, 12640, 5248, 12672, 12704, 12736, 12768, 12800,
+ 12832, 12864, 5248, 12896, 12928, 12960, 12992, 13024, 1824, 1824,
+ 13056, 13088, 13120, 13152, 13184, 13216, 13248, 13280, 1824, 1824,
+ 1824, 1824, 1344, 13312, 13344, 1824, 1344, 13376, 13408, 1824, 1824,
+ 1824, 1824, 1824, 1344, 13440, 13472, 1824, 1344, 13504, 13536, 13568,
+ 1344, 13600, 13632, 1824, 4032, 13664, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1344, 13696, 1824, 1824, 1824, 13728, 13760, 13792, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 13824, 13856, 13888, 1344, 13920,
+ 13952, 1344, 4608, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 13984, 14016, 14048, 14080, 14112, 14144, 1824, 1824, 14176, 14208,
+ 14240, 14272, 14304, 13632, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 14336, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 9984, 1824, 1824, 1824, 10848, 10848, 10848, 14176, 1344, 1344, 1344,
- 1344, 1344, 1344, 14208, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1344, 1344, 1344, 1344, 9984, 1824, 1824, 1824, 10848, 10848, 10848,
+ 14368, 1344, 1344, 1344, 1344, 1344, 1344, 14400, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 14240, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14432, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
@@ -243,10 +243,9 @@ static const unsigned short pageMap[] = {
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 14272, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14464, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
@@ -268,12 +267,13 @@ static const unsigned short pageMap[] = {
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 13856, 4736, 14304, 1824, 1824, 10208,
- 14336, 1344, 14368, 14400, 14432, 14464, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344,
- 14496, 14528, 14560, 1824, 1824, 14592, 1344, 1344, 1344, 1344, 1344,
+ 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4608, 4736, 14496,
+ 1824, 1824, 10208, 14528, 1344, 14560, 14592, 14624, 8512, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 13728, 13760, 14656, 1824,
+ 1824, 1824, 1344, 1344, 14688, 14720, 14752, 1824, 1824, 14784, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -289,9 +289,9 @@ 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, 14624, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14816,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14656, 1824, 1824, 1824,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14848,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
@@ -316,17 +316,16 @@ static const unsigned short pageMap[] = {
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 4736, 1824, 1824, 10208, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 9856, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 4736, 1824, 1824, 10208, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9856, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 14688, 14720,
- 14752, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344,
+ 14880, 14912, 14944, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
@@ -338,41 +337,42 @@ static const unsigned short pageMap[] = {
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 4928, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 4928, 14784, 4928,
- 14816, 14848, 14880, 4928, 14912, 4928, 4928, 14944, 1824, 1824, 1824,
- 1824, 1824, 4928, 4928, 14976, 15008, 1824, 1824, 1824, 1824, 15040,
- 15072, 15104, 15136, 15168, 15200, 15232, 15264, 15296, 15328, 15360,
- 15392, 15424, 15040, 15072, 15456, 15136, 15488, 15520, 15552, 15264,
- 15584, 15616, 15648, 15680, 15712, 15744, 15776, 15808, 15840, 15872,
- 15904, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928,
- 4928, 4928, 4928, 4928, 4928, 4928, 704, 15936, 704, 15968, 16000,
- 16032, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 4928, 14976,
+ 4928, 15008, 15040, 15072, 4928, 15104, 4928, 4928, 15136, 1824, 1824,
+ 1824, 1824, 15168, 4928, 4928, 15200, 15232, 1824, 1824, 1824, 1824,
+ 15264, 15296, 15328, 15360, 15392, 15424, 15456, 15488, 15520, 15552,
+ 15584, 15616, 15648, 15264, 15296, 15680, 15360, 15712, 15744, 15776,
+ 15488, 15808, 15840, 15872, 15904, 15936, 15968, 16000, 16032, 16064,
+ 16096, 16128, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928,
+ 4928, 4928, 4928, 4928, 4928, 4928, 4928, 704, 16160, 704, 16192, 16224,
+ 16256, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 16064, 16096, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 16288, 16320, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1344, 1344, 1344, 1344, 1344, 1344, 16128, 1824, 16160, 16192,
- 16224, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1344, 1344, 1344, 1344, 1344, 1344, 16352, 1824, 16384, 16416,
+ 16448, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 16256, 16288, 16320, 16352, 16384, 16416, 1824, 16448,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 4928, 16480, 4928,
- 4928, 8032, 16512, 16544, 8064, 16576, 16608, 4928, 16480, 4928, 16640,
- 1824, 16672, 16704, 16736, 16768, 16800, 1824, 1824, 1824, 1824, 4928,
- 4928, 4928, 4928, 4928, 4928, 4928, 16832, 4928, 4928, 4928, 4928,
+ 1824, 1824, 16480, 6880, 16512, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1824, 1824, 1824, 1824, 16544, 16576, 16608, 16640, 16672, 16704, 1824,
+ 16736, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 4928, 16768,
+ 4928, 4928, 8032, 16800, 16832, 8064, 16864, 4928, 4928, 16768, 4928,
+ 16896, 1824, 16928, 16960, 16992, 17024, 17056, 1824, 1824, 1824, 1824,
+ 4928, 4928, 4928, 4928, 4928, 4928, 4928, 17088, 4928, 4928, 4928,
4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928,
- 4928, 4928, 4928, 4928, 4928, 4928, 16864, 16896, 4928, 4928, 4928,
- 8032, 4928, 4928, 16864, 1824, 16480, 4928, 16928, 4928, 16960, 16992,
- 1824, 1824, 16480, 8416, 17024, 17056, 17088, 1824, 17120, 6784, 1824,
+ 4928, 4928, 4928, 4928, 4928, 4928, 4928, 17120, 17152, 4928, 4928,
+ 4928, 8032, 4928, 4928, 17184, 1824, 16768, 4928, 17216, 4928, 17248,
+ 17280, 1824, 1824, 16768, 7552, 4928, 17312, 4928, 17344, 16960, 4928,
+ 1824, 1824, 1824, 17280, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -483,7 +483,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, 7840, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 7840, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -494,7 +494,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,
- 17152, 1344, 1344, 1344, 1344, 1344, 1344, 11360, 1344, 1344, 1344,
+ 1344, 1344, 17376, 1344, 1344, 1344, 1344, 1344, 1344, 11360, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -509,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, 17184, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 17408,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
@@ -529,7 +529,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, 17216, 1824, 1824, 1824, 1824, 1824, 1824,
+ 1344, 1344, 1344, 1344, 1344, 17440, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
@@ -537,8 +537,8 @@ static const unsigned short pageMap[] = {
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824,
- 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11360
+ 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344,
+ 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11360
#endif /* TCL_UTF_MAX > 3 */
};
@@ -616,100 +616,100 @@ static const unsigned char groupMap[] = {
23, 24, 23, 24, 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,
- 0, 0, 91, 3, 3, 3, 3, 3, 3, 0, 123, 123, 123, 123, 123, 123, 123, 123,
+ 0, 0, 91, 3, 3, 3, 3, 3, 3, 21, 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, 21, 0, 3, 8, 0, 0, 14, 14, 4, 0, 92, 92, 92, 92, 92, 92,
+ 123, 123, 123, 21, 21, 3, 8, 0, 0, 14, 14, 4, 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, 8, 92, 3, 92, 92, 3, 92, 92, 3, 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, 15, 0, 0, 0, 0, 0,
- 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17,
- 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 92, 92, 3, 17, 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, 15, 15, 91, 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, 92, 92,
- 92, 92, 92, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 92,
+ 92, 92, 92, 92, 92, 92, 8, 92, 3, 92, 92, 3, 92, 92, 3, 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, 15, 0, 0, 0, 0,
+ 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17,
+ 17, 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 3, 17, 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, 15, 15, 91, 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, 92,
+ 92, 92, 92, 92, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 3, 15, 92, 92, 92, 92, 92, 92, 92, 17, 14, 92, 92, 92, 92, 92,
- 92, 91, 91, 92, 92, 14, 92, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 0, 17, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 3, 15, 92, 92, 92, 92, 92, 92, 92, 17, 14, 92, 92, 92, 92,
+ 92, 92, 91, 91, 92, 92, 14, 92, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 0, 17, 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, 15, 15, 15, 15,
- 15, 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, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 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, 0, 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, 15, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15,
+ 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 91, 91, 14, 3, 3, 3, 91, 0, 0, 0, 0, 0,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 14, 3, 3, 3, 91, 0, 0,
+ 92, 4, 4, 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, 91, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 92, 92, 92, 92, 91, 92, 92, 92, 92, 92, 92, 92,
- 92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 92,
- 92, 92, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0,
+ 15, 92, 92, 92, 0, 0, 3, 0, 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, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 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, 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,
+ 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, 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, 92, 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, 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, 15, 3, 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,
+ 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, 15, 3, 92,
+ 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, 3, 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, 92, 92, 92, 92, 92, 92, 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, 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, 92, 92, 92, 92, 92, 92, 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,
+ 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,
+ 0, 0, 0, 0, 92, 124, 124, 124, 92, 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,
+ 18, 18, 14, 15, 92, 124, 124, 3, 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,
@@ -764,353 +764,355 @@ static const unsigned char groupMap[] = {
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, 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, 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, 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, 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, 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, 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,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 3, 91, 126, 126, 126, 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, 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, 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, 92, 15, 0, 0, 0, 0, 0, 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, 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, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 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, 128, 128, 128, 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,
- 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 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, 92, 92, 124, 124, 92, 0, 0, 3, 3, 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, 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, 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, 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, 124, 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,
+ 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, 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, 129, 130, 131, 132, 132, 133, 134, 135, 136,
+ 0, 0, 0, 0, 0, 0, 0, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 0, 0, 137, 137, 137, 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, 124, 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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 21, 21, 21, 21, 21, 21, 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, 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, 92, 92, 92, 92, 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, 4, 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,
+ 91, 91, 91, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 91, 138, 21, 21, 21, 139, 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, 92, 92, 92,
+ 92, 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,
+ 140, 21, 21, 141, 21, 142, 142, 142, 142, 142, 142, 142, 142, 143,
+ 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 0,
+ 0, 143, 143, 143, 143, 143, 143, 0, 0, 142, 142, 142, 142, 142, 142,
+ 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142,
+ 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142,
+ 142, 142, 142, 142, 0, 0, 143, 143, 143, 143, 143, 143, 0, 0, 21, 142,
+ 21, 142, 21, 142, 21, 142, 0, 143, 0, 143, 0, 143, 0, 143, 142, 142,
+ 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143,
+ 144, 144, 145, 145, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
+ 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 150, 150, 150, 150, 150,
+ 150, 150, 150, 142, 142, 142, 142, 142, 142, 142, 142, 150, 150, 150,
+ 150, 150, 150, 150, 150, 142, 142, 142, 142, 142, 142, 142, 142, 150,
+ 150, 150, 150, 150, 150, 150, 150, 142, 142, 21, 151, 21, 0, 21, 21,
+ 143, 143, 152, 152, 153, 11, 154, 11, 11, 11, 21, 151, 21, 0, 21, 21,
+ 155, 155, 155, 155, 153, 11, 11, 11, 142, 142, 21, 21, 0, 0, 21, 21,
+ 143, 143, 156, 156, 0, 11, 11, 11, 142, 142, 21, 21, 21, 113, 21, 21,
+ 143, 143, 157, 157, 117, 11, 11, 11, 0, 0, 21, 151, 21, 0, 21, 21,
+ 158, 158, 159, 159, 153, 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, 160, 161, 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,
+ 4, 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, 162, 14,
+ 107, 14, 163, 164, 107, 107, 14, 21, 107, 107, 165, 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, 166, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 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, 128, 128, 128, 23, 24,
+ 128, 128, 128, 128, 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, 14, 14, 14, 14, 7, 7, 14, 14, 7, 14, 7, 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, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7,
+ 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, 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,
+ 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7,
+ 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, 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, 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, 7, 7, 7, 7, 7, 7, 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, 0, 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,
+ 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, 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,
+ 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, 14, 14,
+ 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, 14, 14, 14, 14, 14, 14, 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,
+ 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+ 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 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, 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, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18,
+ 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, 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, 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, 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,
- 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,
+ 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, 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, 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,
+ 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, 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, 14, 14, 14, 14, 14, 14, 0, 0, 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, 14, 14, 14, 14, 14, 14, 0, 0, 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, 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, 0, 0, 0, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 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, 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,
+ 14, 14, 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, 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, 123, 123, 123,
+ 122, 122, 122, 122, 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, 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, 3, 3, 3, 3, 3, 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,
+ 123, 123, 123, 123, 123, 0, 23, 24, 171, 172, 173, 174, 175, 23, 24,
+ 23, 24, 23, 24, 176, 177, 178, 179, 21, 23, 24, 21, 23, 24, 21, 21,
+ 21, 21, 21, 91, 91, 180, 180, 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, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
+ 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 0, 181,
+ 0, 0, 0, 0, 0, 181, 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, 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, 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,
+ 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, 128, 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, 128, 128, 128, 128, 128, 128, 128, 128, 128, 92,
+ 92, 92, 92, 124, 124, 8, 91, 91, 91, 91, 91, 14, 14, 128, 128, 128,
+ 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, 15, 15, 15, 15, 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, 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+ 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, 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, 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, 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, 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, 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, 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, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 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, 182, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 11, 11, 23,
+ 24, 183, 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, 184, 185, 186,
+ 187, 184, 21, 188, 189, 190, 191, 23, 24, 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, 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,
- 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,
- 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,
+ 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, 15, 92, 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,
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, 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,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 192, 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, 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, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 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, 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, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, 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,
@@ -1160,10 +1162,10 @@ static const unsigned char groupMap[] = {
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, 0, 0, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 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, 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,
+ 14, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 18,
18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
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,
@@ -1176,29 +1178,29 @@ static const unsigned char groupMap[] = {
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, 0, 0, 0, 18, 18, 18, 18,
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, 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, 128, 15, 15, 15, 15, 15, 15,
+ 15, 15, 128, 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, 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, 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,
+ 3, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 128,
+ 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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,
+ 197, 197, 197, 197, 197, 197, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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,
+ 15, 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 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, 196, 196, 0, 0, 0, 0, 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, 197, 197, 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,
@@ -1222,304 +1224,316 @@ static const unsigned char groupMap[] = {
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, 0, 0, 92, 92, 92, 0, 0,
+ 0, 0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 18, 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, 18, 18, 3, 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, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 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, 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, 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18,
+ 15, 15, 15, 15, 92, 92, 92, 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, 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,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 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, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 18, 18, 18, 18, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 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,
- 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, 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, 17, 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,
- 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, 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, 15, 124, 124, 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, 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, 92, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 92, 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, 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, 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,
+ 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,
- 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, 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, 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, 92, 92, 15, 124, 124, 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, 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,
+ 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, 92, 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, 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, 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, 92, 92, 3,
+ 0, 0, 0, 0, 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,
- 10, 10, 10, 10, 10, 10, 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, 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, 92, 92, 92, 92, 92, 92, 124, 124, 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, 92, 92, 92, 92, 92, 92, 124, 15, 92, 92, 92, 92, 3,
- 3, 3, 3, 3, 3, 3, 3, 92, 0, 0, 0, 0, 0, 0, 0, 0, 15, 92, 92, 92, 92,
- 92, 92, 124, 124, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0,
- 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
- 124, 92, 92, 3, 3, 3, 0, 3, 3, 3, 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, 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, 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, 92,
- 92, 92, 92, 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, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 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, 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, 92, 92, 92, 92, 92, 92, 92, 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, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 15, 92,
+ 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 92, 0, 0, 0, 0, 0, 0, 0, 0, 15,
+ 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 92, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 0, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 124, 92, 92, 3, 3, 3, 15, 3, 3, 3, 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, 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, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 0, 92, 92, 0, 92,
- 92, 92, 92, 92, 92, 92, 15, 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, 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, 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92,
+ 92, 92, 92, 92, 0, 92, 92, 92, 92, 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, 15, 15, 15, 15, 15,
+ 15, 15, 0, 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, 92, 92, 92, 92, 92, 92, 0, 0, 0,
+ 92, 0, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 15, 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, 15, 15, 15,
+ 15, 15, 15, 0, 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, 124, 124, 124, 124, 124, 0, 92, 92, 0, 124, 124, 92,
+ 124, 92, 15, 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, 92, 92, 124, 124, 3, 3, 0,
+ 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 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,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 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, 91, 91, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 14, 92, 92, 92, 92, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 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, 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, 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, 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, 107, 107, 107, 21, 21, 21, 21, 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, 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, 0, 107, 107, 107, 107,
- 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 0, 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, 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,
+ 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, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 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,
+ 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, 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,
+ 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, 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, 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, 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,
+ 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, 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, 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, 107, 7, 21, 21, 21, 21,
+ 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, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107,
+ 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, 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,
+ 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, 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, 9, 9, 92, 92, 92, 92,
+ 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, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 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, 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,
+ 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, 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 199, 199,
+ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
+ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
+ 199, 199, 199, 199, 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, 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, 14,
+ 18, 18, 18, 4, 18, 18, 18, 18, 0, 0, 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, 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, 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, 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, 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,
- 14, 14, 14, 14, 0, 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, 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, 14, 14, 14,
- 14, 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,
- 0, 0, 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, 11, 11, 11, 11, 11,
- 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, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 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, 14, 14, 14, 14, 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, 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, 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,
+ 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, 0, 0, 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, 11, 11, 11,
+ 11, 11, 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, 0, 0, 0, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 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, 0, 0, 0, 0, 0, 0, 0, 14, 14,
+ 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, 14, 14, 14, 14, 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, 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, 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, 14, 14, 14, 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,
- 15, 15, 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, 0, 0, 0, 0, 0, 0, 0,
- 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, 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, 0, 0, 14, 14, 14, 14, 0, 0, 0, 14, 0, 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, 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, 15, 15, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
#endif /* TCL_UTF_MAX > 3 */
};
@@ -1535,6 +1549,7 @@ static const unsigned char groupMap[] = {
* 100 = subtract delta for title/upper
* 101 = sub delta for upper, sub 1 for title
* 110 = sub delta for upper, add delta for lower
+ * 111 = subtract delta for upper
*
* Bits 8-31 Case delta: delta for case conversions. This should be the
* highest field so we can easily sign extend.
@@ -1554,16 +1569,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, 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
+ 8, 1859649, -769822, 9949249, 10, 1601154, 1600898, 1598594, 1598082,
+ 1598338, 1596546, 1582466, -9027966, -769983, -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
diff --git a/tcl8.6/generic/tclUtf.c b/tcl8.6/generic/tclUtf.c
index c60e99e..b33bf5f 100644
--- a/tcl8.6/generic/tclUtf.c
+++ b/tcl8.6/generic/tclUtf.c
@@ -154,19 +154,26 @@ Tcl_UniCharToUtf(
return 2;
}
if (ch <= 0xFFFF) {
-#if TCL_UTF_MAX == 4
+#if TCL_UTF_MAX > 3
if ((ch & 0xF800) == 0xD800) {
if (ch & 0x0400) {
/* Low surrogate */
- buf[3] = (char) ((ch | 0x80) & 0xBF);
- buf[2] |= (char) (((ch >> 6) | 0x80) & 0x8F);
- return 4;
+ if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
+ && ((buf[2] & 0xCF) == 0)) {
+ /* Previous Tcl_UniChar was a High surrogate, so combine */
+ buf[3] = (char) ((ch & 0x3F) | 0x80);
+ buf[2] |= (char) (((ch >> 6) & 0x0F) | 0x80);
+ return 4;
+ }
+ /* Previous Tcl_UniChar was not a High surrogate, so just output */
} else {
/* High surrogate */
ch += 0x40;
- buf[2] = (char) (((ch << 4) | 0x80) & 0xB0);
- buf[1] = (char) (((ch >> 2) | 0x80) & 0xBF);
- buf[0] = (char) (((ch >> 8) | 0xF0) & 0xF7);
+ /* Fill buffer with specific 3-byte (invalid) byte combination,
+ so following Low surrogate can recognize it and combine */
+ buf[2] = (char) ((ch << 4) & 0x30);
+ buf[1] = (char) (((ch >> 2) & 0x3F) | 0x80);
+ buf[0] = (char) (((ch >> 8) & 0x07) | 0xF0);
return 0;
}
}
@@ -182,6 +189,13 @@ Tcl_UniCharToUtf(
buf[0] = (char) ((ch >> 18) | 0xF0);
return 4;
}
+ } else if (ch == -1) {
+ if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
+ && ((buf[2] & 0xCF) == 0)) {
+ ch = 0xD7C0 + ((buf[0] & 0x07) << 8) + ((buf[1] & 0x3F) << 2)
+ + ((buf[2] & 0x30) >> 4);
+ goto three;
+ }
#endif
}
@@ -229,7 +243,7 @@ Tcl_UniCharToUtfDString(
*/
oldLength = Tcl_DStringLength(dsPtr);
- Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * TCL_UTF_MAX);
+ Tcl_DStringSetLength(dsPtr, oldLength + (uniLength + 1) * TCL_UTF_MAX);
string = Tcl_DStringValue(dsPtr) + oldLength;
p = string;
@@ -418,17 +432,27 @@ Tcl_UtfToUniCharDString(
*/
oldLength = Tcl_DStringLength(dsPtr);
-/* TODO: fix overreach! */
+
Tcl_DStringSetLength(dsPtr,
- (int) ((oldLength + length + 1) * sizeof(Tcl_UniChar)));
+ oldLength + (int) ((length + 1) * sizeof(Tcl_UniChar)));
wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength);
w = wString;
- end = src + length;
- for (p = src; p < end; ) {
+ p = src;
+ end = src + length - TCL_UTF_MAX;
+ while (p < end) {
p += TclUtfToUniChar(p, &ch);
*w++ = ch;
}
+ end += TCL_UTF_MAX;
+ while (p < end) {
+ if (Tcl_UtfCharComplete(p, end-p)) {
+ p += TclUtfToUniChar(p, &ch);
+ } else {
+ ch = UCHAR(*p++);
+ }
+ *w++ = ch;
+ }
*w = '\0';
Tcl_DStringSetLength(dsPtr,
(oldLength + ((char *) w - (char *) wString)));
@@ -726,8 +750,7 @@ Tcl_UniCharAtIndex(
{
Tcl_UniChar ch = 0;
- while (index >= 0) {
- index--;
+ while (index-- >= 0) {
src += TclUtfToUniChar(src, &ch);
}
return ch;
@@ -756,11 +779,18 @@ Tcl_UtfAtIndex(
register int index) /* The position of the desired character. */
{
Tcl_UniChar ch = 0;
+ int len = 1;
- while (index > 0) {
- index--;
+ while (index-- > 0) {
+ len = TclUtfToUniChar(src, &ch);
+ src += len;
+ }
+#if TCL_UTF_MAX == 4
+ if (!len) {
+ /* Index points at character following High Surrogate */
src += TclUtfToUniChar(src, &ch);
}
+#endif
return src;
}
@@ -971,7 +1001,11 @@ Tcl_UtfToTitle(
}
while (*src) {
bytes = TclUtfToUniChar(src, &ch);
- lowChar = Tcl_UniCharToLower(ch);
+ lowChar = ch;
+ /* Special exception for Georgian Asomtavruli chars, no titlecase. */
+ if ((unsigned)(lowChar - 0x1C90) >= 0x30) {
+ lowChar = Tcl_UniCharToLower(lowChar);
+ }
if (bytes < UtfCount(lowChar)) {
memcpy(dst, src, (size_t) bytes);
@@ -1072,16 +1106,17 @@ Tcl_UtfNcmp(
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
+ if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
- /* map high surrogate characters to values > 0xffff */
- if ((ch1 & 0xFC00) == 0xD800) {
- ch1 += 0x4000;
- }
- if ((ch2 & 0xFC00) == 0xD800) {
- ch2 += 0x4000;
- }
+ /* Surrogates always report higher than non-surrogates */
+ if (((ch1 & 0xFC00) == 0xD800)) {
+ if ((ch2 & 0xFC00) != 0xD800) {
+ return ch1;
+ }
+ } else if ((ch2 & 0xFC00) == 0xD800) {
+ return -ch2;
+ }
#endif
- if (ch1 != ch2) {
return (ch1 - ch2);
}
}
@@ -1122,16 +1157,17 @@ Tcl_UtfNcasecmp(
*/
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
+ if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
- /* map high surrogate characters to values > 0xffff */
- if ((ch1 & 0xFC00) == 0xD800) {
- ch1 += 0x4000;
- }
- if ((ch2 & 0xFC00) == 0xD800) {
- ch2 += 0x4000;
- }
+ /* Surrogates always report higher than non-surrogates */
+ if (((ch1 & 0xFC00) == 0xD800)) {
+ if ((ch2 & 0xFC00) != 0xD800) {
+ return ch1;
+ }
+ } else if ((ch2 & 0xFC00) == 0xD800) {
+ return -ch2;
+ }
#endif
- if (ch1 != ch2) {
ch1 = Tcl_UniCharToLower(ch1);
ch2 = Tcl_UniCharToLower(ch2);
if (ch1 != ch2) {
@@ -1170,16 +1206,17 @@ TclUtfCasecmp(
while (*cs && *ct) {
cs += TclUtfToUniChar(cs, &ch1);
ct += TclUtfToUniChar(ct, &ch2);
+ if (ch1 != ch2) {
#if TCL_UTF_MAX == 4
- /* map high surrogate characters to values > 0xffff */
- if ((ch1 & 0xFC00) == 0xD800) {
- ch1 += 0x4000;
- }
- if ((ch2 & 0xFC00) == 0xD800) {
- ch2 += 0x4000;
- }
+ /* Surrogates always report higher than non-surrogates */
+ if (((ch1 & 0xFC00) == 0xD800)) {
+ if ((ch2 & 0xFC00) != 0xD800) {
+ return ch1;
+ }
+ } else if ((ch2 & 0xFC00) == 0xD800) {
+ return -ch2;
+ }
#endif
- if (ch1 != ch2) {
ch1 = Tcl_UniCharToLower(ch1);
ch2 = Tcl_UniCharToLower(ch2);
if (ch1 != ch2) {
@@ -1240,8 +1277,9 @@ Tcl_UniCharToLower(
int ch) /* Unicode character to convert. */
{
int info = GetUniCharInfo(ch);
+ int mode = GetCaseType(info);
- if (GetCaseType(info) & 0x02) {
+ if ((mode & 0x02) && (mode != 0x7)) {
ch += GetDelta(info);
}
return (Tcl_UniChar) ch;
@@ -1275,7 +1313,9 @@ Tcl_UniCharToTitle(
* Subtract or add one depending on the original case.
*/
- ch += ((mode & 0x4) ? -1 : 1);
+ if (mode != 0x7) {
+ ch += ((mode & 0x4) ? -1 : 1);
+ }
} else if (mode == 0x4) {
ch -= GetDelta(info);
}
diff --git a/tcl8.6/generic/tclUtil.c b/tcl8.6/generic/tclUtil.c
index feee9c5..d5cc7c2 100644
--- a/tcl8.6/generic/tclUtil.c
+++ b/tcl8.6/generic/tclUtil.c
@@ -107,6 +107,8 @@ static Tcl_ThreadDataKey precisionKey;
static void ClearHash(Tcl_HashTable *tablePtr);
static void FreeProcessGlobalValue(ClientData clientData);
static void FreeThreadHash(ClientData clientData);
+static int GetEndOffsetFromObj(Tcl_Obj *objPtr, int endValue,
+ int *indexPtr);
static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr);
static int SetEndOffsetFromAny(Tcl_Interp *interp,
Tcl_Obj *objPtr);
@@ -1044,6 +1046,23 @@ TclScanElement(
return 2;
}
+#if COMPAT
+ /*
+ * We have an established history in TclConvertElement() when quoting
+ * because of a leading hash character to force what would be the
+ * CONVERT_MASK mode into the CONVERT_BRACE mode. That is, we format
+ * the element #{a"b} like this:
+ * {#{a"b}}
+ * and not like this:
+ * \#{a\"b}
+ * This is inconsistent with [list x{a"b}], but we will not change that now.
+ * Set that preference here so that we compute a tight size requirement.
+ */
+ if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
+ preferBrace = 1;
+ }
+#endif
+
if ((*p == '{') || (*p == '"')) {
/*
* Must escape or protect so leading character of value is not
@@ -1641,11 +1660,46 @@ Tcl_Backslash(
/*
*----------------------------------------------------------------------
*
- * TclTrimRight --
+ * UtfWellFormedEnd --
+ * Checks the end of utf string is malformed, if yes - wraps bytes
+ * to the given buffer (as well-formed NTS string). The buffer
+ * argument should be initialized by the caller and ready to use.
+ *
+ * Results:
+ * The bytes with well-formed end of the string.
+ *
+ * Side effects:
+ * Buffer (DString) may be allocated, so must be released.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline const char*
+UtfWellFormedEnd(
+ Tcl_DString *buffer, /* Buffer used to hold well-formed string. */
+ const char *bytes, /* Pointer to the beginning of the string. */
+ int length) /* Length of the string. */
+{
+ const char *l = bytes + length;
+ const char *p = Tcl_UtfPrev(l, bytes);
+
+ if (Tcl_UtfCharComplete(p, l - p)) {
+ return bytes;
+ }
+ /*
+ * Malformed utf-8 end, be sure we've NTS to safe compare of end-character,
+ * avoid segfault by access violation out of range.
+ */
+ Tcl_DStringAppend(buffer, bytes, length);
+ return Tcl_DStringValue(buffer);
+}
+/*
+ *----------------------------------------------------------------------
*
- * Takes two counted strings in the Tcl encoding which must both be null
- * terminated. Conceptually trims from the right side of the first string
- * all characters found in the second string.
+ * TclTrimRight --
+ * Takes two counted strings in the Tcl encoding. Conceptually
+ * finds the sub string (offset) to trim from the right side of the
+ * first string all characters found in the second string.
*
* Results:
* The number of bytes to be removed from the end of the string.
@@ -1656,8 +1710,8 @@ Tcl_Backslash(
*----------------------------------------------------------------------
*/
-int
-TclTrimRight(
+static inline int
+TrimRight(
const char *bytes, /* String to be trimmed... */
int numBytes, /* ...and its length in bytes */
const char *trim, /* String of trim characters... */
@@ -1666,18 +1720,6 @@ TclTrimRight(
const char *p = bytes + numBytes;
int pInc;
- if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
- Tcl_Panic("TclTrimRight works only on null-terminated strings");
- }
-
- /*
- * Empty strings -> nothing to do.
- */
-
- if ((numBytes == 0) || (numTrim == 0)) {
- return 0;
- }
-
/*
* Outer loop: iterate over string to be trimmed.
*/
@@ -1718,15 +1760,46 @@ TclTrimRight(
return numBytes - (p - bytes);
}
+
+int
+TclTrimRight(
+ const char *bytes, /* String to be trimmed... */
+ int numBytes, /* ...and its length in bytes */
+ const char *trim, /* String of trim characters... */
+ int numTrim) /* ...and its length in bytes */
+{
+ int res;
+ Tcl_DString bytesBuf, trimBuf;
+
+ /* Empty strings -> nothing to do */
+ if ((numBytes == 0) || (numTrim == 0)) {
+ return 0;
+ }
+
+ Tcl_DStringInit(&bytesBuf);
+ Tcl_DStringInit(&trimBuf);
+ bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes);
+ trim = UtfWellFormedEnd(&trimBuf, trim, numTrim);
+
+ res = TrimRight(bytes, numBytes, trim, numTrim);
+ if (res > numBytes) {
+ res = numBytes;
+ }
+
+ Tcl_DStringFree(&bytesBuf);
+ Tcl_DStringFree(&trimBuf);
+
+ return res;
+}
/*
*----------------------------------------------------------------------
*
* TclTrimLeft --
*
- * Takes two counted strings in the Tcl encoding which must both be null
- * terminated. Conceptually trims from the left side of the first string
- * all characters found in the second string.
+ * Takes two counted strings in the Tcl encoding. Conceptually
+ * finds the sub string (offset) to trim from the left side of the
+ * first string all characters found in the second string.
*
* Results:
* The number of bytes to be removed from the start of the string.
@@ -1737,8 +1810,8 @@ TclTrimRight(
*----------------------------------------------------------------------
*/
-int
-TclTrimLeft(
+static inline int
+TrimLeft(
const char *bytes, /* String to be trimmed... */
int numBytes, /* ...and its length in bytes */
const char *trim, /* String of trim characters... */
@@ -1746,18 +1819,6 @@ TclTrimLeft(
{
const char *p = bytes;
- if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
- Tcl_Panic("TclTrimLeft works only on null-terminated strings");
- }
-
- /*
- * Empty strings -> nothing to do.
- */
-
- if ((numBytes == 0) || (numTrim == 0)) {
- return 0;
- }
-
/*
* Outer loop: iterate over string to be trimmed.
*/
@@ -1794,10 +1855,99 @@ TclTrimLeft(
p += pInc;
numBytes -= pInc;
- } while (numBytes);
+ } while (numBytes > 0);
return p - bytes;
}
+
+int
+TclTrimLeft(
+ const char *bytes, /* String to be trimmed... */
+ int numBytes, /* ...and its length in bytes */
+ const char *trim, /* String of trim characters... */
+ int numTrim) /* ...and its length in bytes */
+{
+ int res;
+ Tcl_DString bytesBuf, trimBuf;
+
+ /* Empty strings -> nothing to do */
+ if ((numBytes == 0) || (numTrim == 0)) {
+ return 0;
+ }
+
+ Tcl_DStringInit(&bytesBuf);
+ Tcl_DStringInit(&trimBuf);
+ bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes);
+ trim = UtfWellFormedEnd(&trimBuf, trim, numTrim);
+
+ res = TrimLeft(bytes, numBytes, trim, numTrim);
+ if (res > numBytes) {
+ res = numBytes;
+ }
+
+ Tcl_DStringFree(&bytesBuf);
+ Tcl_DStringFree(&trimBuf);
+
+ return res;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTrim --
+ * Finds the sub string (offset) to trim from both sides of the
+ * first string all characters found in the second string.
+ *
+ * Results:
+ * The number of bytes to be removed from the start of the string
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclTrim(
+ const char *bytes, /* String to be trimmed... */
+ int numBytes, /* ...and its length in bytes */
+ const char *trim, /* String of trim characters... */
+ int numTrim, /* ...and its length in bytes */
+ int *trimRight) /* Offset from the end of the string. */
+{
+ int trimLeft;
+ Tcl_DString bytesBuf, trimBuf;
+
+ *trimRight = 0;
+ /* Empty strings -> nothing to do */
+ if ((numBytes == 0) || (numTrim == 0)) {
+ return 0;
+ }
+
+ Tcl_DStringInit(&bytesBuf);
+ Tcl_DStringInit(&trimBuf);
+ bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes);
+ trim = UtfWellFormedEnd(&trimBuf, trim, numTrim);
+
+ trimLeft = TrimLeft(bytes, numBytes, trim, numTrim);
+ if (trimLeft > numBytes) {
+ trimLeft = numBytes;
+ }
+ numBytes -= trimLeft;
+ /* have to trim yet (first char was already verified within TrimLeft) */
+ if (numBytes > 1) {
+ bytes += trimLeft;
+ *trimRight = TrimRight(bytes, numBytes, trim, numTrim);
+ if (*trimRight > numBytes) {
+ *trimRight = numBytes;
+ }
+ }
+
+ Tcl_DStringFree(&bytesBuf);
+ Tcl_DStringFree(&trimBuf);
+
+ return trimLeft;
+}
/*
*----------------------------------------------------------------------
@@ -1865,30 +2015,20 @@ Tcl_Concat(
result = ckalloc((unsigned) (bytesNeeded + argc));
for (p = result, i = 0; i < argc; i++) {
- int trim, elemLength;
+ int triml, trimr, elemLength;
const char *element;
element = argv[i];
elemLength = strlen(argv[i]);
- /*
- * Trim away the leading whitespace.
- */
+ /* Trim away the leading/trailing whitespace. */
+ triml = TclTrim(element, elemLength, CONCAT_TRIM_SET,
+ CONCAT_WS_SIZE, &trimr);
+ element += triml;
+ elemLength -= triml + trimr;
- trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
- CONCAT_WS_SIZE);
- element += trim;
- elemLength -= trim;
-
- /*
- * Trim away the trailing whitespace. Do not permit trimming to expose
- * a final backslash character.
- */
-
- trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
- CONCAT_WS_SIZE);
- trim -= trim && (element[elemLength - trim - 1] == '\\');
- elemLength -= trim;
+ /* Do not permit trimming to expose a final backslash character. */
+ elemLength += trimr && (element[elemLength - 1] == '\\');
/*
* If we're left with empty element after trimming, do nothing.
@@ -2008,28 +2148,18 @@ Tcl_ConcatObj(
Tcl_SetObjLength(resPtr, 0);
for (i = 0; i < objc; i++) {
- int trim;
+ int triml, trimr;
element = TclGetStringFromObj(objv[i], &elemLength);
- /*
- * Trim away the leading whitespace.
- */
-
- trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
- CONCAT_WS_SIZE);
- element += trim;
- elemLength -= trim;
-
- /*
- * Trim away the trailing whitespace. Do not permit trimming to expose
- * a final backslash character.
- */
+ /* Trim away the leading/trailing whitespace. */
+ triml = TclTrim(element, elemLength, CONCAT_TRIM_SET,
+ CONCAT_WS_SIZE, &trimr);
+ element += triml;
+ elemLength -= triml + trimr;
- trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
- CONCAT_WS_SIZE);
- trim -= trim && (element[elemLength - trim - 1] == '\\');
- elemLength -= trim;
+ /* Do not permit trimming to expose a final backslash character. */
+ elemLength += trimr && (element[elemLength - 1] == '\\');
/*
* If we're left with empty element after trimming, do nothing.
@@ -2530,7 +2660,8 @@ TclStringMatchObj(
udata = Tcl_GetUnicodeFromObj(strObj, &length);
uptn = Tcl_GetUnicodeFromObj(ptnObj, &plen);
match = TclUniCharMatch(udata, length, uptn, plen, flags);
- } else if (TclIsPureByteArray(strObj) && !flags) {
+ } else if (TclIsPureByteArray(strObj) && TclIsPureByteArray(ptnObj)
+ && !flags) {
unsigned char *data, *ptn;
data = Tcl_GetByteArrayFromObj(strObj, &length);
@@ -3530,22 +3661,27 @@ TclFormatInt(
*
* TclGetIntForIndex --
*
- * This function returns an integer corresponding to the list index held
- * in a Tcl object. The Tcl object's value is expected to be in the
- * format integer([+-]integer)? or the format end([+-]integer)?.
- *
- * Results:
- * The return value is normally TCL_OK, which means that the index was
- * successfully stored into the location referenced by "indexPtr". If the
- * Tcl object referenced by "objPtr" has the value "end", the value
- * stored is "endValue". If "objPtr"s values is not of one of the
- * expected formats, TCL_ERROR is returned and, if "interp" is non-NULL,
- * an error message is left in the interpreter's result object.
- *
- * Side effects:
- * The object referenced by "objPtr" might be converted to an integer,
- * wide integer, or end-based-index object.
- *
+ * Provides an integer corresponding to the list index held in a Tcl
+ * object. The string value 'objPtr' is expected have the format
+ * integer([+-]integer)? or end([+-]integer)?.
+ *
+ * Value
+ * TCL_OK
+ *
+ * The index is stored at the address given by by 'indexPtr'. If
+ * 'objPtr' has the value "end", the value stored is 'endValue'.
+ *
+ * TCL_ERROR
+ *
+ * The value of 'objPtr' does not have one of the expected formats. If
+ * 'interp' is non-NULL, an error message is left in the interpreter's
+ * result object.
+ *
+ * Effect
+ *
+ * The object referenced by 'objPtr' is converted, as needed, to an
+ * integer, wide integer, or end-based-index object.
+ *
*----------------------------------------------------------------------
*/
@@ -3569,13 +3705,7 @@ TclGetIntForIndex(
return TCL_OK;
}
- if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) {
- /*
- * If the object is already an offset from the end of the list, or can
- * be converted to one, use it.
- */
-
- *indexPtr = endValue + objPtr->internalRep.longValue;
+ if (GetEndOffsetFromObj(objPtr, endValue, indexPtr) == TCL_OK) {
return TCL_OK;
}
@@ -3678,6 +3808,41 @@ UpdateStringOfEndOffset(
/*
*----------------------------------------------------------------------
*
+ * GetEndOffsetFromObj --
+ *
+ * Look for a string of the form "end[+-]offset" and convert it to an
+ * internal representation holding the offset.
+ *
+ * Results:
+ * Tcl return code.
+ *
+ * Side effects:
+ * May store a Tcl_ObjType.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetEndOffsetFromObj(
+ Tcl_Obj *objPtr, /* Pointer to the object to parse */
+ int endValue, /* The value to be stored at "indexPtr" if
+ * "objPtr" holds "end". */
+ int *indexPtr) /* Location filled in with an integer
+ * representing an index. */
+{
+ if (SetEndOffsetFromAny(NULL, objPtr) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /* TODO: Handle overflow cases sensibly */
+ *indexPtr = endValue + (int)objPtr->internalRep.longValue;
+ return TCL_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* SetEndOffsetFromAny --
*
* Look for a string of the form "end[+-]offset" and convert it to an
@@ -3744,6 +3909,8 @@ SetEndOffsetFromAny(
return TCL_ERROR;
}
if (bytes[3] == '-') {
+
+ /* TODO: Review overflow concerns here! */
offset = -offset;
}
} else {
@@ -3775,6 +3942,143 @@ SetEndOffsetFromAny(
/*
*----------------------------------------------------------------------
*
+ * TclIndexEncode --
+ *
+ * Parse objPtr to determine if it is an index value. Two cases
+ * are possible. The value objPtr might be parsed as an absolute
+ * index value in the C signed int range. Note that this includes
+ * index values that are integers as presented and it includes index
+ * arithmetic expressions. The absolute index values that can be
+ * directly meaningful as an index into either a list or a string are
+ * those integer values >= TCL_INDEX_START (0)
+ * and < TCL_INDEX_AFTER (INT_MAX).
+ * The largest string supported in Tcl 8 has bytelength INT_MAX.
+ * This means the largest supported character length is also INT_MAX,
+ * and the index of the last character in a string of length INT_MAX
+ * is INT_MAX-1.
+ *
+ * Any absolute index value parsed outside that range is encoded
+ * using the before and after values passed in by the
+ * caller as the encoding to use for indices that are either
+ * less than or greater than the usable index range. TCL_INDEX_AFTER
+ * is available as a good choice for most callers to use for
+ * after. Likewise, the value TCL_INDEX_BEFORE is good for
+ * most callers to use for before. Other values are possible
+ * when the caller knows it is helpful in producing its own behavior
+ * for indices before and after the indexed item.
+ *
+ * A token can also be parsed as an end-relative index expression.
+ * All end-relative expressions that indicate an index larger
+ * than end (end+2, end--5) point beyond the end of the indexed
+ * collection, and can be encoded as after. The end-relative
+ * expressions that indicate an index less than or equal to end
+ * are encoded relative to the value TCL_INDEX_END (-2). The
+ * index "end" is encoded as -2, down to the index "end-0x7ffffffe"
+ * which is encoded as INT_MIN. Since the largest index into a
+ * string possible in Tcl 8 is 0x7ffffffe, the interpretation of
+ * "end-0x7ffffffe" for that largest string would be 0. Thus,
+ * if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed,
+ * they can be encoded with the before value.
+ *
+ * These details will require re-examination whenever string and
+ * list length limits are increased, but that will likely also
+ * mean a revised routine capable of returning Tcl_WideInt values.
+ *
+ * Returns:
+ * TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
+ *
+ * Side effects:
+ * When TCL_OK is returned, the encoded index value is written
+ * to *indexPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclIndexEncode(
+ Tcl_Interp *interp, /* For error reporting, may be NULL */
+ Tcl_Obj *objPtr, /* Index value to parse */
+ int before, /* Value to return for index before beginning */
+ int after, /* Value to return for index after end */
+ int *indexPtr) /* Where to write the encoded answer, not NULL */
+{
+ int idx;
+
+ if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &idx)) {
+ /* We parsed a value in the range INT_MIN...INT_MAX */
+ integerEncode:
+ if (idx < TCL_INDEX_START) {
+ /* All negative absolute indices are "before the beginning" */
+ idx = before;
+ } else if (idx == INT_MAX) {
+ /* This index value is always "after the end" */
+ idx = after;
+ }
+ /* usual case, the absolute index value encodes itself */
+ } else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &idx)) {
+ /*
+ * We parsed an end+offset index value.
+ * idx holds the offset value in the range INT_MIN...INT_MAX.
+ */
+ if (idx > 0) {
+ /*
+ * All end+postive or end-negative expressions
+ * always indicate "after the end".
+ */
+ idx = after;
+ } else if (idx < INT_MIN - TCL_INDEX_END) {
+ /* These indices always indicate "before the beginning */
+ idx = before;
+ } else {
+ /* Encoded end-positive (or end+negative) are offset */
+ idx += TCL_INDEX_END;
+ }
+
+ /* TODO: Consider flag to suppress repeated end-offset parse. */
+ } else if (TCL_OK == TclGetIntForIndexM(interp, objPtr, 0, &idx)) {
+ /*
+ * Only reach this case when the index value is a
+ * constant index arithmetic expression, and idx
+ * holds the result. Treat it the same as if it were
+ * parsed as an absolute integer value.
+ */
+ goto integerEncode;
+ } else {
+ return TCL_ERROR;
+ }
+ *indexPtr = idx;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIndexDecode --
+ *
+ * Decodes a value previously encoded by TclIndexEncode. The argument
+ * endValue indicates what value of "end" should be used in the
+ * decoding.
+ *
+ * Results:
+ * The decoded index value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclIndexDecode(
+ int encoded, /* Value to decode */
+ int endValue) /* Meaning of "end" to use, > TCL_INDEX_END */
+{
+ if (encoded <= TCL_INDEX_END) {
+ return (encoded - TCL_INDEX_END) + endValue;
+ }
+ return encoded;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclCheckBadOctal --
*
* This function checks for a bad octal value and appends a meaningful
diff --git a/tcl8.6/generic/tclVar.c b/tcl8.6/generic/tclVar.c
index 3dd6790..7b3db7e 100644
--- a/tcl8.6/generic/tclVar.c
+++ b/tcl8.6/generic/tclVar.c
@@ -176,6 +176,9 @@ static void AppendLocals(Tcl_Interp *interp, Tcl_Obj *listPtr,
static void DeleteSearches(Interp *iPtr, Var *arrayVarPtr);
static void DeleteArray(Interp *iPtr, Tcl_Obj *arrayNamePtr,
Var *varPtr, int flags, int index);
+static int LocateArray(Tcl_Interp *interp, Tcl_Obj *name,
+ Var **varPtrPtr, int *isArrayPtr);
+static int NotArrayError(Tcl_Interp *interp, Tcl_Obj *name);
static Tcl_Var ObjFindNamespaceVar(Tcl_Interp *interp,
Tcl_Obj *namePtr, Tcl_Namespace *contextNsPtr,
int flags);
@@ -269,6 +272,42 @@ TclVarHashCreateVar(
return varPtr;
}
+
+static int
+LocateArray(
+ Tcl_Interp *interp,
+ Tcl_Obj *name,
+ Var **varPtrPtr,
+ int *isArrayPtr)
+{
+ Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, name, NULL, /*flags*/ 0,
+ /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+ if (TclCheckArrayTraces(interp, varPtr, arrayPtr, name, -1) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ if (varPtrPtr) {
+ *varPtrPtr = varPtr;
+ }
+ if (isArrayPtr) {
+ *isArrayPtr = varPtr && !TclIsVarUndefined(varPtr)
+ && TclIsVarArray(varPtr);
+ }
+ return TCL_OK;
+}
+
+static int
+NotArrayError(
+ Tcl_Interp *interp,
+ Tcl_Obj *name)
+{
+ const char *nameStr = Tcl_GetString(name);
+
+ Tcl_SetObjResult(interp,
+ Tcl_ObjPrintf("\"%s\" isn't an array", nameStr));
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", nameStr, NULL);
+ return TCL_ERROR;
+}
/*
*----------------------------------------------------------------------
@@ -933,20 +972,24 @@ TclLookupSimpleVar(
}
}
} else { /* Local var: look in frame varFramePtr. */
- int localLen, localCt = varFramePtr->numCompiledLocals;
- Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0;
- const char *localNameStr;
+ int localCt = varFramePtr->numCompiledLocals;
- for (i=0 ; i<localCt ; i++, objPtrPtr++) {
- register Tcl_Obj *objPtr = *objPtrPtr;
+ if (localCt > 0) {
+ Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0;
+ const char *localNameStr;
+ int localLen;
- if (objPtr) {
- localNameStr = TclGetStringFromObj(objPtr, &localLen);
+ for (i=0 ; i<localCt ; i++, objPtrPtr++) {
+ register Tcl_Obj *objPtr = *objPtrPtr;
- if ((varLen == localLen) && (varName[0] == localNameStr[0])
+ if (objPtr) {
+ localNameStr = TclGetStringFromObj(objPtr, &localLen);
+
+ if ((varLen == localLen) && (varName[0] == localNameStr[0])
&& !memcmp(varName, localNameStr, varLen)) {
- *indexPtr = i;
- return (Var *) &varFramePtr->compiledLocals[i];
+ *indexPtr = i;
+ return (Var *) &varFramePtr->compiledLocals[i];
+ }
}
}
}
@@ -2929,175 +2972,6 @@ Tcl_LappendObjCmd(
/*
*----------------------------------------------------------------------
*
- * TclArraySet --
- *
- * Set the elements of an array. If there are no elements to set, create
- * an empty array. This routine is used by the Tcl_ArrayObjCmd and by the
- * TclSetupEnv routine.
- *
- * Results:
- * A standard Tcl result object.
- *
- * Side effects:
- * A variable will be created if one does not already exist.
- * Callers must Incr arrayNameObj if they pland to Decr it.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclArraySet(
- Tcl_Interp *interp, /* Current interpreter. */
- Tcl_Obj *arrayNameObj, /* The array name. */
- Tcl_Obj *arrayElemObj) /* The array elements list or dict. If this is
- * NULL, create an empty array. */
-{
- Var *varPtr, *arrayPtr;
- int result, i;
-
- varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
- /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "set", /*createPart1*/ 1,
- /*createPart2*/ 1, &arrayPtr);
- if (varPtr == NULL) {
- return TCL_ERROR;
- }
- if (arrayPtr) {
- CleanupVar(varPtr, arrayPtr);
- TclObjVarErrMsg(interp, arrayNameObj, NULL, "set", needArray, -1);
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
- TclGetString(arrayNameObj), NULL);
- return TCL_ERROR;
- }
-
- if (arrayElemObj == NULL) {
- goto ensureArray;
- }
-
- /*
- * Install the contents of the dictionary or list into the array.
- */
-
- if (arrayElemObj->typePtr == &tclDictType) {
- Tcl_Obj *keyPtr, *valuePtr;
- Tcl_DictSearch search;
- int done;
-
- if (Tcl_DictObjSize(interp, arrayElemObj, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- if (done == 0) {
- /*
- * Empty, so we'll just force the array to be properly existing
- * instead.
- */
-
- goto ensureArray;
- }
-
- /*
- * Don't need to look at result of Tcl_DictObjFirst as we've just
- * successfully used a dictionary operation on the same object.
- */
-
- for (Tcl_DictObjFirst(interp, arrayElemObj, &search,
- &keyPtr, &valuePtr, &done) ; !done ;
- Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done)) {
- /*
- * At this point, it would be nice if the key was directly usable
- * by the array. This isn't the case though.
- */
-
- Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
- keyPtr, TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
-
- if ((elemVarPtr == NULL) ||
- (TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
- keyPtr, valuePtr, TCL_LEAVE_ERR_MSG, -1) == NULL)) {
- Tcl_DictObjDone(&search);
- return TCL_ERROR;
- }
- }
- return TCL_OK;
- } else {
- /*
- * Not a dictionary, so assume (and convert to, for backward-
- * -compatibility reasons) a list.
- */
-
- int elemLen;
- Tcl_Obj **elemPtrs, *copyListObj;
-
- result = TclListObjGetElements(interp, arrayElemObj,
- &elemLen, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if (elemLen & 1) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "list must have an even number of elements", -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "FORMAT", NULL);
- return TCL_ERROR;
- }
- if (elemLen == 0) {
- goto ensureArray;
- }
-
- /*
- * We needn't worry about traces invalidating arrayPtr: should that be
- * the case, TclPtrSetVarIdx will return NULL so that we break out of
- * the loop and return an error.
- */
-
- copyListObj = TclListObjCopy(NULL, arrayElemObj);
- for (i=0 ; i<elemLen ; i+=2) {
- Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
- elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
-
- if ((elemVarPtr == NULL) ||
- (TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
- elemPtrs[i],elemPtrs[i+1],TCL_LEAVE_ERR_MSG,-1) == NULL)){
- result = TCL_ERROR;
- break;
- }
- }
- Tcl_DecrRefCount(copyListObj);
- return result;
- }
-
- /*
- * The list is empty make sure we have an array, or create one if
- * necessary.
- */
-
- ensureArray:
- if (varPtr != NULL) {
- if (TclIsVarArray(varPtr)) {
- /*
- * Already an array, done.
- */
-
- return TCL_OK;
- }
- if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
- /*
- * Either an array element, or a scalar: lose!
- */
-
- TclObjVarErrMsg(interp, arrayNameObj, NULL, "array set",
- needArray, -1);
- Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
- return TCL_ERROR;
- }
- }
- TclSetVarArray(varPtr);
- varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
- TclInitVarHashTable(varPtr->value.tablePtr, TclGetVarNsPtr(varPtr));
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* ArrayStartSearchCmd --
*
* This object-based function is invoked to process the "array
@@ -3121,11 +2995,10 @@ ArrayStartSearchCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
+ Interp *iPtr = (Interp *)interp;
+ Var *varPtr;
Tcl_HashEntry *hPtr;
- Tcl_Obj *varNameObj;
- int isNew;
+ int isNew, isArray;
ArraySearch *searchPtr;
const char *varName;
@@ -3133,48 +3006,20 @@ ArrayStartSearchCmd(
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
- varNameObj = objv[1];
-
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
- varName = TclGetString(varNameObj);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, objv[1], &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't an array", varName));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", varName, NULL);
- return TCL_ERROR;
+ if (!isArray) {
+ return NotArrayError(interp, objv[1]);
}
/*
* Make a new array search with a free name.
*/
+ varName = TclGetString(objv[1]);
searchPtr = ckalloc(sizeof(ArraySearch));
hPtr = Tcl_CreateHashEntry(&iPtr->varSearches, varPtr, &isNew);
if (isNew) {
@@ -3219,10 +3064,10 @@ ArrayAnyMoreCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
+ Interp *iPtr = (Interp *)interp;
+ Var *varPtr;
Tcl_Obj *varNameObj, *searchObj;
- int gotValue;
+ int gotValue, isArray;
ArraySearch *searchPtr;
if (objc != 3) {
@@ -3232,40 +3077,12 @@ ArrayAnyMoreCmd(
varNameObj = objv[1];
searchObj = objv[2];
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't an array", TclGetString(varNameObj)));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
- TclGetString(varNameObj), NULL);
- return TCL_ERROR;
+ if (!isArray) {
+ return NotArrayError(interp, varNameObj);
}
/*
@@ -3326,10 +3143,10 @@ ArrayNextElementCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
+ Var *varPtr;
Tcl_Obj *varNameObj, *searchObj;
ArraySearch *searchPtr;
+ int isArray;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName searchId");
@@ -3338,40 +3155,12 @@ ArrayNextElementCmd(
varNameObj = objv[1];
searchObj = objv[2];
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't an array", TclGetString(varNameObj)));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
- TclGetString(varNameObj), NULL);
- return TCL_ERROR;
+ if (!isArray) {
+ return NotArrayError(interp, varNameObj);
}
/*
@@ -3435,11 +3224,12 @@ ArrayDoneSearchCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
+ Interp *iPtr = (Interp *)interp;
+ Var *varPtr;
Tcl_HashEntry *hPtr;
Tcl_Obj *varNameObj, *searchObj;
ArraySearch *searchPtr, *prevPtr;
+ int isArray;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName searchId");
@@ -3448,40 +3238,12 @@ ArrayDoneSearchCmd(
varNameObj = objv[1];
searchObj = objv[2];
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't an array", TclGetString(varNameObj)));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
- TclGetString(varNameObj), NULL);
- return TCL_ERROR;
+ if (!isArray) {
+ return NotArrayError(interp, varNameObj);
}
/*
@@ -3543,45 +3305,19 @@ ArrayExistsCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
- Tcl_Obj *arrayNameObj;
- int notArray;
+ Interp *iPtr = (Interp *)interp;
+ int isArray;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
- arrayNameObj = objv[1];
-
- /*
- * Locate the array variable.
- */
- varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, arrayNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, objv[1], NULL, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Check whether we've actually got an array variable.
- */
-
- notArray = ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr));
- Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[!notArray]);
+ Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[isArray]);
return TCL_OK;
}
@@ -3610,13 +3346,12 @@ ArrayGetCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr, *varPtr2;
+ Var *varPtr, *varPtr2;
Tcl_Obj *varNameObj, *nameObj, *valueObj, *nameLstObj, *tmpResObj;
Tcl_Obj **nameObjPtr, *patternObj;
Tcl_HashSearch search;
const char *pattern;
- int i, count, result;
+ int i, count, result, isArray;
switch (objc) {
case 2:
@@ -3632,35 +3367,12 @@ ArrayGetCmd(
return TCL_ERROR;
}
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces. If not an array, it's an empty result.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
+ /* If not an array, it's an empty result. */
+ if (!isArray) {
return TCL_OK;
}
@@ -3798,39 +3510,20 @@ ArrayNamesCmd(
"-exact", "-glob", "-regexp", NULL
};
enum options { OPT_EXACT, OPT_GLOB, OPT_REGEXP };
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr, *varPtr2;
- Tcl_Obj *varNameObj, *nameObj, *resultObj, *patternObj;
+ Var *varPtr, *varPtr2;
+ Tcl_Obj *nameObj, *resultObj, *patternObj;
Tcl_HashSearch search;
const char *pattern = NULL;
- int mode = OPT_GLOB;
+ int isArray, mode = OPT_GLOB;
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?mode? ?pattern?");
return TCL_ERROR;
}
- varNameObj = objv[1];
patternObj = (objc > 2 ? objv[objc-1] : NULL);
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, objv[1], &varPtr, &isArray)) {
+ return TCL_ERROR;
}
/*
@@ -3842,14 +3535,9 @@ ArrayNamesCmd(
return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces. If not an array, the result is empty.
- */
+ /* If not an array, the result is empty. */
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
+ if (!isArray) {
return TCL_OK;
}
@@ -3986,36 +3674,156 @@ ArraySetCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
+ Tcl_Obj *arrayNameObj;
+ Tcl_Obj *arrayElemObj;
Var *varPtr, *arrayPtr;
+ int result, i;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName list");
return TCL_ERROR;
}
+ if (TCL_ERROR == LocateArray(interp, objv[1], NULL, NULL)) {
+ return TCL_ERROR;
+ }
+
+ arrayNameObj = objv[1];
+ varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
+ /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "set", /*createPart1*/ 1,
+ /*createPart2*/ 1, &arrayPtr);
+ if (varPtr == NULL) {
+ return TCL_ERROR;
+ }
+ if (arrayPtr) {
+ CleanupVar(varPtr, arrayPtr);
+ TclObjVarErrMsg(interp, arrayNameObj, NULL, "set", needArray, -1);
+ Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+ TclGetString(arrayNameObj), NULL);
+ return TCL_ERROR;
+ }
+
/*
- * Locate the array variable.
+ * Install the contents of the dictionary or list into the array.
*/
- varPtr = TclObjLookupVarEx(interp, objv[1], NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+ arrayElemObj = objv[2];
+ if (arrayElemObj->typePtr == &tclDictType && arrayElemObj->bytes == NULL) {
+ Tcl_Obj *keyPtr, *valuePtr;
+ Tcl_DictSearch search;
+ int done;
+
+ if (Tcl_DictObjSize(interp, arrayElemObj, &done) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (done == 0) {
+ /*
+ * Empty, so we'll just force the array to be properly existing
+ * instead.
+ */
+
+ goto ensureArray;
+ }
+
+ /*
+ * Don't need to look at result of Tcl_DictObjFirst as we've just
+ * successfully used a dictionary operation on the same object.
+ */
+
+ for (Tcl_DictObjFirst(interp, arrayElemObj, &search,
+ &keyPtr, &valuePtr, &done) ; !done ;
+ Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done)) {
+ /*
+ * At this point, it would be nice if the key was directly usable
+ * by the array. This isn't the case though.
+ */
+
+ Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
+ keyPtr, TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
+
+ if ((elemVarPtr == NULL) ||
+ (TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
+ keyPtr, valuePtr, TCL_LEAVE_ERR_MSG, -1) == NULL)) {
+ Tcl_DictObjDone(&search);
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+ } else {
+ /*
+ * Not a dictionary, so assume (and convert to, for backward-
+ * -compatibility reasons) a list.
+ */
+
+ int elemLen;
+ Tcl_Obj **elemPtrs, *copyListObj;
+
+ result = TclListObjGetElements(interp, arrayElemObj,
+ &elemLen, &elemPtrs);
+ if (result != TCL_OK) {
+ return result;
+ }
+ if (elemLen & 1) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "list must have an even number of elements", -1));
+ Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "FORMAT", NULL);
+ return TCL_ERROR;
+ }
+ if (elemLen == 0) {
+ goto ensureArray;
+ }
+
+ /*
+ * We needn't worry about traces invalidating arrayPtr: should that be
+ * the case, TclPtrSetVarIdx will return NULL so that we break out of
+ * the loop and return an error.
+ */
+
+ copyListObj = TclListObjCopy(NULL, arrayElemObj);
+ for (i=0 ; i<elemLen ; i+=2) {
+ Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
+ elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
+
+ if ((elemVarPtr == NULL) ||
+ (TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
+ elemPtrs[i],elemPtrs[i+1],TCL_LEAVE_ERR_MSG,-1) == NULL)){
+ result = TCL_ERROR;
+ break;
+ }
+ }
+ Tcl_DecrRefCount(copyListObj);
+ return result;
+ }
/*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
+ * The list is empty make sure we have an array, or create one if
+ * necessary.
*/
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, objv[1], NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+ ensureArray:
+ if (varPtr != NULL) {
+ if (TclIsVarArray(varPtr)) {
+ /*
+ * Already an array, done.
+ */
+
+ return TCL_OK;
+ }
+ if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
+ /*
+ * Either an array element, or a scalar: lose!
+ */
+
+ TclObjVarErrMsg(interp, arrayNameObj, NULL, "array set",
+ needArray, -1);
+ Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
return TCL_ERROR;
}
}
-
- return TclArraySet(interp, objv[1], objv[2]);
+ TclSetVarArray(varPtr);
+ varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
+ TclInitVarHashTable(varPtr->value.tablePtr, TclGetVarNsPtr(varPtr));
+ return TCL_OK;
}
/*
@@ -4043,47 +3851,23 @@ ArraySizeCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
- Tcl_Obj *varNameObj;
+ Var *varPtr;
Tcl_HashSearch search;
Var *varPtr2;
- int size = 0;
+ int isArray, size = 0;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
- varNameObj = objv[1];
-
- /*
- * Locate the array variable.
- */
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, objv[1], &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces. We can only iterate over the array if it exists...
- */
+ /* We can only iterate over the array if it exists... */
- if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
+ if (isArray) {
/*
* Must iterate in order to get chance to check for present but
* "undefined" entries.
@@ -4127,10 +3911,10 @@ ArrayStatsCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr;
+ Var *varPtr;
Tcl_Obj *varNameObj;
char *stats;
+ int isArray;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
@@ -4138,40 +3922,12 @@ ArrayStatsCmd(
}
varNameObj = objv[1];
- /*
- * Locate the array variable.
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't an array", TclGetString(varNameObj)));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
- TclGetString(varNameObj), NULL);
- return TCL_ERROR;
+ if (!isArray) {
+ return NotArrayError(interp, varNameObj);
}
stats = Tcl_HashStats((Tcl_HashTable *) varPtr->value.tablePtr);
@@ -4210,12 +3966,12 @@ ArrayUnsetCmd(
int objc,
Tcl_Obj *const objv[])
{
- Interp *iPtr = (Interp *) interp;
- Var *varPtr, *arrayPtr, *varPtr2, *protectedVarPtr;
+ Var *varPtr, *varPtr2, *protectedVarPtr;
Tcl_Obj *varNameObj, *patternObj, *nameObj;
Tcl_HashSearch search;
const char *pattern;
const int unsetFlags = 0; /* Should this be TCL_LEAVE_ERR_MSG? */
+ int isArray;
switch (objc) {
case 2:
@@ -4231,35 +3987,11 @@ ArrayUnsetCmd(
return TCL_ERROR;
}
- /*
- * Locate the array variable
- */
-
- varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
- /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
-
- /*
- * Special array trace used to keep the env array in sync for array names,
- * array get, etc.
- */
-
- if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
- && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
- (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
- TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
- return TCL_ERROR;
- }
+ if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
+ return TCL_ERROR;
}
- /*
- * Verify that it is indeed an array variable. This test comes after the
- * traces - the variable may actually become an array as an effect of said
- * traces.
- */
-
- if ((varPtr == NULL) || !TclIsVarArray(varPtr)
- || TclIsVarUndefined(varPtr)) {
+ if (!isArray) {
return TCL_OK;
}
@@ -5596,9 +5328,6 @@ DeleteArray(
Tcl_Obj *objPtr;
VarTrace *tracePtr;
- if (varPtr->flags & VAR_SEARCH_ACTIVE) {
- DeleteSearches(iPtr, varPtr);
- }
for (elPtr = VarHashFirstVar(varPtr->value.tablePtr, &search);
elPtr != NULL; elPtr = VarHashNextVar(&search)) {
if (TclIsVarScalar(elPtr) && (elPtr->value.objPtr != NULL)) {
@@ -6407,7 +6136,7 @@ AppendLocals(
Interp *iPtr = (Interp *) interp;
Var *varPtr;
int i, localVarCt, added;
- Tcl_Obj **varNamePtr, *objNamePtr;
+ Tcl_Obj *objNamePtr;
const char *varName;
TclVarHashTable *localVarTablePtr;
Tcl_HashSearch search;
@@ -6417,27 +6146,30 @@ AppendLocals(
localVarCt = iPtr->varFramePtr->numCompiledLocals;
varPtr = iPtr->varFramePtr->compiledLocals;
localVarTablePtr = iPtr->varFramePtr->varTablePtr;
- varNamePtr = &iPtr->varFramePtr->localCachePtr->varName0;
if (includeLinks) {
Tcl_InitObjHashTable(&addedTable);
}
- for (i = 0; i < localVarCt; i++, varNamePtr++) {
- /*
- * Skip nameless (temporary) variables and undefined variables.
- */
+ if (localVarCt > 0) {
+ Tcl_Obj **varNamePtr = &iPtr->varFramePtr->localCachePtr->varName0;
+
+ for (i = 0; i < localVarCt; i++, varNamePtr++) {
+ /*
+ * Skip nameless (temporary) variables and undefined variables.
+ */
- if (*varNamePtr && !TclIsVarUndefined(varPtr)
+ if (*varNamePtr && !TclIsVarUndefined(varPtr)
&& (includeLinks || !TclIsVarLink(varPtr))) {
- varName = TclGetString(*varNamePtr);
- if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
- Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr);
- if (includeLinks) {
- Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added);
+ varName = TclGetString(*varNamePtr);
+ if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
+ Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr);
+ if (includeLinks) {
+ Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added);
+ }
}
}
+ varPtr++;
}
- varPtr++;
}
/*
diff --git a/tcl8.6/library/dde/pkgIndex.tcl b/tcl8.6/library/dde/pkgIndex.tcl
index 4cf73d0..7aa67fa 100644
--- a/tcl8.6/library/dde/pkgIndex.tcl
+++ b/tcl8.6/library/dde/pkgIndex.tcl
@@ -1,7 +1,7 @@
if {([info commands ::tcl::pkgconfig] eq "")
|| ([info sharedlibextension] ne ".dll")} return
if {[::tcl::pkgconfig get debug]} {
- package ifneeded dde 1.4.0 [list load [file join $dir tcldde14g.dll] dde]
+ package ifneeded dde 1.4.1 [list load [file join $dir tcldde14g.dll] dde]
} else {
- package ifneeded dde 1.4.0 [list load [file join $dir tcldde14.dll] dde]
+ package ifneeded dde 1.4.1 [list load [file join $dir tcldde14.dll] dde]
}
diff --git a/tcl8.6/library/http/http.tcl b/tcl8.6/library/http/http.tcl
index 9f5310b..f82bced 100644
--- a/tcl8.6/library/http/http.tcl
+++ b/tcl8.6/library/http/http.tcl
@@ -11,7 +11,7 @@
package require Tcl 8.6-
# Keep this in sync with pkgIndex.tcl and with the install directories in
# Makefiles
-package provide http 2.8.12
+package provide http 2.9.0
namespace eval http {
# Allow resourcing to not clobber existing data
@@ -20,26 +20,30 @@ namespace eval http {
if {![info exists http]} {
array set http {
-accept */*
+ -pipeline 1
+ -postfresh 0
-proxyhost {}
-proxyport {}
-proxyfilter http::ProxyRequired
+ -repost 0
-urlencoding utf-8
+ -zip 1
}
- # We need a useragent string of this style or various servers will refuse to
- # send us compressed content even when we ask for it. This follows the
- # de-facto layout of user-agent strings in current browsers.
+ # We need a useragent string of this style or various servers will
+ # refuse to send us compressed content even when we ask for it. This
+ # follows the de-facto layout of user-agent strings in current browsers.
# Safe interpreters do not have ::tcl_platform(os) or
# ::tcl_platform(osVersion).
if {[interp issafe]} {
set http(-useragent) "Mozilla/5.0\
- (Windows; U;\
- Windows NT 10.0)\
- http/[package provide http] Tcl/[package provide Tcl]"
+ (Windows; U;\
+ Windows NT 10.0)\
+ http/[package provide http] Tcl/[package provide Tcl]"
} else {
set http(-useragent) "Mozilla/5.0\
- ([string totitle $::tcl_platform(platform)]; U;\
- $::tcl_platform(os) $::tcl_platform(osVersion))\
- http/[package provide http] Tcl/[package provide Tcl]"
+ ([string totitle $::tcl_platform(platform)]; U;\
+ $::tcl_platform(os) $::tcl_platform(osVersion))\
+ http/[package provide http] Tcl/[package provide Tcl]"
}
}
@@ -60,14 +64,42 @@ namespace eval http {
variable formMap [array get map]
# Create a map for HTTP/1.1 open sockets
- variable socketmap
- if {[info exists socketmap]} {
- # Close but don't remove open sockets on re-init
- foreach {url sock} [array get socketmap] {
- catch {close $sock}
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+ if {[info exists socketMapping]} {
+ # Close open sockets on re-init. Do not permit retries.
+ foreach {url sock} [array get socketMapping] {
+ unset -nocomplain socketClosing($url)
+ unset -nocomplain socketPlayCmd($url)
+ CloseSocket $sock
}
}
- array set socketmap {}
+
+ # CloseSocket should have unset the socket* arrays, one element at
+ # a time. Now unset anything that was overlooked.
+ # Traces on "unset socketRdState(*)" will call CancelReadPipeline and
+ # cancel any queued responses.
+ # Traces on "unset socketWrState(*)" will call CancelWritePipeline and
+ # cancel any queued requests.
+ array unset socketMapping
+ array unset socketRdState
+ array unset socketWrState
+ array unset socketRdQueue
+ array unset socketWrQueue
+ array unset socketClosing
+ array unset socketPlayCmd
+ array set socketMapping {}
+ array set socketRdState {}
+ array set socketWrState {}
+ array set socketRdQueue {}
+ array set socketWrQueue {}
+ array set socketClosing {}
+ array set socketPlayCmd {}
}
init
@@ -95,8 +127,13 @@ namespace eval http {
set defaultKeepalive 0
}
- namespace export geturl config reset wait formatQuery register unregister
- # Useful, but not exported: data size status code
+ namespace export geturl config reset wait formatQuery quoteString
+ namespace export register unregister registerError
+ # - Useful, but not exported: data, size, status, code, cleanup, error,
+ # meta, ncode, mapReply, init. Comments suggest that "init" can be used
+ # for re-initialisation, although the command is undocumented.
+ # - Not exported, probably should be upper-case initial letter as part
+ # of the internals: getTextLine, make-transformation-chunked.
}
# http::Log --
@@ -190,40 +227,279 @@ proc http::config {args} {
# Arguments:
# token Connection token.
# errormsg (optional) If set, forces status to error.
-# skipCB (optional) If set, don't call the -command callback. This
+# skipCB (optional) If set, don't call the -command callback. This
# is useful when geturl wants to throw an exception instead
# of calling the callback. That way, the same error isn't
# reported to two places.
#
# Side Effects:
-# Closes the socket
+# May close the socket.
proc http::Finish {token {errormsg ""} {skipCB 0}} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
variable $token
upvar 0 $token state
global errorInfo errorCode
+ set closeQueue 0
if {$errormsg ne ""} {
set state(error) [list $errormsg $errorInfo $errorCode]
set state(status) "error"
}
- if { ($state(status) eq "timeout")
+ if {[info commands ${token}EventCoroutine] ne {}} {
+ rename ${token}EventCoroutine {}
+ }
+ if { ($state(status) eq "timeout")
|| ($state(status) eq "error")
+ || ($state(status) eq "eof")
|| ([info exists state(-keepalive)] && !$state(-keepalive))
|| ([info exists state(connection)] && ($state(connection) eq "close"))
} {
- CloseSocket $state(sock) $token
+ set closeQueue 1
+ set connId $state(socketinfo)
+ set sock $state(sock)
+ CloseSocket $state(sock) $token
+ } elseif {
+ ([info exists state(-keepalive)] && $state(-keepalive))
+ && ([info exists state(connection)] && ($state(connection) ne "close"))
+ } {
+ KeepSocket $token
}
if {[info exists state(after)]} {
after cancel $state(after)
+ unset state(after)
}
- if {[info exists state(-command)] && !$skipCB
- && ![info exists state(done-command-cb)]} {
+ if {[info exists state(-command)] && (!$skipCB)
+ && (![info exists state(done-command-cb)])} {
set state(done-command-cb) yes
if {[catch {eval $state(-command) {$token}} err] && $errormsg eq ""} {
set state(error) [list $err $errorInfo $errorCode]
set state(status) error
}
}
+
+ if { $closeQueue
+ && [info exists socketMapping($connId)]
+ && ($socketMapping($connId) eq $sock)
+ } {
+ http::CloseQueuedQueries $connId $token
+ }
+}
+
+# http::KeepSocket -
+#
+# Keep a socket in the persistent sockets table and connect it to its next
+# queued task if possible. Otherwise leave it idle and ready for its next
+# use.
+#
+# If $socketClosing(*), then ($state(connection) eq "close") and therefore
+# this command will not be called by Finish.
+#
+# Arguments:
+# token Connection token.
+
+proc http::KeepSocket {token} {
+ variable http
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ variable $token
+ upvar 0 $token state
+ set tk [namespace tail $token]
+
+ # Keep this socket open for another request ("Keep-Alive").
+ # React if the server half-closes the socket.
+ # Discussion is in http::geturl.
+ catch {fileevent $state(sock) readable [list http::CheckEof $state(sock)]}
+
+ # The line below should not be changed in production code.
+ # It is edited by the test suite.
+ set TEST_EOF 0
+ if {$TEST_EOF} {
+ # ONLY for testing reaction to server eof.
+ # No server timeouts will be caught.
+ catch {fileevent $state(sock) readable {}}
+ }
+
+ if { [info exists state(socketinfo)]
+ && [info exists socketMapping($state(socketinfo))]
+ } {
+ set connId $state(socketinfo)
+ # The value "Rready" is set only here.
+ set socketRdState($connId) Rready
+
+ if { $state(-pipeline)
+ && [info exists socketRdQueue($connId)]
+ && [llength $socketRdQueue($connId)]
+ } {
+ # The usual case for pipelined responses - if another response is
+ # queued, arrange to read it.
+ set token3 [lindex $socketRdQueue($connId) 0]
+ set socketRdQueue($connId) [lrange $socketRdQueue($connId) 1 end]
+ variable $token3
+ upvar 0 $token3 state3
+ set tk2 [namespace tail $token3]
+
+ #Log pipelined, GRANT read access to $token3 in KeepSocket
+ set socketRdState($connId) $token3
+ ReceiveResponse $token3
+
+ # Other pipelined cases.
+ # - The test above ensures that, for the pipelined cases in the two
+ # tests below, the read queue is empty.
+ # - In those two tests, check whether the next write will be
+ # nonpipeline.
+ } elseif {
+ $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "peNding")
+
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && (![set token3 [lindex $socketWrQueue($connId) 0]
+ set ${token3}(-pipeline)
+ ]
+ )
+ } {
+ # This case:
+ # - Now it the time to run the "pending" request.
+ # - The next token in the write queue is nonpipeline, and
+ # socketWrState has been marked "pending" (in
+ # http::NextPipelinedWrite or http::geturl) so a new pipelined
+ # request cannot jump the queue.
+ #
+ # Tests:
+ # - In this case the read queue (tested above) is empty and this
+ # "pending" write token is in front of the rest of the write
+ # queue.
+ # - The write state is not Wready and therefore appears to be busy,
+ # but because it is "pending" we know that it is reserved for the
+ # first item in the write queue, a non-pipelined request that is
+ # waiting for the read queue to empty. That has now happened: so
+ # give that request read and write access.
+ variable $token3
+ set conn [set ${token3}(tmpConnArgs)]
+ #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket
+ set socketRdState($connId) $token3
+ set socketWrState($connId) $token3
+ set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end]
+ # Connect does its own fconfigure.
+ fileevent $state(sock) writable [list http::Connect $token3 {*}$conn]
+ #Log ---- $state(sock) << conn to $token3 for HTTP request (c)
+
+ } elseif {
+ $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "peNding")
+
+ } {
+ # Should not come here. The second block in the previous "elseif"
+ # test should be tautologous (but was needed in an earlier
+ # implementation) and will be removed after testing.
+ # If we get here, the value "pending" was assigned in error.
+ # This error would block the queue for ever.
+ Log ^X$tk <<<<< Error in queueing of requests >>>>> - token $token
+
+ } elseif {
+ $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "Wready")
+
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && (![set token3 [lindex $socketWrQueue($connId) 0]
+ set ${token3}(-pipeline)
+ ]
+ )
+ } {
+ # This case:
+ # - The next token in the write queue is nonpipeline, and
+ # socketWrState is Wready. Get the next event from socketWrQueue.
+ # Tests:
+ # - In this case the read state (tested above) is Rready and the
+ # write state (tested here) is Wready - there is no "pending"
+ # request.
+ # Code:
+ # - The code is the same as the code below for the nonpipelined
+ # case with a queued request.
+ variable $token3
+ set conn [set ${token3}(tmpConnArgs)]
+ #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket
+ set socketRdState($connId) $token3
+ set socketWrState($connId) $token3
+ set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end]
+ # Connect does its own fconfigure.
+ fileevent $state(sock) writable [list http::Connect $token3 {*}$conn]
+ #Log ---- $state(sock) << conn to $token3 for HTTP request (c)
+
+ } elseif {
+ (!$state(-pipeline))
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && ($state(connection) ne "close")
+ } {
+ # If not pipelined, (socketRdState eq Rready) tells us that we are
+ # ready for the next write - there is no need to check
+ # socketWrState. Write the next request, if one is waiting.
+ # If the next request is pipelined, it receives premature read
+ # access to the socket. This is not a problem.
+ set token3 [lindex $socketWrQueue($connId) 0]
+ variable $token3
+ set conn [set ${token3}(tmpConnArgs)]
+ #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket
+ set socketRdState($connId) $token3
+ set socketWrState($connId) $token3
+ set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end]
+ # Connect does its own fconfigure.
+ fileevent $state(sock) writable [list http::Connect $token3 {*}$conn]
+ #Log ---- $state(sock) << conn to $token3 for HTTP request (d)
+
+ } elseif {(!$state(-pipeline))} {
+ set socketWrState($connId) Wready
+ # Rready and Wready and idle: nothing to do.
+ }
+
+ } else {
+ CloseSocket $state(sock) $token
+ # There is no socketMapping($state(socketinfo)), so it does not matter
+ # that CloseQueuedQueries is not called.
+ }
+}
+
+# http::CheckEof -
+#
+# Read from a socket and close it if eof.
+# The command is bound to "fileevent readable" on an idle socket, and
+# "eof" is the only event that should trigger the binding, occurring when
+# the server times out and half-closes the socket.
+#
+# A read is necessary so that [eof] gives a meaningful result.
+# Any bytes sent are junk (or a bug).
+
+proc http::CheckEof {sock} {
+ set junk [read $sock]
+ set n [string length $junk]
+ if {$n} {
+ Log "WARNING: $n bytes received but no HTTP request sent"
+ }
+
+ if {[catch {eof $sock} res] || $res} {
+ # The server has half-closed the socket.
+ # If a new write has started, its transaction will fail and
+ # will then be error-handled.
+ CloseSocket $sock
+ }
}
# http::CloseSocket -
@@ -231,44 +507,137 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} {
# Close a socket and remove it from the persistent sockets table. If
# possible an http token is included here but when we are called from a
# fileevent on remote closure we need to find the correct entry - hence
-# the second section.
+# the "else" block of the first "if" command.
+
+proc http::CloseSocket {s {token {}}} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ set tk [namespace tail $token]
-proc ::http::CloseSocket {s {token {}}} {
- variable socketmap
catch {fileevent $s readable {}}
- set conn_id {}
+ set connId {}
if {$token ne ""} {
- variable $token
- upvar 0 $token state
- if {[info exists state(socketinfo)]} {
- set conn_id $state(socketinfo)
- }
+ variable $token
+ upvar 0 $token state
+ if {[info exists state(socketinfo)]} {
+ set connId $state(socketinfo)
+ }
} else {
- set map [array get socketmap]
- set ndx [lsearch -exact $map $s]
- if {$ndx != -1} {
+ set map [array get socketMapping]
+ set ndx [lsearch -exact $map $s]
+ if {$ndx != -1} {
incr ndx -1
- set conn_id [lindex $map $ndx]
- }
+ set connId [lindex $map $ndx]
+ }
}
- if {$conn_id eq {} || ![info exists socketmap($conn_id)]} {
- Log "Closing socket $s (no connection info)"
- if {[catch {close $s} err]} {
- Log "Error: $err"
+ if { ($connId ne {})
+ && [info exists socketMapping($connId)]
+ && ($socketMapping($connId) eq $s)
+ } {
+ Log "Closing connection $connId (sock $socketMapping($connId))"
+ if {[catch {close $socketMapping($connId)} err]} {
+ Log "Error closing connection: $err"
+ }
+ if {$token eq {}} {
+ # Cases with a non-empty token are handled by Finish, so the tokens
+ # are finished in connection order.
+ http::CloseQueuedQueries $connId
}
} else {
- if {[info exists socketmap($conn_id)]} {
- Log "Closing connection $conn_id (sock $socketmap($conn_id))"
- if {[catch {close $socketmap($conn_id)} err]} {
- Log "Error: $err"
- }
- unset socketmap($conn_id)
- } else {
- Log "Cannot close connection $conn_id - no socket in socket map"
+ Log "Closing socket $s (no connection info)"
+ if {[catch {close $s} err]} {
+ Log "Error closing socket: $err"
}
}
}
+# http::CloseQueuedQueries
+#
+# connId - identifier "domain:port" for the connection
+# token - (optional) used only for logging
+#
+# Called from http::CloseSocket and http::Finish, after a connection is closed,
+# to clear the read and write queues if this has not already been done.
+
+proc http::CloseQueuedQueries {connId {token {}}} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ if {![info exists socketMapping($connId)]} {
+ # Command has already been called.
+ # Don't come here again - especially recursively.
+ return
+ }
+
+ # Used only for logging.
+ if {$token eq {}} {
+ set tk {}
+ } else {
+ set tk [namespace tail $token]
+ }
+
+ if { [info exists socketPlayCmd($connId)]
+ && ($socketPlayCmd($connId) ne {ReplayIfClose Wready {} {}})
+ } {
+ # Before unsetting, there is some unfinished business.
+ # - If the server sent "Connection: close", we have stored the command
+ # for retrying any queued requests in socketPlayCmd, so copy that
+ # value for execution below. socketClosing(*) was also set.
+ # - Also clear the queues to prevent calls to Finish that would set the
+ # state for the requests that will be retried to "finished with error
+ # status".
+ set unfinished $socketPlayCmd($connId)
+ set socketRdQueue($connId) {}
+ set socketWrQueue($connId) {}
+ } else {
+ set unfinished {}
+ }
+
+ Unset $connId
+
+ if {$unfinished ne {}} {
+ Log ^R$tk Any unfinished transactions (excluding $token) failed \
+ - token $token
+ {*}$unfinished
+ }
+}
+
+# http::Unset
+#
+# The trace on "unset socketRdState(*)" will call CancelReadPipeline
+# and cancel any queued responses.
+# The trace on "unset socketWrState(*)" will call CancelWritePipeline
+# and cancel any queued requests.
+
+proc http::Unset {connId} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ unset socketMapping($connId)
+ unset socketRdState($connId)
+ unset socketWrState($connId)
+ unset -nocomplain socketRdQueue($connId)
+ unset -nocomplain socketWrQueue($connId)
+ unset -nocomplain socketClosing($connId)
+ unset -nocomplain socketPlayCmd($connId)
+}
+
# http::reset --
#
# See documentation for details.
@@ -278,7 +647,7 @@ proc ::http::CloseSocket {s {token {}}} {
# why Status info.
#
# Side Effects:
-# See Finish
+# See Finish
proc http::reset {token {why reset}} {
variable $token
@@ -299,8 +668,8 @@ proc http::reset {token {why reset}} {
# Establishes a connection to a remote url via http.
#
# Arguments:
-# url The http URL to goget.
-# args Option value pairs. Valid options include:
+# url The http URL to goget.
+# args Option value pairs. Valid options include:
# -blocksize, -validate, -headers, -timeout
# Results:
# Returns a token for this connection. This token is the name of an
@@ -320,9 +689,12 @@ proc http::geturl {url args} {
set http(uid) 0
}
set token [namespace current]::[incr http(uid)]
+ ##Log Starting http::geturl - token $token
variable $token
upvar 0 $token state
+ set tk [namespace tail $token]
reset $token
+ Log ^A$tk URL $url - token $token
# Process command options.
@@ -337,8 +709,9 @@ proc http::geturl {url args} {
-queryprogress {}
-protocol 1.1
binary 0
- state connecting
+ state created
meta {}
+ method {}
coding {}
currentsize 0
totalsize 0
@@ -555,14 +928,7 @@ proc http::geturl {url args} {
# Don't append the fragment!
set state(url) $url
- # If a timeout is specified we set up the after event and arrange for an
- # asynchronous socket connection.
-
set sockopts [list -async]
- if {$state(-timeout) > 0} {
- set state(after) [after $state(-timeout) \
- [list http::reset $token timeout]]
- }
# If we are using the proxy, we must pass in the full URL that includes
# the server name.
@@ -580,51 +946,295 @@ proc http::geturl {url args} {
# c11a51c482]
set state(accept-types) $http(-accept)
+ if {$isQuery || $isQueryChannel} {
+ # It's a POST.
+ # A client wishing to send a non-idempotent request SHOULD wait to send
+ # that request until it has received the response status for the
+ # previous request.
+ if {$http(-postfresh)} {
+ # Override -keepalive for a POST. Use a new connection, and thus
+ # avoid the small risk of a race against server timeout.
+ set state(-keepalive) 0
+ } else {
+ # Allow -keepalive but do not -pipeline - wait for the previous
+ # transaction to finish.
+ # There is a small risk of a race against server timeout.
+ set state(-pipeline) 0
+ }
+ } else {
+ # It's a GET or HEAD.
+ set state(-pipeline) $http(-pipeline)
+ }
+
# See if we are supposed to use a previously opened channel.
+ # - In principle, ANY call to http::geturl could use a previously opened
+ # channel if it is available - the "Connection: keep-alive" header is a
+ # request to leave the channel open AFTER completion of this call.
+ # - In fact, we try to use an existing channel only if -keepalive 1 -- this
+ # means that at most one channel is left open for each value of
+ # $state(socketinfo). This property simplifies the mapping of open
+ # channels.
+ set reusing 0
+ set alreadyQueued 0
if {$state(-keepalive)} {
- variable socketmap
- if {[info exists socketmap($state(socketinfo))]} {
- if {[catch {fconfigure $socketmap($state(socketinfo))}]} {
- Log "WARNING: socket for $state(socketinfo) was closed"
- unset socketmap($state(socketinfo))
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ if {[info exists socketMapping($state(socketinfo))]} {
+ # - If the connection is idle, it has a "fileevent readable" binding
+ # to http::CheckEof, in case the server times out and half-closes
+ # the socket (http::CheckEof closes the other half).
+ # - We leave this binding in place until just before the last
+ # puts+flush in http::Connected (GET/HEAD) or http::Write (POST),
+ # after which the HTTP response might be generated.
+
+ if { [info exists socketClosing($state(socketinfo))]
+ && $socketClosing($state(socketinfo))
+ } {
+ # socketClosing(*) is set because the server has sent a
+ # "Connection: close" header.
+ # Do not use the persistent socket again.
+ # Since we have only one persistent socket per server, and the
+ # old socket is not yet dead, add the request to the write queue
+ # of the dying socket, which will be replayed by ReplayIfClose.
+ # Also add it to socketWrQueue(*) which is used only if an error
+ # causes a call to Finish.
+ set reusing 1
+ set sock $socketMapping($state(socketinfo))
+ Log "reusing socket $sock for $state(socketinfo) - token $token"
+
+ set alreadyQueued 1
+ lassign $socketPlayCmd($state(socketinfo)) com0 com1 com2 com3
+ lappend com3 $token
+ set socketPlayCmd($state(socketinfo)) [list $com0 $com1 $com2 $com3]
+ lappend socketWrQueue($state(socketinfo)) $token
+ } elseif {[catch {fconfigure $socketMapping($state(socketinfo))}]} {
+ # FIXME Is it still possible for this code to be executed? If
+ # so, this could be another place to call TestForReplay,
+ # rather than discarding the queued transactions.
+ Log "WARNING: socket for $state(socketinfo) was closed\
+ - token $token"
+ Log "WARNING - if testing, pay special attention to this\
+ case (GH) which is seldom executed - token $token"
+
+ # This will call CancelReadPipeline, CancelWritePipeline, and
+ # cancel any queued requests, responses.
+ Unset $state(socketinfo)
} else {
- set sock $socketmap($state(socketinfo))
- Log "reusing socket $sock for $state(socketinfo)"
- catch {fileevent $sock writable {}}
- catch {fileevent $sock readable {}}
+ # Use the persistent socket.
+ # The socket may not be ready to write: an earlier request might
+ # still be still writing (in the pipelined case) or
+ # writing/reading (in the nonpipeline case). This possibility
+ # is handled by socketWrQueue later in this command.
+ set reusing 1
+ set sock $socketMapping($state(socketinfo))
+ Log "reusing socket $sock for $state(socketinfo) - token $token"
+
}
+ # Do not automatically close the connection socket.
+ set state(connection) {}
}
- # don't automatically close this connection socket
- set state(connection) {}
}
+
+ if {$reusing} {
+ # Define state(tmpState) and state(tmpOpenCmd) for use
+ # by http::ReplayIfDead if the persistent connection has died.
+ set state(tmpState) [array get state]
+
+ # Pass -myaddr directly to the socket command
+ if {[info exists state(-myaddr)]} {
+ lappend sockopts -myaddr $state(-myaddr)
+ }
+
+ set state(tmpOpenCmd) [list {*}$defcmd {*}$sockopts {*}$targetAddr]
+ }
+
+ set state(reusing) $reusing
+ # Excluding ReplayIfDead and the decision whether to call it, there are four
+ # places outside http::geturl where state(reusing) is used:
+ # - Connected - if reusing and not pipelined, start the state(-timeout)
+ # timeout (when writing).
+ # - DoneRequest - if reusing and pipelined, send the next pipelined write
+ # - Event - if reusing and pipelined, start the state(-timeout)
+ # timeout (when reading).
+ # - Event - if (not reusing) and pipelined, send the next pipelined
+ # write
+
+ # See comments above re the start of this timeout in other cases.
+ if {(!$state(reusing)) && ($state(-timeout) > 0)} {
+ set state(after) [after $state(-timeout) \
+ [list http::reset $token timeout]]
+ }
+
if {![info exists sock]} {
# Pass -myaddr directly to the socket command
if {[info exists state(-myaddr)]} {
lappend sockopts -myaddr $state(-myaddr)
}
- if {[catch {eval $defcmd $sockopts $targetAddr} sock]} {
- # something went wrong while trying to establish the connection.
+ set pre [clock milliseconds]
+ ##Log pre socket opened, - token $token
+ ##Log [concat $defcmd $sockopts $targetAddr] - token $token
+ if {[catch {eval $defcmd $sockopts $targetAddr} sock errdict]} {
+ # Something went wrong while trying to establish the connection.
# Clean up after events and such, but DON'T call the command
# callback (if available) because we're going to throw an
# exception from here instead.
- set state(sock) $sock
- Finish $token "" 1
+ set state(sock) NONE
+ Finish $token $sock 1
cleanup $token
- return -code error $sock
- }
+ dict unset errdict -level
+ return -options $errdict $sock
+ } else {
+ # Initialisation of a new socket.
+ ##Log post socket opened, - token $token
+ ##Log socket opened, now fconfigure - token $token
+ set delay [expr {[clock milliseconds] - $pre}]
+ if {$delay > 3000} {
+ Log socket delay $delay - token $token
+ }
+ fconfigure $sock -translation {auto crlf} \
+ -buffersize $state(-blocksize)
+ ##Log socket opened, DONE fconfigure - token $token
+ }
}
+ # Command [socket] is called with -async, but takes 5s to 5.1s to return,
+ # with probability of order 1 in 10,000. This may be a bizarre scheduling
+ # issue with my (KJN's) system (Fedora Linux).
+ # This does not cause a problem (unless the request times out when this
+ # command returns).
+
set state(sock) $sock
- Log "Using $sock for $state(socketinfo)" \
- [expr {$state(-keepalive)?"keepalive":""}]
- if {$state(-keepalive)} {
- set socketmap($state(socketinfo)) $sock
+ Log "Using $sock for $state(socketinfo) - token $token" \
+ [expr {$state(-keepalive)?"keepalive":""}]
+
+ if { $state(-keepalive)
+ && (![info exists socketMapping($state(socketinfo))])
+ } {
+ # Freshly-opened socket that we would like to become persistent.
+ set socketMapping($state(socketinfo)) $sock
+
+ if {![info exists socketRdState($state(socketinfo))]} {
+ set socketRdState($state(socketinfo)) {}
+ set varName ::http::socketRdState($state(socketinfo))
+ trace add variable $varName unset ::http::CancelReadPipeline
+ }
+ if {![info exists socketWrState($state(socketinfo))]} {
+ set socketWrState($state(socketinfo)) {}
+ set varName ::http::socketWrState($state(socketinfo))
+ trace add variable $varName unset ::http::CancelWritePipeline
+ }
+
+ if {$state(-pipeline)} {
+ #Log new, init for pipelined, GRANT write access to $token in geturl
+ # Also grant premature read access to the socket. This is OK.
+ set socketRdState($state(socketinfo)) $token
+ set socketWrState($state(socketinfo)) $token
+ } else {
+ # socketWrState is not used by this non-pipelined transaction.
+ # We cannot leave it as "Wready" because the next call to
+ # http::geturl with a pipelined transaction would conclude that the
+ # socket is available for writing.
+ #Log new, init for nonpipeline, GRANT r/w access to $token in geturl
+ set socketRdState($state(socketinfo)) $token
+ set socketWrState($state(socketinfo)) $token
+ }
+
+ set socketRdQueue($state(socketinfo)) {}
+ set socketWrQueue($state(socketinfo)) {}
+ set socketClosing($state(socketinfo)) 0
+ set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}}
}
if {![info exists phost]} {
set phost ""
}
- fileevent $sock writable [list http::Connect $token $proto $phost $srvurl]
+ if {$reusing} {
+ # For use by http::ReplayIfDead if the persistent connection has died.
+ # Also used by NextPipelinedWrite.
+ set state(tmpConnArgs) [list $proto $phost $srvurl]
+ }
+
+ # The element socketWrState($connId) has a value which is either the name of
+ # the token that is permitted to write to the socket, or "Wready" if no
+ # token is permitted to write.
+ #
+ # The code that sets the value to Wready immediately calls
+ # http::NextPipelinedWrite, which examines socketWrQueue($connId) and
+ # processes the next request in the queue, if there is one. The value
+ # Wready is not found when the interpreter is in the event loop unless the
+ # socket is idle.
+ #
+ # The element socketRdState($connId) has a value which is either the name of
+ # the token that is permitted to read from the socket, or "Rready" if no
+ # token is permitted to read.
+ #
+ # The code that sets the value to Rready then examines
+ # socketRdQueue($connId) and processes the next request in the queue, if
+ # there is one. The value Rready is not found when the interpreter is in
+ # the event loop unless the socket is idle.
+
+ if {$alreadyQueued} {
+ # A write may or may not be in progress. There is no need to set
+ # socketWrState to prevent another call stealing write access - all
+ # subsequent calls on this socket will come here because the socket
+ # will close after the current read, and its
+ # socketClosing($connId) is 1.
+ ##Log "HTTP request for token $token is queued"
+
+ } elseif { $reusing
+ && $state(-pipeline)
+ && ($socketWrState($state(socketinfo)) ne "Wready")
+ } {
+ ##Log "HTTP request for token $token is queued for pipelined use"
+ lappend socketWrQueue($state(socketinfo)) $token
+
+ } elseif { $reusing
+ && (!$state(-pipeline))
+ && ($socketWrState($state(socketinfo)) ne "Wready")
+ } {
+ # A write is queued or in progress. Lappend to the write queue.
+ ##Log "HTTP request for token $token is queued for nonpipeline use"
+ lappend socketWrQueue($state(socketinfo)) $token
+
+ } elseif { $reusing
+ && (!$state(-pipeline))
+ && ($socketWrState($state(socketinfo)) eq "Wready")
+ && ($socketRdState($state(socketinfo)) ne "Rready")
+ } {
+ # A read is queued or in progress, but not a write. Cannot start the
+ # nonpipeline transaction, but must set socketWrState to prevent a
+ # pipelined request jumping the queue.
+ ##Log "HTTP request for token $token is queued for nonpipeline use"
+ #Log re-use nonpipeline, GRANT delayed write access to $token in geturl
+
+ set socketWrState($state(socketinfo)) peNding
+ lappend socketWrQueue($state(socketinfo)) $token
+
+ } else {
+ if {$reusing && $state(-pipeline)} {
+ #Log re-use pipelined, GRANT write access to $token in geturl
+ set socketWrState($state(socketinfo)) $token
+
+ } elseif {$reusing} {
+ # Cf tests above - both are ready.
+ #Log re-use nonpipeline, GRANT r/w access to $token in geturl
+ set socketRdState($state(socketinfo)) $token
+ set socketWrState($state(socketinfo)) $token
+ }
+
+ # All (!$reusing) cases come here, and also some $reusing cases if the
+ # connection is ready.
+ #Log ---- $state(socketinfo) << conn to $token for HTTP request (a)
+ # Connect does its own fconfigure.
+ fileevent $sock writable \
+ [list http::Connect $token $proto $phost $srvurl]
+ }
# Wait for the connection to complete.
if {![info exists state(-command)]} {
@@ -647,7 +1257,7 @@ proc http::geturl {url args} {
return -code error $err
}
}
-
+ ##Log Leaving http::geturl - token $token
return $token
}
@@ -657,8 +1267,8 @@ proc http::geturl {url args} {
# established.
#
# Arguments:
-# token State token.
-# proto What protocol (http, https, etc.) was used to connect.
+# token State token.
+# proto What protocol (http, https, etc.) was used to connect.
# phost Are we using keep-alive? Non-empty if yes.
# srvurl Service-local URL that we're requesting
# Results:
@@ -667,11 +1277,24 @@ proc http::geturl {url args} {
proc http::Connected {token proto phost srvurl} {
variable http
variable urlTypes
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
variable $token
upvar 0 $token state
+ set tk [namespace tail $token]
+
+ if {$state(reusing) && (!$state(-pipeline)) && ($state(-timeout) > 0)} {
+ set state(after) [after $state(-timeout) \
+ [list http::reset $token timeout]]
+ }
- # Set back the variables needed here
+ # Set back the variables needed here.
set sock $state(sock)
set isQueryChannel [info exists state(-querychannel)]
set isQuery [info exists state(-query)]
@@ -681,9 +1304,12 @@ proc http::Connected {token proto phost srvurl} {
set lower [string tolower $proto]
set defport [lindex $urlTypes($lower) 0]
- # Send data in cr-lf format, but accept any line terminators
-
- fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize)
+ # Send data in cr-lf format, but accept any line terminators.
+ # Initialisation to {auto *} now done in geturl, KeepSocket and DoneRequest.
+ # We are concerned here with the request (write) not the response (read).
+ lassign [fconfigure $sock -translation] trRead trWrite
+ fconfigure $sock -translation [list $trRead crlf] \
+ -buffersize $state(-blocksize)
# The following is disallowed in safe interpreters, but the socket is
# already in non-blocking mode in that case.
@@ -706,10 +1332,12 @@ proc http::Connected {token proto phost srvurl} {
set how POST
# The query channel must be blocking for the async Write to
# work properly.
- fconfigure $state(-querychannel) -blocking 1 -translation binary
+ lassign [fconfigure $sock -translation] trRead trWrite
+ fconfigure $state(-querychannel) -blocking 1 \
+ -translation [list $trRead binary]
set contDone 0
}
- if {[info exists state(-method)] && $state(-method) ne ""} {
+ if {[info exists state(-method)] && ($state(-method) ne "")} {
set how $state(-method)
}
# We cannot handle chunked encodings with -handler, so force HTTP/1.0
@@ -718,7 +1346,11 @@ proc http::Connected {token proto phost srvurl} {
set state(-protocol) 1.0
}
set accept_types_seen 0
+
+ Log ^B$tk begin sending request - token $token
+
if {[catch {
+ set state(method) $how
puts $sock "$how $srvurl HTTP/$state(-protocol)"
if {[dict exists $state(-headers) Host]} {
# Allow Host spoofing. [Bug 928154]
@@ -731,16 +1363,18 @@ proc http::Connected {token proto phost srvurl} {
puts $sock "Host: $host:$port"
}
puts $sock "User-Agent: $http(-useragent)"
- if {$state(-protocol) == 1.0 && $state(-keepalive)} {
+ if {($state(-protocol) >= 1.0) && $state(-keepalive)} {
+ # Send this header, because a 1.1 server is not compelled to treat
+ # this as the default.
puts $sock "Connection: keep-alive"
- }
- if {$state(-protocol) > 1.0 && !$state(-keepalive)} {
+ }
+ if {($state(-protocol) > 1.0) && !$state(-keepalive)} {
puts $sock "Connection: close" ;# RFC2616 sec 8.1.2.1
- }
- if {[info exists phost] && ($phost ne "") && $state(-keepalive)} {
+ }
+ if {[info exists phost] && ($phost ne "") && $state(-keepalive)} {
puts $sock "Proxy-Connection: Keep-Alive"
- }
- set accept_encoding_seen 0
+ }
+ set accept_encoding_seen 0
set content_type_seen 0
dict for {key value} $state(-headers) {
set value [string map [list \n "" \r ""] $value]
@@ -770,10 +1404,13 @@ proc http::Connected {token proto phost srvurl} {
if {!$accept_types_seen} {
puts $sock "Accept: $state(accept-types)"
}
- if {!$accept_encoding_seen && ![info exists state(-handler)]} {
+ if { (!$accept_encoding_seen)
+ && (![info exists state(-handler)])
+ && $http(-zip)
+ } {
puts $sock "Accept-Encoding: gzip,deflate,compress"
- }
- if {$isQueryChannel && $state(querylength) == 0} {
+ }
+ if {$isQueryChannel && ($state(querylength) == 0)} {
# Try to determine size of data in channel. If we cannot seek, the
# surrounding catch will trap us
@@ -802,6 +1439,7 @@ proc http::Connected {token proto phost srvurl} {
# response.
if {$isQuery || $isQueryChannel} {
+ # POST method.
if {!$content_type_seen} {
puts $sock "Content-Type: $state(-type)"
}
@@ -809,29 +1447,753 @@ proc http::Connected {token proto phost srvurl} {
puts $sock "Content-Length: $state(querylength)"
}
puts $sock ""
- fconfigure $sock -translation {auto binary}
+ flush $sock
+ # Flush flushes the error in the https case with a bad handshake:
+ # else the socket never becomes writable again, and hangs until
+ # timeout (if any).
+
+ lassign [fconfigure $sock -translation] trRead trWrite
+ fconfigure $sock -translation [list $trRead binary]
fileevent $sock writable [list http::Write $token]
+ # The http::Write command decides when to make the socket readable,
+ # using the same test as the GET/HEAD case below.
} else {
+ # GET or HEAD method.
+ if { (![catch {fileevent $sock readable} binding])
+ && ($binding eq [list http::CheckEof $sock])
+ } {
+ # Remove the "fileevent readable" binding of an idle persistent
+ # socket to http::CheckEof. We can no longer treat bytes
+ # received as junk. The server might still time out and
+ # half-close the socket if it has not yet received the first
+ # "puts".
+ fileevent $sock readable {}
+ }
puts $sock ""
flush $sock
- fileevent $sock readable [list http::Event $sock $token]
+ Log ^C$tk end sending request - token $token
+ # End of writing (GET/HEAD methods). The request has been sent.
+
+ DoneRequest $token
}
} err]} {
- # The socket probably was never connected, or the connection dropped
- # later.
+ # The socket probably was never connected, OR the connection dropped
+ # later, OR https handshake error, which may be discovered as late as
+ # the "flush" command above...
+ Log "WARNING - if testing, pay special attention to this\
+ case (GI) which is seldom executed - token $token"
+ if {[info exists state(reusing)] && $state(reusing)} {
+ # The socket was closed at the server end, and closed at
+ # this end by http::CheckEof.
+ if {[TestForReplay $token write $err a]} {
+ return
+ } else {
+ Finish $token {failed to re-use socket}
+ }
- # if state(status) is error, it means someone's already called Finish
- # to do the above-described clean up.
- if {$state(status) ne "error"} {
+ # else:
+ # This is NOT a persistent socket that has been closed since its
+ # last use.
+ # If any other requests are in flight or pipelined/queued, they will
+ # be discarded.
+ } elseif {$state(status) eq ""} {
+ # ...https handshake errors come here.
+ set msg [registerError $sock]
+ registerError $sock {}
+ if {$msg eq {}} {
+ set msg {failed to use socket}
+ }
+ Finish $token $msg
+ } elseif {$state(status) ne "error"} {
Finish $token $err
}
}
}
+# http::registerError
+#
+# Called (for example when processing TclTLS activity) to register
+# an error for a connection on a specific socket. This helps
+# http::Connected to deliver meaningful error messages, e.g. when a TLS
+# certificate fails verification.
+#
+# Usage: http::registerError socket ?newValue?
+#
+# "set" semantics, except that a "get" (a call without a new value) for a
+# non-existent socket returns {}, not an error.
+
+proc http::registerError {sock args} {
+ variable registeredErrors
+
+ if { ([llength $args] == 0)
+ && (![info exists registeredErrors($sock)])
+ } {
+ return
+ } elseif { ([llength $args] == 1)
+ && ([lindex $args 0] eq {})
+ } {
+ unset -nocomplain registeredErrors($sock)
+ return
+ }
+ set registeredErrors($sock) {*}$args
+}
+
+# http::DoneRequest --
+#
+# Command called when a request has been sent. It will arrange the
+# next request and/or response as appropriate.
+#
+# If this command is called when $socketClosing(*), the request $token
+# that calls it must be pipelined and destined to fail.
+
+proc http::DoneRequest {token} {
+ variable http
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ variable $token
+ upvar 0 $token state
+ set tk [namespace tail $token]
+ set sock $state(sock)
+
+ # If pipelined, connect the next HTTP request to the socket.
+ if {$state(reusing) && $state(-pipeline)} {
+ # Enable next token (if any) to write.
+ # The value "Wready" is set only here, and
+ # in http::Event after reading the response-headers of a
+ # non-reusing transaction.
+ # Previous value is $token. It cannot be pending.
+ set socketWrState($state(socketinfo)) Wready
+
+ # Now ready to write the next pipelined request (if any).
+ http::NextPipelinedWrite $token
+ } else {
+ # If pipelined, this is the first transaction on this socket. We wait
+ # for the response headers to discover whether the connection is
+ # persistent. (If this is not done and the connection is not
+ # persistent, we SHOULD retry and then MUST NOT pipeline before knowing
+ # that we have a persistent connection
+ # (rfc2616 8.1.2.2)).
+ }
+
+ # Connect to receive the response, unless the socket is pipelined
+ # and another response is being sent.
+ # This code block is separate from the code below because there are
+ # cases where socketRdState already has the value $token.
+ if { $state(-keepalive)
+ && $state(-pipeline)
+ && [info exists socketRdState($state(socketinfo))]
+ && ($socketRdState($state(socketinfo)) eq "Rready")
+ } {
+ #Log pipelined, GRANT read access to $token in Connected
+ set socketRdState($state(socketinfo)) $token
+ }
+
+ if { $state(-keepalive)
+ && $state(-pipeline)
+ && [info exists socketRdState($state(socketinfo))]
+ && ($socketRdState($state(socketinfo)) ne $token)
+ } {
+ # Do not read from the socket until it is ready.
+ ##Log "HTTP response for token $token is queued for pipelined use"
+ # If $socketClosing(*), then the caller will be a pipelined write and
+ # execution will come here.
+ # This token has already been recorded as "in flight" for writing.
+ # When the socket is closed, the read queue will be cleared in
+ # CloseQueuedQueries and so the "lappend" here has no effect.
+ lappend socketRdQueue($state(socketinfo)) $token
+ } else {
+ # In the pipelined case, connection for reading depends on the
+ # value of socketRdState.
+ # In the nonpipeline case, connection for reading always occurs.
+ ReceiveResponse $token
+ }
+}
+
+# http::ReceiveResponse
+#
+# Connects token to its socket for reading.
+
+proc http::ReceiveResponse {token} {
+ variable $token
+ upvar 0 $token state
+ set tk [namespace tail $token]
+ set sock $state(sock)
+
+ #Log ---- $state(socketinfo) >> conn to $token for HTTP response
+ lassign [fconfigure $sock -translation] trRead trWrite
+ fconfigure $sock -translation [list auto $trWrite] \
+ -buffersize $state(-blocksize)
+ Log ^D$tk begin receiving response - token $token
+
+ coroutine ${token}EventCoroutine http::Event $sock $token
+ fileevent $sock readable ${token}EventCoroutine
+}
+
+# http::NextPipelinedWrite
+#
+# - Connecting a socket to a token for writing is done by this command and by
+# command KeepSocket.
+# - If another request has a pipelined write scheduled for $token's socket,
+# and if the socket is ready to accept it, connect the write and update
+# the queue accordingly.
+# - This command is called from http::DoneRequest and http::Event,
+# IF $state(-pipeline) AND (the current transfer has reached the point at
+# which the socket is ready for the next request to be written).
+# - This command is called when a token has write access and is pipelined and
+# keep-alive, and sets socketWrState to Wready.
+# - The command need not consider the case where socketWrState is set to a token
+# that does not yet have write access. Such a token is waiting for Rready,
+# and the assignment of the connection to the token will be done elsewhere (in
+# http::KeepSocket).
+# - This command cannot be called after socketWrState has been set to a
+# "pending" token value (that is then overwritten by the caller), because that
+# value is set by this command when it is called by an earlier token when it
+# relinquishes its write access, and the pending token is always the next in
+# line to write.
+
+proc http::NextPipelinedWrite {token} {
+ variable http
+ variable socketRdState
+ variable socketWrState
+ variable socketWrQueue
+ variable socketClosing
+ variable $token
+ upvar 0 $token state
+ set connId $state(socketinfo)
+
+ if { [info exists socketClosing($connId)]
+ && $socketClosing($connId)
+ } {
+ # socketClosing(*) is set because the server has sent a
+ # "Connection: close" header.
+ # Behave as if the queues are empty - so do nothing.
+ } elseif { $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "Wready")
+
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && ([set token2 [lindex $socketWrQueue($connId) 0]
+ set ${token2}(-pipeline)
+ ]
+ )
+ } {
+ # - The usual case for a pipelined connection, ready for a new request.
+ #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite
+ set conn [set ${token2}(tmpConnArgs)]
+ set socketWrState($connId) $token2
+ set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end]
+ # Connect does its own fconfigure.
+ fileevent $state(sock) writable [list http::Connect $token2 {*}$conn]
+ #Log ---- $connId << conn to $token2 for HTTP request (b)
+
+ # In the tests below, the next request will be nonpipeline.
+ } elseif { $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "Wready")
+
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && (![ set token3 [lindex $socketWrQueue($connId) 0]
+ set ${token3}(-pipeline)
+ ]
+ )
+
+ && [info exists socketRdState($connId)]
+ && ($socketRdState($connId) eq "Rready")
+ } {
+ # The case in which the next request will be non-pipelined, and the read
+ # and write queues is ready: which is the condition for a non-pipelined
+ # write.
+ variable $token3
+ upvar 0 $token3 state3
+ set conn [set ${token3}(tmpConnArgs)]
+ #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite
+ set socketRdState($connId) $token3
+ set socketWrState($connId) $token3
+ set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end]
+ # Connect does its own fconfigure.
+ fileevent $state(sock) writable [list http::Connect $token3 {*}$conn]
+ #Log ---- $state(sock) << conn to $token3 for HTTP request (c)
+
+ } elseif { $state(-pipeline)
+ && [info exists socketWrState($connId)]
+ && ($socketWrState($connId) eq "Wready")
+
+ && [info exists socketWrQueue($connId)]
+ && [llength $socketWrQueue($connId)]
+ && (![set token2 [lindex $socketWrQueue($connId) 0]
+ set ${token2}(-pipeline)
+ ]
+ )
+ } {
+ # - The case in which the next request will be non-pipelined, but the
+ # read queue is NOT ready.
+ # - A read is queued or in progress, but not a write. Cannot start the
+ # nonpipeline transaction, but must set socketWrState to prevent a new
+ # pipelined request (in http::geturl) jumping the queue.
+ # - Because socketWrState($connId) is not set to Wready, the assignment
+ # of the connection to $token2 will be done elsewhere - by command
+ # http::KeepSocket when $socketRdState($connId) is set to "Rready".
+
+ #Log re-use nonpipeline, GRANT delayed write access to $token in NextP..
+ set socketWrState($connId) peNding
+ }
+}
+
+# http::CancelReadPipeline
+#
+# Cancel pipelined responses on a closing "Keep-Alive" socket.
+#
+# - Called by a variable trace on "unset socketRdState($connId)".
+# - The variable relates to a Keep-Alive socket, which has been closed.
+# - Cancels all pipelined responses. The requests have been sent,
+# the responses have not yet been received.
+# - This is a hard cancel that ends each transaction with error status,
+# and closes the connection. Do not use it if you want to replay failed
+# transactions.
+# - N.B. Always delete ::http::socketRdState($connId) before deleting
+# ::http::socketRdQueue($connId), or this command will do nothing.
+#
+# Arguments
+# As for a trace command on a variable.
+
+proc http::CancelReadPipeline {name1 connId op} {
+ variable socketRdQueue
+ ##Log CancelReadPipeline $name1 $connId $op
+ if {[info exists socketRdQueue($connId)]} {
+ set msg {the connection was closed by CancelReadPipeline}
+ foreach token $socketRdQueue($connId) {
+ set tk [namespace tail $token]
+ Log ^X$tk end of response "($msg)" - token $token
+ set ${token}(status) eof
+ Finish $token ;#$msg
+ }
+ set socketRdQueue($connId) {}
+ }
+}
+
+# http::CancelWritePipeline
+#
+# Cancel queued events on a closing "Keep-Alive" socket.
+#
+# - Called by a variable trace on "unset socketWrState($connId)".
+# - The variable relates to a Keep-Alive socket, which has been closed.
+# - In pipelined or nonpipeline case: cancels all queued requests. The
+# requests have not yet been sent, the responses are not due.
+# - This is a hard cancel that ends each transaction with error status,
+# and closes the connection. Do not use it if you want to replay failed
+# transactions.
+# - N.B. Always delete ::http::socketWrState($connId) before deleting
+# ::http::socketWrQueue($connId), or this command will do nothing.
+#
+# Arguments
+# As for a trace command on a variable.
+
+proc http::CancelWritePipeline {name1 connId op} {
+ variable socketWrQueue
+
+ ##Log CancelWritePipeline $name1 $connId $op
+ if {[info exists socketWrQueue($connId)]} {
+ set msg {the connection was closed by CancelWritePipeline}
+ foreach token $socketWrQueue($connId) {
+ set tk [namespace tail $token]
+ Log ^X$tk end of response "($msg)" - token $token
+ set ${token}(status) eof
+ Finish $token ;#$msg
+ }
+ set socketWrQueue($connId) {}
+ }
+}
+
+# http::ReplayIfDead --
+#
+# - A query on a re-used persistent socket failed at the earliest opportunity,
+# because the socket had been closed by the server. Keep the token, tidy up,
+# and try to connect on a fresh socket.
+# - The connection is monitored for eof by the command http::CheckEof. Thus
+# http::ReplayIfDead is needed only when a server event (half-closing an
+# apparently idle connection), and a client event (sending a request) occur at
+# almost the same time, and neither client nor server detects the other's
+# action before performing its own (an "asynchronous close event").
+# - To simplify testing of http::ReplayIfDead, set TEST_EOF 1 in
+# http::KeepSocket, and then http::ReplayIfDead will be called if http::geturl
+# is called at any time after the server timeout.
+#
+# Arguments:
+# token Connection token.
+#
+# Side Effects:
+# Use the same token, but try to open a new socket.
+
+proc http::ReplayIfDead {tokenArg doing} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ variable $tokenArg
+ upvar 0 $tokenArg stateArg
+
+ Log running http::ReplayIfDead for $tokenArg $doing
+
+ # 1. Merge the tokens for transactions in flight, the read (response) queue,
+ # and the write (request) queue.
+
+ set InFlightR {}
+ set InFlightW {}
+
+ # Obtain the tokens for transactions in flight.
+ if {$stateArg(-pipeline)} {
+ # Two transactions may be in flight. The "read" transaction was first.
+ # It is unlikely that the server would close the socket if a response
+ # was pending; however, an earlier request (as well as the present
+ # request) may have been sent and ignored if the socket was half-closed
+ # by the server.
+
+ if { [info exists socketRdState($stateArg(socketinfo))]
+ && ($socketRdState($stateArg(socketinfo)) ne "Rready")
+ } {
+ lappend InFlightR $socketRdState($stateArg(socketinfo))
+ } elseif {($doing eq "read")} {
+ lappend InFlightR $tokenArg
+ }
+
+ if { [info exists socketWrState($stateArg(socketinfo))]
+ && $socketWrState($stateArg(socketinfo)) ni {Wready peNding}
+ } {
+ lappend InFlightW $socketWrState($stateArg(socketinfo))
+ } elseif {($doing eq "write")} {
+ lappend InFlightW $tokenArg
+ }
+
+ # Report any inconsistency of $tokenArg with socket*state.
+ if { ($doing eq "read")
+ && [info exists socketRdState($stateArg(socketinfo))]
+ && ($tokenArg ne $socketRdState($stateArg(socketinfo)))
+ } {
+ Log WARNING - ReplayIfDead pipelined tokenArg $tokenArg $doing \
+ ne socketRdState($stateArg(socketinfo)) \
+ $socketRdState($stateArg(socketinfo))
+
+ } elseif {
+ ($doing eq "write")
+ && [info exists socketWrState($stateArg(socketinfo))]
+ && ($tokenArg ne $socketWrState($stateArg(socketinfo)))
+ } {
+ Log WARNING - ReplayIfDead pipelined tokenArg $tokenArg $doing \
+ ne socketWrState($stateArg(socketinfo)) \
+ $socketWrState($stateArg(socketinfo))
+ }
+ } else {
+ # One transaction should be in flight.
+ # socketRdState, socketWrQueue are used.
+ # socketRdQueue should be empty.
+
+ # Report any inconsistency of $tokenArg with socket*state.
+ if {$tokenArg ne $socketRdState($stateArg(socketinfo))} {
+ Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \
+ ne socketRdState($stateArg(socketinfo)) \
+ $socketRdState($stateArg(socketinfo))
+ }
+
+ # Report the inconsistency that socketRdQueue is non-empty.
+ if { [info exists socketRdQueue($stateArg(socketinfo))]
+ && ($socketRdQueue($stateArg(socketinfo)) ne {})
+ } {
+ Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \
+ has read queue socketRdQueue($stateArg(socketinfo)) \
+ $socketRdQueue($stateArg(socketinfo)) ne {}
+ }
+
+ lappend InFlightW $socketRdState($stateArg(socketinfo))
+ set socketRdQueue($stateArg(socketinfo)) {}
+ }
+
+ set newQueue {}
+ lappend newQueue {*}$InFlightR
+ lappend newQueue {*}$socketRdQueue($stateArg(socketinfo))
+ lappend newQueue {*}$InFlightW
+ lappend newQueue {*}$socketWrQueue($stateArg(socketinfo))
+
+
+ # 2. Tidy up tokenArg. This is a cut-down form of Finish/CloseSocket.
+ # Do not change state(status).
+ # No need to after cancel stateArg(after) - either this is done in
+ # ReplayCore/ReInit, or Finish is called.
+
+ catch {close $stateArg(sock)}
+
+ # 2a. Tidy the tokens in the queues - this is done in ReplayCore/ReInit.
+ # - Transactions, if any, that are awaiting responses cannot be completed.
+ # They are listed for re-sending in newQueue.
+ # - All tokens are preserved for re-use by ReplayCore, and their variables
+ # will be re-initialised by calls to ReInit.
+ # - The relevant element of socketMapping, socketRdState, socketWrState,
+ # socketRdQueue, socketWrQueue, socketClosing, socketPlayCmd will be set
+ # to new values in ReplayCore.
+
+ ReplayCore $newQueue
+}
+
+# http::ReplayIfClose --
+#
+# A request on a socket that was previously "Connection: keep-alive" has
+# received a "Connection: close" response header. The server supplies
+# that response correctly, but any later requests already queued on this
+# connection will be lost when the socket closes.
+#
+# This command takes arguments that represent the socketWrState,
+# socketRdQueue and socketWrQueue for this connection. The socketRdState
+# is not needed because the server responds in full to the request that
+# received the "Connection: close" response header.
+#
+# Existing request tokens $token (::http::$n) are preserved. The caller
+# will be unaware that the request was processed this way.
+
+proc http::ReplayIfClose {Wstate Rqueue Wqueue} {
+ Log running http::ReplayIfClose for $Wstate $Rqueue $Wqueue
+
+ if {$Wstate in $Rqueue || $Wstate in $Wqueue} {
+ Log WARNING duplicate token in http::ReplayIfClose - token $Wstate
+ set Wstate Wready
+ }
+
+ # 1. Create newQueue
+ set InFlightW {}
+ if {$Wstate ni {Wready peNding}} {
+ lappend InFlightW $Wstate
+ }
+
+ set newQueue {}
+ lappend newQueue {*}$Rqueue
+ lappend newQueue {*}$InFlightW
+ lappend newQueue {*}$Wqueue
+
+ # 2. Cleanup - none needed, done by the caller.
+
+ ReplayCore $newQueue
+}
+
+# http::ReInit --
+#
+# Command to restore a token's state to a condition that
+# makes it ready to replay a request.
+#
+# Command http::geturl stores extra state in state(tmp*) so
+# we don't need to do the argument processing again.
+#
+# The caller must:
+# - Set state(reusing) and state(sock) to their new values after calling
+# this command.
+# - Unset state(tmpState), state(tmpOpenCmd) if future calls to ReplayCore
+# or ReInit are inappropriate for this token. Typically only one retry
+# is allowed.
+# The caller may also unset state(tmpConnArgs) if this value (and the
+# token) will be used immediately. The value is needed by tokens that
+# will be stored in a queue.
+#
+# Arguments:
+# token Connection token.
+#
+# Return Value: (boolean) true iff the re-initialisation was successful.
+
+proc http::ReInit {token} {
+ variable $token
+ upvar 0 $token state
+
+ if {!(
+ [info exists state(tmpState)]
+ && [info exists state(tmpOpenCmd)]
+ && [info exists state(tmpConnArgs)]
+ )
+ } {
+ Log FAILED in http::ReInit via ReplayCore - NO tmp vars for $token
+ return 0
+ }
+
+ if {[info exists state(after)]} {
+ after cancel $state(after)
+ unset state(after)
+ }
+
+ # Don't alter state(status) - this would trigger http::wait if it is in use.
+ set tmpState $state(tmpState)
+ set tmpOpenCmd $state(tmpOpenCmd)
+ set tmpConnArgs $state(tmpConnArgs)
+ foreach name [array names state] {
+ if {$name ne "status"} {
+ unset state($name)
+ }
+ }
+
+ # Don't alter state(status).
+ # Restore state(tmp*) - the caller may decide to unset them.
+ # Restore state(tmpConnArgs) which is needed for connection.
+ # state(tmpState), state(tmpOpenCmd) are needed only for retries.
+
+ dict unset tmpState status
+ array set state $tmpState
+ set state(tmpState) $tmpState
+ set state(tmpOpenCmd) $tmpOpenCmd
+ set state(tmpConnArgs) $tmpConnArgs
+
+ return 1
+}
+
+# http::ReplayCore --
+#
+# Command to replay a list of requests, using existing connection tokens.
+#
+# Abstracted from http::geturl which stores extra state in state(tmp*) so
+# we don't need to do the argument processing again.
+#
+# Arguments:
+# newQueue List of connection tokens.
+#
+# Side Effects:
+# Use existing tokens, but try to open a new socket.
+
+proc http::ReplayCore {newQueue} {
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
+ if {[llength $newQueue] == 0} {
+ # Nothing to do.
+ return
+ }
+
+ ##Log running ReplayCore for {*}$newQueue
+ set newToken [lindex $newQueue 0]
+ set newQueue [lrange $newQueue 1 end]
+
+ # 3. Use newToken, and restore its values of state(*). Do not restore
+ # elements tmp* - we try again only once.
+
+ set token $newToken
+ variable $token
+ upvar 0 $token state
+
+ if {![ReInit $token]} {
+ Log FAILED in http::ReplayCore - NO tmp vars
+ Finish $token {cannot send this request again}
+ return
+ }
+
+ set tmpState $state(tmpState)
+ set tmpOpenCmd $state(tmpOpenCmd)
+ set tmpConnArgs $state(tmpConnArgs)
+ unset state(tmpState)
+ unset state(tmpOpenCmd)
+ unset state(tmpConnArgs)
+
+ set state(reusing) 0
+
+ if {$state(-timeout) > 0} {
+ set resetCmd [list http::reset $token timeout]
+ set state(after) [after $state(-timeout) $resetCmd]
+ }
+
+ set pre [clock milliseconds]
+ ##Log pre socket opened, - token $token
+ ##Log $tmpOpenCmd - token $token
+ # 4. Open a socket.
+ if {[catch {eval $tmpOpenCmd} sock]} {
+ # Something went wrong while trying to establish the connection.
+ Log FAILED - $sock
+ set state(sock) NONE
+ Finish $token $sock
+ return
+ }
+ ##Log post socket opened, - token $token
+ set delay [expr {[clock milliseconds] - $pre}]
+ if {$delay > 3000} {
+ Log socket delay $delay - token $token
+ }
+ # Command [socket] is called with -async, but takes 5s to 5.1s to return,
+ # with probability of order 1 in 10,000. This may be a bizarre scheduling
+ # issue with my (KJN's) system (Fedora Linux).
+ # This does not cause a problem (unless the request times out when this
+ # command returns).
+
+ # 5. Configure the persistent socket data.
+ if {$state(-keepalive)} {
+ set socketMapping($state(socketinfo)) $sock
+
+ if {![info exists socketRdState($state(socketinfo))]} {
+ set socketRdState($state(socketinfo)) {}
+ set varName ::http::socketRdState($state(socketinfo))
+ trace add variable $varName unset ::http::CancelReadPipeline
+ }
+
+ if {![info exists socketWrState($state(socketinfo))]} {
+ set socketWrState($state(socketinfo)) {}
+ set varName ::http::socketWrState($state(socketinfo))
+ trace add variable $varName unset ::http::CancelWritePipeline
+ }
+
+ if {$state(-pipeline)} {
+ #Log new, init for pipelined, GRANT write acc to $token ReplayCore
+ set socketRdState($state(socketinfo)) $token
+ set socketWrState($state(socketinfo)) $token
+ } else {
+ #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore
+ set socketRdState($state(socketinfo)) $token
+ set socketWrState($state(socketinfo)) $token
+ }
+
+ set socketRdQueue($state(socketinfo)) {}
+ set socketWrQueue($state(socketinfo)) $newQueue
+ set socketClosing($state(socketinfo)) 0
+ set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}}
+ }
+
+ ##Log pre newQueue ReInit, - token $token
+ # 6. Configure sockets in the queue.
+ foreach tok $newQueue {
+ if {[ReInit $tok]} {
+ set ${tok}(reusing) 1
+ set ${tok}(sock) $sock
+ } else {
+ set ${tok}(reusing) 1
+ set ${tok}(sock) NONE
+ Finish $token {cannot send this request again}
+ }
+ }
+
+ # 7. Configure the socket for newToken to send a request.
+ set state(sock) $sock
+ Log "Using $sock for $state(socketinfo) - token $token" \
+ [expr {$state(-keepalive)?"keepalive":""}]
+
+ # Initialisation of a new socket.
+ ##Log socket opened, now fconfigure - token $token
+ fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize)
+ ##Log socket opened, DONE fconfigure - token $token
+
+ # Connect does its own fconfigure.
+ fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs]
+ #Log ---- $sock << conn to $token for HTTP request (e)
+}
+
# Data access functions:
# Data - the URL data
-# Status - the transaction status: ok, reset, eof, timeout
+# Status - the transaction status: ok, reset, eof, timeout, error
# Code - the HTTP transaction code, e.g., 200
# Size - the size of the URL data
@@ -894,6 +2256,13 @@ proc http::error {token} {
proc http::cleanup {token} {
variable $token
upvar 0 $token state
+ if {[info commands ${token}EventCoroutine] ne {}} {
+ rename ${token}EventCoroutine {}
+ }
+ if {[info exists state(after)]} {
+ after cancel $state(after)
+ unset state(after)
+ }
if {[info exists state]} {
unset state
}
@@ -913,17 +2282,33 @@ proc http::cleanup {token} {
proc http::Connect {token proto phost srvurl} {
variable $token
upvar 0 $token state
+ set tk [namespace tail $token]
set err "due to unexpected EOF"
if {
[eof $state(sock)] ||
[set err [fconfigure $state(sock) -error]] ne ""
} {
+ Log "WARNING - if testing, pay special attention to this\
+ case (GJ) which is seldom executed - token $token"
+ if {[info exists state(reusing)] && $state(reusing)} {
+ # The socket was closed at the server end, and closed at
+ # this end by http::CheckEof.
+ if {[TestForReplay $token write $err b]} {
+ return
+ }
+
+ # else:
+ # This is NOT a persistent socket that has been closed since its
+ # last use.
+ # If any other requests are in flight or pipelined/queued, they will
+ # be discarded.
+ }
Finish $token "connect failed $err"
} else {
+ set state(state) connecting
fileevent $state(sock) writable {}
::http::Connected $token $proto $phost $srvurl
}
- return
}
# http::Write
@@ -937,8 +2322,18 @@ proc http::Connect {token proto phost srvurl} {
# Write the socket and handle callbacks.
proc http::Write {token} {
+ variable http
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
variable $token
upvar 0 $token state
+ set tk [namespace tail $token]
set sock $state(sock)
# Output a block. Tcl will buffer this if the socket blocks
@@ -949,7 +2344,21 @@ proc http::Write {token} {
if {[info exists state(-query)]} {
# Chop up large query strings so queryprogress callback can give
# smooth feedback.
-
+ if { $state(queryoffset) + $state(-queryblocksize)
+ >= $state(querylength)
+ } {
+ # This will be the last puts for the request-body.
+ if { (![catch {fileevent $sock readable} binding])
+ && ($binding eq [list http::CheckEof $sock])
+ } {
+ # Remove the "fileevent readable" binding of an idle
+ # persistent socket to http::CheckEof. We can no longer
+ # treat bytes received as junk. The server might still time
+ # out and half-close the socket if it has not yet received
+ # the first "puts".
+ fileevent $sock readable {}
+ }
+ }
puts -nonewline $sock \
[string range $state(-query) $state(queryoffset) \
[expr {$state(queryoffset) + $state(-queryblocksize) - 1}]]
@@ -962,6 +2371,19 @@ proc http::Write {token} {
# Copy blocks from the query channel
set outStr [read $state(-querychannel) $state(-queryblocksize)]
+ if {[eof $state(-querychannel)]} {
+ # This will be the last puts for the request-body.
+ if { (![catch {fileevent $sock readable} binding])
+ && ($binding eq [list http::CheckEof $sock])
+ } {
+ # Remove the "fileevent readable" binding of an idle
+ # persistent socket to http::CheckEof. We can no longer
+ # treat bytes received as junk. The server might still time
+ # out and half-close the socket if it has not yet received
+ # the first "puts".
+ fileevent $sock readable {}
+ }
+ }
puts -nonewline $sock $outStr
incr state(queryoffset) [string length $outStr]
if {[eof $state(-querychannel)]} {
@@ -975,10 +2397,14 @@ proc http::Write {token} {
set state(posterror) $err
set done 1
}
+
if {$done} {
catch {flush $sock}
fileevent $sock writable {}
- fileevent $sock readable [list http::Event $sock $token]
+ Log ^C$tk end sending request - token $token
+ # End of writing (POST method). The request has been sent.
+
+ DoneRequest $token
}
# Callback to the client after we've completely handled everything.
@@ -991,7 +2417,9 @@ proc http::Write {token} {
# http::Event
#
-# Handle input on the socket
+# Handle input on the socket. This command is the core of
+# the coroutine commands ${token}EventCoroutine that are
+# bound to "fileevent $sock readable" and process input.
#
# Arguments
# sock The socket receiving input.
@@ -1001,196 +2429,532 @@ proc http::Write {token} {
# Read the socket and handle callbacks.
proc http::Event {sock token} {
+ variable http
+ variable socketMapping
+ variable socketRdState
+ variable socketWrState
+ variable socketRdQueue
+ variable socketWrQueue
+ variable socketClosing
+ variable socketPlayCmd
+
variable $token
upvar 0 $token state
+ set tk [namespace tail $token]
+ while 1 {
+ yield
+ ##Log Event call - token $token
- if {![info exists state]} {
- Log "Event $sock with invalid token '$token' - remote close?"
- if {![eof $sock]} {
- if {[set d [read $sock]] ne ""} {
- Log "WARNING: additional data left on closed socket"
+ if {![info exists state]} {
+ Log "Event $sock with invalid token '$token' - remote close?"
+ if {![eof $sock]} {
+ if {[set d [read $sock]] ne ""} {
+ Log "WARNING: additional data left on closed socket\
+ - token $token"
+ }
}
+ Log ^X$tk end of response (token error) - token $token
+ CloseSocket $sock
+ return
}
- CloseSocket $sock
- return
- }
- if {$state(state) eq "connecting"} {
- if {[catch {gets $sock state(http)} n]} {
- return [Finish $token $n]
- } elseif {$n >= 0} {
- set state(state) "header"
- }
- } elseif {$state(state) eq "header"} {
- if {[catch {gets $sock line} n]} {
- return [Finish $token $n]
- } elseif {$n == 0} {
- # We have now read all headers
- # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3
- if {$state(http) == "" || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)} {
- set state(state) "connecting"
- return
+ if {$state(state) eq "connecting"} {
+ ##Log - connecting - token $token
+ if { $state(reusing)
+ && $state(-pipeline)
+ && ($state(-timeout) > 0)
+ && (![info exists state(after)])
+ } {
+ set state(after) [after $state(-timeout) \
+ [list http::reset $token timeout]]
}
- set state(state) body
+ if {[catch {gets $sock state(http)} nsl]} {
+ Log "WARNING - if testing, pay special attention to this\
+ case (GK) which is seldom executed - token $token"
+ if {[info exists state(reusing)] && $state(reusing)} {
+ # The socket was closed at the server end, and closed at
+ # this end by http::CheckEof.
- # If doing a HEAD, then we won't get any body
- if {$state(-validate)} {
- Eof $token
- return
- }
+ if {[TestForReplay $token read $nsl c]} {
+ return
+ }
- # For non-chunked transfer we may have no body - in this case we
- # may get no further file event if the connection doesn't close
- # and no more data is sent. We can tell and must finish up now -
- # not later.
- if {
- !(([info exists state(connection)]
- && ($state(connection) eq "close"))
- || [info exists state(transfer)])
- && ($state(totalsize) == 0)
+ # else:
+ # This is NOT a persistent socket that has been closed since
+ # its last use.
+ # If any other requests are in flight or pipelined/queued,
+ # they will be discarded.
+ } else {
+ Log ^X$tk end of response (error) - token $token
+ Finish $token $nsl
+ return
+ }
+ } elseif {$nsl >= 0} {
+ ##Log - connecting 1 - token $token
+ set state(state) "header"
+ } elseif { [eof $sock]
+ && [info exists state(reusing)]
+ && $state(reusing)
} {
- Log "body size is 0 and no events likely - complete."
- Eof $token
- return
- }
+ # The socket was closed at the server end, and we didn't notice.
+ # This is the first read - where the closure is usually first
+ # detected.
- # We have to use binary translation to count bytes properly.
- fconfigure $sock -translation binary
+ if {[TestForReplay $token read {} d]} {
+ return
+ }
- if {
- $state(-binary) || [IsBinaryContentType $state(type)]
- } {
- # Turn off conversions for non-text data
- set state(binary) 1
+ # else:
+ # This is NOT a persistent socket that has been closed since its
+ # last use.
+ # If any other requests are in flight or pipelined/queued, they
+ # will be discarded.
}
- if {[info exists state(-channel)]} {
- if {$state(binary) || [llength [ContentEncoding $token]]} {
- fconfigure $state(-channel) -translation binary
+ } elseif {$state(state) eq "header"} {
+ if {[catch {gets $sock line} nhl]} {
+ ##Log header failed - token $token
+ Log ^X$tk end of response (error) - token $token
+ Finish $token $nhl
+ return
+ } elseif {$nhl == 0} {
+ ##Log header done - token $token
+ Log ^E$tk end of response headers - token $token
+ # We have now read all headers
+ # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3
+ if { ($state(http) == "")
+ || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)
+ } {
+ set state(state) "connecting"
+ continue
+ # This was a "return" in the pre-coroutine code.
}
- if {![info exists state(-handler)]} {
- # Initiate a sequence of background fcopies
- fileevent $sock readable {}
- CopyStart $sock $token
- return
+
+ if { ([info exists state(connection)])
+ && ([info exists socketMapping($state(socketinfo))])
+ && ($state(connection) eq "keep-alive")
+ && ($state(-keepalive))
+ && (!$state(reusing))
+ && ($state(-pipeline))
+ } {
+ # Response headers received for first request on a
+ # persistent socket. Now ready for pipelined writes (if
+ # any).
+ # Previous value is $token. It cannot be "pending".
+ set socketWrState($state(socketinfo)) Wready
+ http::NextPipelinedWrite $token
}
- }
- } elseif {$n > 0} {
- # Process header lines
- if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
- switch -- [string tolower $key] {
- content-type {
- set state(type) [string trim [string tolower $value]]
- # grab the optional charset information
- if {[regexp -nocase \
- {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \
- $state(type) -> cs]} {
- set state(charset) [string map {{\"} \"} $cs]
+
+ # Once a "close" has been signaled, the client MUST NOT send any
+ # more requests on that connection.
+ #
+ # If either the client or the server sends the "close" token in
+ # the Connection header, that request becomes the last one for
+ # the connection.
+
+ if { ([info exists state(connection)])
+ && ([info exists socketMapping($state(socketinfo))])
+ && ($state(connection) eq "close")
+ && ($state(-keepalive))
+ } {
+ # The server warns that it will close the socket after this
+ # response.
+ ##Log WARNING - socket will close after response for $token
+ # Prepare data for a call to ReplayIfClose.
+ if { ($socketRdQueue($state(socketinfo)) ne {})
+ || ($socketWrQueue($state(socketinfo)) ne {})
+ || ($socketWrState($state(socketinfo)) ni
+ [list Wready peNding $token])
+ } {
+ set InFlightW $socketWrState($state(socketinfo))
+ if {$InFlightW in [list Wready peNding $token]} {
+ set InFlightW Wready
} else {
- regexp -nocase {charset\s*=\s*(\S+?);?} \
- $state(type) -> state(charset)
+ set msg "token ${InFlightW} is InFlightW"
+ ##Log $msg - token $token
}
+
+ set socketPlayCmd($state(socketinfo)) \
+ [list ReplayIfClose $InFlightW \
+ $socketRdQueue($state(socketinfo)) \
+ $socketWrQueue($state(socketinfo))]
+
+ # - All tokens are preserved for re-use by ReplayCore.
+ # - Queues are preserved in case of Finish with error,
+ # but are not used for anything else because
+ # socketClosing(*) is set below.
+ # - Cancel the state(after) timeout events.
+ foreach tokenVal $socketRdQueue($state(socketinfo)) {
+ if {[info exists ${tokenVal}(after)]} {
+ after cancel [set ${tokenVal}(after)]
+ unset ${tokenVal}(after)
+ }
+ }
+
+ } else {
+ set socketPlayCmd($state(socketinfo)) \
+ {ReplayIfClose Wready {} {}}
}
- content-length {
- set state(totalsize) [string trim $value]
- }
- content-encoding {
- set state(coding) [string trim $value]
+
+ # Do not allow further connections on this socket.
+ set socketClosing($state(socketinfo)) 1
+ }
+
+ set state(state) body
+
+ # If doing a HEAD, then we won't get any body
+ if {$state(-validate)} {
+ Log ^F$tk end of response for HEAD request - token $token
+ set state(state) complete
+ Eot $token
+ return
+ }
+
+ # - For non-chunked transfer we may have no body - in this case
+ # we may get no further file event if the connection doesn't
+ # close and no more data is sent. We can tell and must finish
+ # up now - not later - the alternative would be to wait until
+ # the server times out.
+ # - In this case, the server has NOT told the client it will
+ # close the connection, AND it has NOT indicated the resource
+ # length EITHER by setting the Content-Length (totalsize) OR
+ # by using chunked Transfer-Encoding.
+ # - Do not worry here about the case (Connection: close) because
+ # the server should close the connection.
+ # - IF (NOT Connection: close) AND (NOT chunked encoding) AND
+ # (totalsize == 0).
+
+ if { (!( [info exists state(connection)]
+ && ($state(connection) eq "close")
+ )
+ )
+ && (![info exists state(transfer)])
+ && ($state(totalsize) == 0)
+ } {
+ set msg {body size is 0 and no events likely - complete}
+ Log "$msg - token $token"
+ set msg {(length unknown, set to 0)}
+ Log ^F$tk end of response body {*}$msg - token $token
+ set state(state) complete
+ Eot $token
+ return
+ }
+
+ # We have to use binary translation to count bytes properly.
+ lassign [fconfigure $sock -translation] trRead trWrite
+ fconfigure $sock -translation [list binary $trWrite]
+
+ if {
+ $state(-binary) || [IsBinaryContentType $state(type)]
+ } {
+ # Turn off conversions for non-text data.
+ set state(binary) 1
+ }
+ if {[info exists state(-channel)]} {
+ if {$state(binary) || [llength [ContentEncoding $token]]} {
+ fconfigure $state(-channel) -translation binary
}
- transfer-encoding {
- set state(transfer) \
- [string trim [string tolower $value]]
+ if {![info exists state(-handler)]} {
+ # Initiate a sequence of background fcopies.
+ fileevent $sock readable {}
+ rename ${token}EventCoroutine {}
+ CopyStart $sock $token
+ return
}
- proxy-connection -
- connection {
- set state(connection) \
- [string trim [string tolower $value]]
+ }
+ } elseif {$nhl > 0} {
+ # Process header lines.
+ ##Log header - token $token - $line
+ if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
+ switch -- [string tolower $key] {
+ content-type {
+ set state(type) [string trim [string tolower $value]]
+ # Grab the optional charset information.
+ if {[regexp -nocase \
+ {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \
+ $state(type) -> cs]} {
+ set state(charset) [string map {{\"} \"} $cs]
+ } else {
+ regexp -nocase {charset\s*=\s*(\S+?);?} \
+ $state(type) -> state(charset)
+ }
+ }
+ content-length {
+ set state(totalsize) [string trim $value]
+ }
+ content-encoding {
+ set state(coding) [string trim $value]
+ }
+ transfer-encoding {
+ set state(transfer) \
+ [string trim [string tolower $value]]
+ }
+ proxy-connection -
+ connection {
+ set state(connection) \
+ [string trim [string tolower $value]]
+ }
}
+ lappend state(meta) $key [string trim $value]
}
- lappend state(meta) $key [string trim $value]
}
- }
- } else {
- # Now reading body
- if {[catch {
- if {[info exists state(-handler)]} {
- set n [eval $state(-handler) [list $sock $token]]
- } elseif {[info exists state(transfer_final)]} {
- set line [getTextLine $sock]
- set n [string length $line]
- if {$n > 0} {
- Log "found $n bytes following final chunk"
- append state(transfer_final) $line
- } else {
- Log "final chunk part"
- Eof $token
- }
- } elseif {
- [info exists state(transfer)]
- && $state(transfer) eq "chunked"
- } {
- set size 0
- set chunk [getTextLine $sock]
- set n [string length $chunk]
- if {[string trim $chunk] ne ""} {
- scan $chunk %x size
- if {$size != 0} {
- set bl [fconfigure $sock -blocking]
- fconfigure $sock -blocking 1
- set chunk [read $sock $size]
- fconfigure $sock -blocking $bl
- set n [string length $chunk]
- if {$n >= 0} {
- append state(body) $chunk
+ } else {
+ # Now reading body
+ ##Log body - token $token
+ if {[catch {
+ if {[info exists state(-handler)]} {
+ set n [eval $state(-handler) [list $sock $token]]
+ ##Log handler $n - token $token
+ # N.B. the protocol has been set to 1.0 because the -handler
+ # logic is not expected to handle chunked encoding.
+ # FIXME Allow -handler with 1.1 on dechunked stacked chan.
+ if {$state(totalsize) == 0} {
+ # We know the transfer is complete only when the server
+ # closes the connection - i.e. eof is not an error.
+ set state(state) complete
+ }
+ if {![string is integer -strict $n]} {
+ if 1 {
+ # Do not tolerate bad -handler - fail with error
+ # status.
+ set msg {the -handler command for http::geturl must\
+ return an integer (the number of bytes\
+ read)}
+ Log ^X$tk end of response (handler error) -\
+ token $token
+ Eot $token $msg
+ } else {
+ # Tolerate the bad -handler, and continue. The
+ # penalty:
+ # (a) Because the handler returns nonsense, we know
+ # the transfer is complete only when the server
+ # closes the connection - i.e. eof is not an
+ # error.
+ # (b) http::size will not be accurate.
+ # (c) The transaction is already downgraded to 1.0
+ # to avoid chunked transfer encoding. It MUST
+ # also be forced to "Connection: close" or the
+ # HTTP/1.0 equivalent; or it MUST fail (as
+ # above) if the server sends
+ # "Connection: keep-alive" or the HTTP/1.0
+ # equivalent.
+ set n 0
+ set state(state) complete
}
- if {$size != [string length $chunk]} {
- Log "WARNING: mis-sized chunk:\
- was [string length $chunk], should be $size"
+ }
+ } elseif {[info exists state(transfer_final)]} {
+ # This code forgives EOF in place of the final CRLF.
+ set line [getTextLine $sock]
+ set n [string length $line]
+ set state(state) complete
+ if {$n > 0} {
+ # - HTTP trailers (late response headers) are permitted
+ # by Chunked Transfer-Encoding, and can be safely
+ # ignored.
+ # - Do not count these bytes in the total received for
+ # the response body.
+ Log "trailer of $n bytes after final chunk -\
+ token $token"
+ append state(transfer_final) $line
+ set n 0
+ } else {
+ Log ^F$tk end of response body (chunked) - token $token
+ Log "final chunk part - token $token"
+ Eot $token
+ }
+ } elseif { [info exists state(transfer)]
+ && ($state(transfer) eq "chunked")
+ } {
+ ##Log chunked - token $token
+ set size 0
+ set hexLenChunk [getTextLine $sock]
+ #set ntl [string length $hexLenChunk]
+ if {[string trim $hexLenChunk] ne ""} {
+ scan $hexLenChunk %x size
+ if {$size != 0} {
+ ##Log chunk-measure $size - token $token
+ set chunk [BlockingRead $sock $size]
+ set n [string length $chunk]
+ if {$n >= 0} {
+ append state(body) $chunk
+ incr state(log_size) [string length $chunk]
+ ##Log chunk $n cumul $state(log_size) -\
+ token $token
+ }
+ if {$size != [string length $chunk]} {
+ Log "WARNING: mis-sized chunk:\
+ was [string length $chunk], should be\
+ $size - token $token"
+ set n 0
+ set state(connection) close
+ Log ^X$tk end of response (chunk error) \
+ - token $token
+ set msg {error in chunked encoding - fetch\
+ terminated}
+ Eot $token $msg
+ }
+ # CRLF that follows chunk.
+ # If eof, this is handled at the end of this proc.
+ getTextLine $sock
+ } else {
+ set n 0
+ set state(transfer_final) {}
}
- getTextLine $sock
} else {
- set state(transfer_final) {}
+ # Line expected to hold chunk length is empty, or eof.
+ ##Log bad-chunk-measure - token $token
+ set n 0
+ set state(connection) close
+ Log ^X$tk end of response (chunk error) - token $token
+ Eot $token {error in chunked encoding -\
+ fetch terminated}
+ }
+ } else {
+ ##Log unchunked - token $token
+ if {$state(totalsize) == 0} {
+ # We know the transfer is complete only when the server
+ # closes the connection.
+ set state(state) complete
+ set reqSize $state(-blocksize)
+ } else {
+ # Ask for the whole of the unserved response-body.
+ # This works around a problem with a tls::socket - for
+ # https in keep-alive mode, and a request for
+ # $state(-blocksize) bytes, the last part of the
+ # resource does not get read until the server times out.
+ set reqSize [expr { $state(totalsize)
+ - $state(currentsize)}]
+
+ # The workaround fails if reqSize is
+ # capped at $state(-blocksize).
+ # set reqSize [expr {min($reqSize, $state(-blocksize))}]
+ }
+ set c $state(currentsize)
+ set t $state(totalsize)
+ ##Log non-chunk currentsize $c of totalsize $t -\
+ token $token
+ set block [read $sock $reqSize]
+ set n [string length $block]
+ if {$n >= 0} {
+ append state(body) $block
+ ##Log non-chunk [string length $state(body)] -\
+ token $token
}
}
+ # This calculation uses n from the -handler, chunked, or
+ # unchunked case as appropriate.
+ if {[info exists state]} {
+ if {$n >= 0} {
+ incr state(currentsize) $n
+ set c $state(currentsize)
+ set t $state(totalsize)
+ ##Log another $n currentsize $c totalsize $t -\
+ token $token
+ }
+ # If Content-Length - check for end of data.
+ if {
+ ($state(totalsize) > 0)
+ && ($state(currentsize) >= $state(totalsize))
+ } {
+ Log ^F$tk end of response body (unchunked) -\
+ token $token
+ set state(state) complete
+ Eot $token
+ }
+ }
+ } err]} {
+ Log ^X$tk end of response (error ${err}) - token $token
+ Finish $token $err
+ return
} else {
- #Log "read non-chunk $state(currentsize) of $state(totalsize)"
- set block [read $sock $state(-blocksize)]
- set n [string length $block]
- if {$n >= 0} {
- append state(body) $block
+ if {[info exists state(-progress)]} {
+ eval $state(-progress) \
+ [list $token $state(totalsize) $state(currentsize)]
}
}
- if {[info exists state]} {
- if {$n >= 0} {
- incr state(currentsize) $n
- }
- # If Content-Length - check for end of data.
- if {
- ($state(totalsize) > 0)
- && ($state(currentsize) >= $state(totalsize))
- } {
- Eof $token
+ }
+
+ # catch as an Eot above may have closed the socket already
+ # $state(state) may be connecting, header, body, or complete
+ if {![set cc [catch {eof $sock} eof]] && $eof} {
+ ##Log eof - token $token
+ if {[info exists $token]} {
+ set state(connection) close
+ if {$state(state) eq "complete"} {
+ # This includes all cases in which the transaction
+ # can be completed by eof.
+ # The value "complete" is set only in http::Event, and it is
+ # used only in the test above.
+ Log ^F$tk end of response body (unchunked, eof) -\
+ token $token
+ Eot $token
+ } else {
+ # Premature eof.
+ Log ^X$tk end of response (unexpected eof) - token $token
+ Eot $token eof
}
+ } else {
+ # open connection closed on a token that has been cleaned up.
+ Log ^X$tk end of response (token error) - token $token
+ CloseSocket $sock
}
- } err]} {
- return [Finish $token $err]
- } else {
- if {[info exists state(-progress)]} {
- eval $state(-progress) \
- [list $token $state(totalsize) $state(currentsize)]
- }
+ } elseif {$cc} {
+ return
}
}
+}
- # catch as an Eof above may have closed the socket already
- if {![catch {eof $sock} eof] && $eof} {
- if {[info exists $token]} {
- set state(connection) close
- Eof $token
- } else {
- # open connection closed on a token that has been cleaned up.
- CloseSocket $sock
- }
- return
+# http::TestForReplay
+#
+# Command called if eof is discovered when a socket is first used for a
+# new transaction. Typically this occurs if a persistent socket is used
+# after a period of idleness and the server has half-closed the socket.
+#
+# token - the connection token returned by http::geturl
+# doing - "read" or "write"
+# err - error message, if any
+# caller - code to identify the caller - used only in logging
+#
+# Return Value: boolean, true iff the command calls http::ReplayIfDead.
+
+proc http::TestForReplay {token doing err caller} {
+ variable http
+ variable $token
+ upvar 0 $token state
+ set tk [namespace tail $token]
+ if {$doing eq "read"} {
+ set code Q
+ set action response
+ set ing reading
+ } else {
+ set code P
+ set action request
+ set ing writing
+ }
+
+ if {$err eq {}} {
+ set err "detect eof when $ing (server timed out?)"
+ }
+
+ if {$state(method) eq "POST" && !$http(-repost)} {
+ # No Replay.
+ # The present transaction will end when Finish is called.
+ # That call to Finish will abort any other transactions
+ # currently in the write queue.
+ # For calls from http::Event this occurs when execution
+ # reaches the code block at the end of that proc.
+ set msg {no retry for POST with http::config -repost 0}
+ Log reusing socket failed "($caller)" - $msg - token $token
+ Log error - $err - token $token
+ Log ^X$tk end of $action (error) - token $token
+ return 0
+ } else {
+ # Replay.
+ set msg {try a new socket}
+ Log reusing socket failed "($caller)" - $msg - token $token
+ Log error - $err - token $token
+ Log ^$code$tk Any unfinished (incl this one) failed - token $token
+ ReplayIfDead $token $doing
+ return 1
}
}
@@ -1228,7 +2992,10 @@ proc http::IsBinaryContentType {type} {
# http::getTextLine --
#
-# Get one line with the stream in blocking crlf mode
+# Get one line with the stream in crlf mode.
+# Used if Transfer-Encoding is chunked.
+# Empty line is not distinguished from eof. The caller must
+# be able to handle this.
#
# Arguments
# sock The socket receiving input.
@@ -1238,13 +3005,55 @@ proc http::IsBinaryContentType {type} {
proc http::getTextLine {sock} {
set tr [fconfigure $sock -translation]
- set bl [fconfigure $sock -blocking]
- fconfigure $sock -translation crlf -blocking 1
- set r [gets $sock]
- fconfigure $sock -translation $tr -blocking $bl
+ lassign $tr trRead trWrite
+ fconfigure $sock -translation [list crlf $trWrite]
+ set r [BlockingGets $sock]
+ fconfigure $sock -translation $tr
return $r
}
+# http::BlockingRead
+#
+# Replacement for a blocking read.
+# The caller must be a coroutine.
+
+proc http::BlockingRead {sock size} {
+ if {$size < 1} {
+ return
+ }
+ set result {}
+ while 1 {
+ set need [expr {$size - [string length $result]}]
+ set block [read $sock $need]
+ set eof [eof $sock]
+ append result $block
+ if {[string length $result] >= $size || $eof} {
+ return $result
+ } else {
+ yield
+ }
+ }
+}
+
+# http::BlockingGets
+#
+# Replacement for a blocking gets.
+# The caller must be a coroutine.
+# Empty line is not distinguished from eof. The caller must
+# be able to handle this.
+
+proc http::BlockingGets {sock} {
+ while 1 {
+ set count [gets $sock line]
+ set eof [eof $sock]
+ if {$count > -1 || $eof} {
+ return $line
+ } else {
+ yield
+ }
+ }
+}
+
# http::CopyStart
#
# Error handling wrapper around fcopy
@@ -1270,6 +3079,10 @@ proc http::CopyStart {sock token {initial 1}} {
}
}
if {[catch {
+ # FIXME Keep-Alive on https tls::socket with unchunked transfer
+ # hangs until the server times out. A workaround is possible, as for
+ # the case without -channel, but it does not use the neat "fcopy"
+ # solution.
fcopy $sock $state(-channel) -size $state(-blocksize) -command \
[list http::CopyDone $token]
} err]} {
@@ -1293,7 +3106,7 @@ proc http::CopyChunk {token chunk} {
$token $state(totalsize) $state(currentsize)]
}
} else {
- Log "CopyChunk Finish $token"
+ Log "CopyChunk Finish - token $token"
if {[info exists state(zlib)]} {
set excess ""
foreach stream $state(zlib) {
@@ -1303,7 +3116,7 @@ proc http::CopyChunk {token chunk} {
foreach stream $state(zlib) { $stream close }
unset state(zlib)
}
- Eof $token ;# FIX ME: pipelining.
+ Eot $token ;# FIX ME: pipelining.
}
}
@@ -1327,33 +3140,53 @@ proc http::CopyDone {token count {error {}}} {
eval $state(-progress) \
[list $token $state(totalsize) $state(currentsize)]
}
- # At this point the token may have been reset
+ # At this point the token may have been reset.
if {[string length $error]} {
Finish $token $error
} elseif {[catch {eof $sock} iseof] || $iseof} {
- Eof $token
+ Eot $token
} else {
CopyStart $sock $token 0
}
}
-# http::Eof
+# http::Eot
#
-# Handle eof on the socket
+# Called when either:
+# a. An eof condition is detected on the socket.
+# b. The client decides that the response is complete.
+# c. The client detects an inconsistency and aborts the transaction.
+#
+# Does:
+# 1. Set state(status)
+# 2. Reverse any Content-Encoding
+# 3. Convert charset encoding and line ends if necessary
+# 4. Call http::Finish
#
# Arguments
# token The token returned from http::geturl
+# force (previously) optional, has no effect
+# reason - "eof" means premature EOF (not EOF as the natural end of
+# the response)
+# - "" means completion of response, with or without EOF
+# - anything else describes an error confition other than
+# premature EOF.
#
# Side Effects
# Clean up the socket
-proc http::Eof {token {force 0}} {
+proc http::Eot {token {reason {}}} {
variable $token
upvar 0 $token state
- if {$state(state) eq "header"} {
- # Premature eof
+ if {$reason eq "eof"} {
+ # Premature eof.
set state(status) eof
+ set reason {}
+ } elseif {$reason ne ""} {
+ # Abort the transaction.
+ set state(status) $reason
} else {
+ # The response is complete.
set state(status) ok
}
@@ -1363,14 +3196,15 @@ proc http::Eof {token {force 0}} {
set state(body) [zlib $coding $state(body)]
}
} err]} {
- Log "error doing decompression: $err"
- return [Finish $token $err]
+ Log "error doing decompression for token $token: $err"
+ Finish $token $err
+ return
}
if {!$state(binary)} {
# If we are getting text, set the incoming channel's encoding
- # correctly. iso8859-1 is the RFC default, but this could be any IANA
- # charset. However, we only know how to convert what we have
+ # correctly. iso8859-1 is the RFC default, but this could be any
+ # IANA charset. However, we only know how to convert what we have
# encodings for.
set enc [CharsetToEncoding $state(charset)]
@@ -1382,7 +3216,7 @@ proc http::Eof {token {force 0}} {
set state(body) [string map {\r\n \n \r \n} $state(body)]
}
}
- Finish $token
+ Finish $token $reason
}
# http::wait --
@@ -1393,7 +3227,7 @@ proc http::Eof {token {force 0}} {
# token Connection token.
#
# Results:
-# The status after the wait.
+# The status after the wait.
proc http::wait {token} {
variable $token
@@ -1420,6 +3254,12 @@ proc http::wait {token} {
# TODO
proc http::formatQuery {args} {
+ if {[llength $args] % 2} {
+ return \
+ -code error \
+ -errorcode [list HTTP BADARGCNT $args] \
+ {Incorrect number of arguments, must be an even number.}
+ }
set result ""
set sep ""
foreach i $args {
@@ -1464,6 +3304,7 @@ proc http::mapReply {string} {
}
return $converted
}
+interp alias {} http::quoteString {} http::mapReply
# http::ProxyRequired --
# Default proxy filter.
@@ -1546,37 +3387,39 @@ proc http::ContentEncoding {token} {
return $r
}
+proc http::ReceiveChunked {chan command} {
+ set data ""
+ set size -1
+ yield
+ while {1} {
+ chan configure $chan -translation {crlf binary}
+ while {[gets $chan line] < 1} { yield }
+ chan configure $chan -translation {binary binary}
+ if {[scan $line %x size] != 1} {
+ return -code error "invalid size: \"$line\""
+ }
+ set chunk ""
+ while {$size && ![chan eof $chan]} {
+ set part [chan read $chan $size]
+ incr size -[string length $part]
+ append chunk $part
+ }
+ if {[catch {
+ uplevel #0 [linsert $command end $chunk]
+ }]} {
+ http::Log "Error in callback: $::errorInfo"
+ }
+ if {[string length $chunk] == 0} {
+ # channel might have been closed in the callback
+ catch {chan event $chan readable {}}
+ return
+ }
+ }
+}
+
proc http::make-transformation-chunked {chan command} {
- set lambda {{chan command} {
- set data ""
- set size -1
- yield
- while {1} {
- chan configure $chan -translation {crlf binary}
- while {[gets $chan line] < 1} { yield }
- chan configure $chan -translation {binary binary}
- if {[scan $line %x size] != 1} { return -code error "invalid size: \"$line\"" }
- set chunk ""
- while {$size && ![chan eof $chan]} {
- set part [chan read $chan $size]
- incr size -[string length $part]
- append chunk $part
- }
- if {[catch {
- uplevel #0 [linsert $command end $chunk]
- }]} {
- http::Log "Error in callback: $::errorInfo"
- }
- if {[string length $chunk] == 0} {
- # channel might have been closed in the callback
- catch {chan event $chan readable {}}
- return
- }
- }
- }}
- coroutine dechunk$chan ::apply $lambda $chan $command
- chan event $chan readable [namespace origin dechunk$chan]
- return
+ coroutine [namespace current]::dechunk$chan ::http::ReceiveChunked $chan $command
+ chan event $chan readable [namespace current]::dechunk$chan
}
# Local variables:
diff --git a/tcl8.6/library/http/pkgIndex.tcl b/tcl8.6/library/http/pkgIndex.tcl
index d3fc7af..4f74635 100644
--- a/tcl8.6/library/http/pkgIndex.tcl
+++ b/tcl8.6/library/http/pkgIndex.tcl
@@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 8.6-]} {return}
-package ifneeded http 2.8.12 [list tclPkgSetup $dir http 2.8.12 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
+package ifneeded http 2.9.0 [list tclPkgSetup $dir http 2.9.0 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
diff --git a/tcl8.6/library/init.tcl b/tcl8.6/library/init.tcl
index b3990df..8952172 100644
--- a/tcl8.6/library/init.tcl
+++ b/tcl8.6/library/init.tcl
@@ -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.8
+package require -exact Tcl 8.6.9
# Compute the auto path to use in this interpreter.
# The values on the path come from several locations:
diff --git a/tcl8.6/library/reg/pkgIndex.tcl b/tcl8.6/library/reg/pkgIndex.tcl
index b1fe234..ee559b5 100755
--- a/tcl8.6/library/reg/pkgIndex.tcl
+++ b/tcl8.6/library/reg/pkgIndex.tcl
@@ -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.2 \
+ package ifneeded registry 1.3.3 \
[list load [file join $dir tclreg13g.dll] registry]
} else {
- package ifneeded registry 1.3.2 \
+ package ifneeded registry 1.3.3 \
[list load [file join $dir tclreg13.dll] registry]
}
diff --git a/tcl8.6/library/tcltest/pkgIndex.tcl b/tcl8.6/library/tcltest/pkgIndex.tcl
index c9d3759..fde3ffe 100644
--- a/tcl8.6/library/tcltest/pkgIndex.tcl
+++ b/tcl8.6/library/tcltest/pkgIndex.tcl
@@ -8,5 +8,5 @@
# script is sourced, the variable $dir must contain the
# full path name of this file's directory.
-if {![package vsatisfies [package provide Tcl] 8.5]} {return}
-package ifneeded tcltest 2.4.1 [list source [file join $dir tcltest.tcl]]
+if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
+package ifneeded tcltest 2.5.0 [list source [file join $dir tcltest.tcl]]
diff --git a/tcl8.6/library/tcltest/tcltest.tcl b/tcl8.6/library/tcltest/tcltest.tcl
index f1b6082..d67a900 100644
--- a/tcl8.6/library/tcltest/tcltest.tcl
+++ b/tcl8.6/library/tcltest/tcltest.tcl
@@ -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.4.1
+ variable Version 2.5.0
# Compatibility support for dumb variables defined in tcltest 1
# Do not use these. Call [package provide Tcl] and [info patchlevel]
@@ -1841,6 +1841,9 @@ proc tcltest::SubstArguments {argList} {
# is optional; default is {}.
# returnCodes - Expected return codes. This attribute is
# optional; default is {0 2}.
+# errorCode - Expected error code. This attribute is
+# optional; default is {*}. It is a glob pattern.
+# If given, returnCodes defaults to {1}.
# setup - Code to run before $script (above). This
# attribute is optional; default is {}.
# cleanup - Code to run after $script (above). This
@@ -1882,7 +1885,7 @@ proc tcltest::test {name description args} {
# Pre-define everything to null except output and errorOutput. We
# determine whether or not to trap output based on whether or not
# these variables (output & errorOutput) are defined.
- lassign {} constraints setup cleanup body result returnCodes match
+ lassign {} constraints setup cleanup body result returnCodes errorCode match
# Set the default match mode
set match exact
@@ -1892,6 +1895,9 @@ proc tcltest::test {name description args} {
# 'return' being used in the test script).
set returnCodes [list 0 2]
+ # Set the default error code pattern
+ set errorCode "*"
+
# The old test format can't have a 3rd argument (constraints or
# script) that starts with '-'.
if {[string match -* [lindex $args 0]] || ([llength $args] <= 1)} {
@@ -1901,7 +1907,7 @@ proc tcltest::test {name description args} {
set testAttributes($element) $value
}
foreach item {constraints match setup body cleanup \
- result returnCodes output errorOutput} {
+ result returnCodes errorCode output errorOutput} {
if {[info exists testAttributes(-$item)]} {
set testAttributes(-$item) [uplevel 1 \
::concat $testAttributes(-$item)]
@@ -1912,7 +1918,7 @@ proc tcltest::test {name description args} {
}
set validFlags {-setup -cleanup -body -result -returnCodes \
- -match -output -errorOutput -constraints}
+ -errorCode -match -output -errorOutput -constraints}
foreach flag [array names testAttributes] {
if {$flag ni $validFlags} {
@@ -1944,6 +1950,10 @@ proc tcltest::test {name description args} {
foreach {strcode numcode} {ok 0 normal 0 error 1 return 2 break 3 continue 4} {
set returnCodes [string map -nocase [list $strcode $numcode] $returnCodes]
}
+ # errorCode without returnCode 1 is meaningless
+ if {$errorCode ne "*" && 1 ni $returnCodes} {
+ set returnCodes 1
+ }
} else {
# This is parsing for the old test command format; it is here
# for backward compatibility.
@@ -1976,7 +1986,7 @@ proc tcltest::test {name description args} {
set code [catch {uplevel 1 $setup} setupMsg]
if {$code == 1} {
set errorInfo(setup) $::errorInfo
- set errorCode(setup) $::errorCode
+ set errorCodeRes(setup) $::errorCode
}
set setupFailure [expr {$code != 0}]
@@ -2003,7 +2013,7 @@ proc tcltest::test {name description args} {
lassign $testResult actualAnswer returnCode
if {$returnCode == 1} {
set errorInfo(body) $::errorInfo
- set errorCode(body) $::errorCode
+ set errorCodeRes(body) $::errorCode
}
}
@@ -2012,6 +2022,11 @@ proc tcltest::test {name description args} {
if {!$setupFailure && ($returnCode ni $returnCodes)} {
set codeFailure 1
}
+ set errorCodeFailure 0
+ if {!$setupFailure && !$codeFailure && $returnCode == 1 && \
+ ![string match $errorCode $errorCodeRes(body)]} {
+ set errorCodeFailure 1
+ }
# If expected output/error strings exist, we have to compare
# them. If the comparison fails, then so did the test.
@@ -2055,7 +2070,7 @@ proc tcltest::test {name description args} {
set code [catch {uplevel 1 $cleanup} cleanupMsg]
if {$code == 1} {
set errorInfo(cleanup) $::errorInfo
- set errorCode(cleanup) $::errorCode
+ set errorCodeRes(cleanup) $::errorCode
}
set cleanupFailure [expr {$code != 0}]
@@ -2106,7 +2121,7 @@ proc tcltest::test {name description args} {
variable numTests
if {!($setupFailure || $cleanupFailure || $coreFailure
|| $outputFailure || $errorFailure || $codeFailure
- || $scriptFailure)} {
+ || $errorCodeFailure || $scriptFailure)} {
if {$testLevel == 1} {
incr numTests(Passed)
if {[IsVerbose pass]} {
@@ -2159,7 +2174,7 @@ proc tcltest::test {name description args} {
failed:\n$setupMsg"
if {[info exists errorInfo(setup)]} {
puts [outputChannel] "---- errorInfo(setup): $errorInfo(setup)"
- puts [outputChannel] "---- errorCode(setup): $errorCode(setup)"
+ puts [outputChannel] "---- errorCode(setup): $errorCodeRes(setup)"
}
}
if {$scriptFailure} {
@@ -2171,6 +2186,10 @@ proc tcltest::test {name description args} {
($match matching):\n$result"
}
}
+ if {$errorCodeFailure} {
+ puts [outputChannel] "---- Error code was: '$errorCodeRes(body)'"
+ puts [outputChannel] "---- Error code should have been: '$errorCode'"
+ }
if {$codeFailure} {
switch -- $returnCode {
0 { set msg "Test completed normally" }
@@ -2186,7 +2205,7 @@ proc tcltest::test {name description args} {
if {[IsVerbose error]} {
if {[info exists errorInfo(body)] && (1 ni $returnCodes)} {
puts [outputChannel] "---- errorInfo: $errorInfo(body)"
- puts [outputChannel] "---- errorCode: $errorCode(body)"
+ puts [outputChannel] "---- errorCode: $errorCodeRes(body)"
}
}
}
@@ -2212,7 +2231,7 @@ proc tcltest::test {name description args} {
puts [outputChannel] "---- Test cleanup failed:\n$cleanupMsg"
if {[info exists errorInfo(cleanup)]} {
puts [outputChannel] "---- errorInfo(cleanup): $errorInfo(cleanup)"
- puts [outputChannel] "---- errorCode(cleanup): $errorCode(cleanup)"
+ puts [outputChannel] "---- errorCode(cleanup): $errorCodeRes(cleanup)"
}
}
if {$coreFailure} {
@@ -2722,7 +2741,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
# shell being tested
#
# Results:
-# None.
+# Whether there were any failures.
#
# Side effects:
# None.
@@ -2733,6 +2752,7 @@ proc tcltest::runAllTests { {shell ""} } {
variable numTests
variable failFiles
variable DefaultValue
+ set failFilesAccum {}
FillFilesExisted
if {[llength [info level 0]] == 1} {
@@ -2822,6 +2842,7 @@ proc tcltest::runAllTests { {shell ""} } {
}
if {$Failed > 0} {
lappend failFiles $testFile
+ lappend failFilesAccum $testFile
}
} elseif {[regexp [join {
{^Number of tests skipped }
@@ -2868,7 +2889,7 @@ proc tcltest::runAllTests { {shell ""} } {
puts [outputChannel] ""
puts [outputChannel] [string repeat ~ 44]
}
- return
+ return [expr {[info exists testFileFailures] || [llength $failFilesAccum]}]
}
#####################################################################
diff --git a/tcl8.6/library/tzdata/Africa/Accra b/tcl8.6/library/tzdata/Africa/Accra
index 18f4522..f43f751 100644
--- a/tcl8.6/library/tzdata/Africa/Accra
+++ b/tcl8.6/library/tzdata/Africa/Accra
@@ -2,51 +2,51 @@
set TZData(:Africa/Accra) {
{-9223372036854775808 -52 0 LMT}
- {-1640995148 0 0 +0020}
- {-1556841600 1200 1 +0020}
- {-1546388400 0 0 +0020}
- {-1525305600 1200 1 +0020}
- {-1514852400 0 0 +0020}
- {-1493769600 1200 1 +0020}
- {-1483316400 0 0 +0020}
- {-1462233600 1200 1 +0020}
- {-1451780400 0 0 +0020}
- {-1430611200 1200 1 +0020}
- {-1420158000 0 0 +0020}
- {-1399075200 1200 1 +0020}
- {-1388622000 0 0 +0020}
- {-1367539200 1200 1 +0020}
- {-1357086000 0 0 +0020}
- {-1336003200 1200 1 +0020}
- {-1325550000 0 0 +0020}
- {-1304380800 1200 1 +0020}
- {-1293927600 0 0 +0020}
- {-1272844800 1200 1 +0020}
- {-1262391600 0 0 +0020}
- {-1241308800 1200 1 +0020}
- {-1230855600 0 0 +0020}
- {-1209772800 1200 1 +0020}
- {-1199319600 0 0 +0020}
- {-1178150400 1200 1 +0020}
- {-1167697200 0 0 +0020}
- {-1146614400 1200 1 +0020}
- {-1136161200 0 0 +0020}
- {-1115078400 1200 1 +0020}
- {-1104625200 0 0 +0020}
- {-1083542400 1200 1 +0020}
- {-1073089200 0 0 +0020}
- {-1051920000 1200 1 +0020}
- {-1041466800 0 0 +0020}
- {-1020384000 1200 1 +0020}
- {-1009930800 0 0 +0020}
- {-988848000 1200 1 +0020}
- {-978394800 0 0 +0020}
- {-957312000 1200 1 +0020}
- {-946858800 0 0 +0020}
- {-925689600 1200 1 +0020}
- {-915236400 0 0 +0020}
- {-894153600 1200 1 +0020}
- {-883700400 0 0 +0020}
- {-862617600 1200 1 +0020}
- {-852164400 0 0 +0020}
+ {-1640995148 0 0 GMT}
+ {-1556841600 1200 1 GMT}
+ {-1546388400 0 0 GMT}
+ {-1525305600 1200 1 GMT}
+ {-1514852400 0 0 GMT}
+ {-1493769600 1200 1 GMT}
+ {-1483316400 0 0 GMT}
+ {-1462233600 1200 1 GMT}
+ {-1451780400 0 0 GMT}
+ {-1430611200 1200 1 GMT}
+ {-1420158000 0 0 GMT}
+ {-1399075200 1200 1 GMT}
+ {-1388622000 0 0 GMT}
+ {-1367539200 1200 1 GMT}
+ {-1357086000 0 0 GMT}
+ {-1336003200 1200 1 GMT}
+ {-1325550000 0 0 GMT}
+ {-1304380800 1200 1 GMT}
+ {-1293927600 0 0 GMT}
+ {-1272844800 1200 1 GMT}
+ {-1262391600 0 0 GMT}
+ {-1241308800 1200 1 GMT}
+ {-1230855600 0 0 GMT}
+ {-1209772800 1200 1 GMT}
+ {-1199319600 0 0 GMT}
+ {-1178150400 1200 1 GMT}
+ {-1167697200 0 0 GMT}
+ {-1146614400 1200 1 GMT}
+ {-1136161200 0 0 GMT}
+ {-1115078400 1200 1 GMT}
+ {-1104625200 0 0 GMT}
+ {-1083542400 1200 1 GMT}
+ {-1073089200 0 0 GMT}
+ {-1051920000 1200 1 GMT}
+ {-1041466800 0 0 GMT}
+ {-1020384000 1200 1 GMT}
+ {-1009930800 0 0 GMT}
+ {-988848000 1200 1 GMT}
+ {-978394800 0 0 GMT}
+ {-957312000 1200 1 GMT}
+ {-946858800 0 0 GMT}
+ {-925689600 1200 1 GMT}
+ {-915236400 0 0 GMT}
+ {-894153600 1200 1 GMT}
+ {-883700400 0 0 GMT}
+ {-862617600 1200 1 GMT}
+ {-852164400 0 0 GMT}
}
diff --git a/tcl8.6/library/tzdata/Africa/Bissau b/tcl8.6/library/tzdata/Africa/Bissau
index 88d9d03..e0568fb 100644
--- a/tcl8.6/library/tzdata/Africa/Bissau
+++ b/tcl8.6/library/tzdata/Africa/Bissau
@@ -2,6 +2,6 @@
set TZData(:Africa/Bissau) {
{-9223372036854775808 -3740 0 LMT}
- {-1830380260 -3600 0 -01}
+ {-1830380400 -3600 0 -01}
{157770000 0 0 GMT}
}
diff --git a/tcl8.6/library/tzdata/Africa/Casablanca b/tcl8.6/library/tzdata/Africa/Casablanca
index 33ad99b..3207e59 100644
--- a/tcl8.6/library/tzdata/Africa/Casablanca
+++ b/tcl8.6/library/tzdata/Africa/Casablanca
@@ -2,229 +2,59 @@
set TZData(:Africa/Casablanca) {
{-9223372036854775808 -1820 0 LMT}
- {-1773012580 0 0 WET}
- {-956361600 3600 1 WEST}
- {-950490000 0 0 WET}
- {-942019200 3600 1 WEST}
- {-761187600 0 0 WET}
- {-617241600 3600 1 WEST}
- {-605149200 0 0 WET}
- {-81432000 3600 1 WEST}
- {-71110800 0 0 WET}
- {141264000 3600 1 WEST}
- {147222000 0 0 WET}
- {199756800 3600 1 WEST}
- {207702000 0 0 WET}
- {231292800 3600 1 WEST}
- {244249200 0 0 WET}
- {265507200 3600 1 WEST}
- {271033200 0 0 WET}
- {448243200 3600 0 CET}
- {504918000 0 0 WET}
- {1212278400 3600 1 WEST}
- {1220223600 0 0 WET}
- {1243814400 3600 1 WEST}
- {1250809200 0 0 WET}
- {1272758400 3600 1 WEST}
- {1281222000 0 0 WET}
- {1301788800 3600 1 WEST}
- {1312066800 0 0 WET}
- {1335664800 3600 1 WEST}
- {1342749600 0 0 WET}
- {1345428000 3600 1 WEST}
- {1348970400 0 0 WET}
- {1367114400 3600 1 WEST}
- {1373162400 0 0 WET}
- {1376100000 3600 1 WEST}
- {1382839200 0 0 WET}
- {1396144800 3600 1 WEST}
- {1403920800 0 0 WET}
- {1406944800 3600 1 WEST}
- {1414288800 0 0 WET}
- {1427594400 3600 1 WEST}
- {1434247200 0 0 WET}
- {1437271200 3600 1 WEST}
- {1445738400 0 0 WET}
- {1459044000 3600 1 WEST}
- {1465092000 0 0 WET}
- {1468116000 3600 1 WEST}
- {1477792800 0 0 WET}
- {1490493600 3600 1 WEST}
- {1495332000 0 0 WET}
- {1498960800 3600 1 WEST}
- {1509242400 0 0 WET}
- {1521943200 3600 1 WEST}
- {1526176800 0 0 WET}
- {1529200800 3600 1 WEST}
- {1540692000 0 0 WET}
- {1553997600 3600 1 WEST}
- {1557021600 0 0 WET}
- {1560045600 3600 1 WEST}
- {1572141600 0 0 WET}
- {1585447200 3600 1 WEST}
- {1587261600 0 0 WET}
- {1590285600 3600 1 WEST}
- {1603591200 0 0 WET}
- {1616896800 3600 1 WEST}
- {1618106400 0 0 WET}
- {1621130400 3600 1 WEST}
- {1635645600 0 0 WET}
- {1651975200 3600 1 WEST}
- {1667095200 0 0 WET}
- {1682215200 3600 1 WEST}
- {1698544800 0 0 WET}
- {1713060000 3600 1 WEST}
- {1729994400 0 0 WET}
- {1743904800 3600 1 WEST}
- {1761444000 0 0 WET}
- {1774749600 3600 1 WEST}
- {1792893600 0 0 WET}
- {1806199200 3600 1 WEST}
- {1824948000 0 0 WET}
- {1837648800 3600 1 WEST}
- {1856397600 0 0 WET}
- {1869098400 3600 1 WEST}
- {1887847200 0 0 WET}
- {1901152800 3600 1 WEST}
- {1919296800 0 0 WET}
- {1932602400 3600 1 WEST}
- {1950746400 0 0 WET}
- {1964052000 3600 1 WEST}
- {1982800800 0 0 WET}
- {1995501600 3600 1 WEST}
- {2014250400 0 0 WET}
- {2026951200 3600 1 WEST}
- {2045700000 0 0 WET}
- {2058400800 3600 1 WEST}
- {2077149600 0 0 WET}
- {2090455200 3600 1 WEST}
- {2107994400 0 0 WET}
- {2108602800 0 0 WET}
- {2121904800 3600 1 WEST}
- {2138234400 0 0 WET}
- {2140052400 0 0 WET}
- {2153354400 3600 1 WEST}
- {2172103200 0 0 WET}
- {2184804000 3600 1 WEST}
- {2203552800 0 0 WET}
- {2216253600 3600 1 WEST}
- {2235002400 0 0 WET}
- {2248308000 3600 1 WEST}
- {2266452000 0 0 WET}
- {2279757600 3600 1 WEST}
- {2297901600 0 0 WET}
- {2311207200 3600 1 WEST}
- {2329351200 0 0 WET}
- {2342656800 3600 1 WEST}
- {2361405600 0 0 WET}
- {2374106400 3600 1 WEST}
- {2392855200 0 0 WET}
- {2405556000 3600 1 WEST}
- {2424304800 0 0 WET}
- {2437610400 3600 1 WEST}
- {2455754400 0 0 WET}
- {2469060000 3600 1 WEST}
- {2487204000 0 0 WET}
- {2500509600 3600 1 WEST}
- {2519258400 0 0 WET}
- {2531959200 3600 1 WEST}
- {2550708000 0 0 WET}
- {2563408800 3600 1 WEST}
- {2582157600 0 0 WET}
- {2595463200 3600 1 WEST}
- {2613607200 0 0 WET}
- {2626912800 3600 1 WEST}
- {2645056800 0 0 WET}
- {2658362400 3600 1 WEST}
- {2676506400 0 0 WET}
- {2689812000 3600 1 WEST}
- {2708560800 0 0 WET}
- {2721261600 3600 1 WEST}
- {2740010400 0 0 WET}
- {2752711200 3600 1 WEST}
- {2771460000 0 0 WET}
- {2784765600 3600 1 WEST}
- {2802909600 0 0 WET}
- {2816215200 3600 1 WEST}
- {2834359200 0 0 WET}
- {2847664800 3600 1 WEST}
- {2866413600 0 0 WET}
- {2879114400 3600 1 WEST}
- {2897863200 0 0 WET}
- {2910564000 3600 1 WEST}
- {2929312800 0 0 WET}
- {2942013600 3600 1 WEST}
- {2960762400 0 0 WET}
- {2974068000 3600 1 WEST}
- {2992212000 0 0 WET}
- {3005517600 3600 1 WEST}
- {3023661600 0 0 WET}
- {3036967200 3600 1 WEST}
- {3055716000 0 0 WET}
- {3068416800 3600 1 WEST}
- {3087165600 0 0 WET}
- {3099866400 3600 1 WEST}
- {3118615200 0 0 WET}
- {3131920800 3600 1 WEST}
- {3150064800 0 0 WET}
- {3163370400 3600 1 WEST}
- {3181514400 0 0 WET}
- {3194820000 3600 1 WEST}
- {3212964000 0 0 WET}
- {3226269600 3600 1 WEST}
- {3245018400 0 0 WET}
- {3257719200 3600 1 WEST}
- {3276468000 0 0 WET}
- {3289168800 3600 1 WEST}
- {3307917600 0 0 WET}
- {3321223200 3600 1 WEST}
- {3339367200 0 0 WET}
- {3352672800 3600 1 WEST}
- {3370816800 0 0 WET}
- {3384122400 3600 1 WEST}
- {3402871200 0 0 WET}
- {3415572000 3600 1 WEST}
- {3434320800 0 0 WET}
- {3447021600 3600 1 WEST}
- {3465770400 0 0 WET}
- {3479076000 3600 1 WEST}
- {3497220000 0 0 WET}
- {3510525600 3600 1 WEST}
- {3528669600 0 0 WET}
- {3541975200 3600 1 WEST}
- {3560119200 0 0 WET}
- {3573424800 3600 1 WEST}
- {3592173600 0 0 WET}
- {3604874400 3600 1 WEST}
- {3623623200 0 0 WET}
- {3636324000 3600 1 WEST}
- {3655072800 0 0 WET}
- {3668378400 3600 1 WEST}
- {3686522400 0 0 WET}
- {3699828000 3600 1 WEST}
- {3717972000 0 0 WET}
- {3731277600 3600 1 WEST}
- {3750026400 0 0 WET}
- {3762727200 3600 1 WEST}
- {3781476000 0 0 WET}
- {3794176800 3600 1 WEST}
- {3812925600 0 0 WET}
- {3825626400 3600 1 WEST}
- {3844375200 0 0 WET}
- {3857680800 3600 1 WEST}
- {3875824800 0 0 WET}
- {3889130400 3600 1 WEST}
- {3907274400 0 0 WET}
- {3920580000 3600 1 WEST}
- {3939328800 0 0 WET}
- {3952029600 3600 1 WEST}
- {3970778400 0 0 WET}
- {3983479200 3600 1 WEST}
- {4002228000 0 0 WET}
- {4015533600 3600 1 WEST}
- {4033677600 0 0 WET}
- {4046983200 3600 1 WEST}
- {4065127200 0 0 WET}
- {4078432800 3600 1 WEST}
- {4096576800 0 0 WET}
+ {-1773012580 0 0 +00}
+ {-956361600 3600 1 +00}
+ {-950490000 0 0 +00}
+ {-942019200 3600 1 +00}
+ {-761187600 0 0 +00}
+ {-617241600 3600 1 +00}
+ {-605149200 0 0 +00}
+ {-81432000 3600 1 +00}
+ {-71110800 0 0 +00}
+ {141264000 3600 1 +00}
+ {147222000 0 0 +00}
+ {199756800 3600 1 +00}
+ {207702000 0 0 +00}
+ {231292800 3600 1 +00}
+ {244249200 0 0 +00}
+ {265507200 3600 1 +00}
+ {271033200 0 0 +00}
+ {448243200 3600 0 +01}
+ {504918000 0 0 +00}
+ {1212278400 3600 1 +00}
+ {1220223600 0 0 +00}
+ {1243814400 3600 1 +00}
+ {1250809200 0 0 +00}
+ {1272758400 3600 1 +00}
+ {1281222000 0 0 +00}
+ {1301788800 3600 1 +00}
+ {1312066800 0 0 +00}
+ {1335664800 3600 1 +00}
+ {1342749600 0 0 +00}
+ {1345428000 3600 1 +00}
+ {1348970400 0 0 +00}
+ {1367114400 3600 1 +00}
+ {1373162400 0 0 +00}
+ {1376100000 3600 1 +00}
+ {1382839200 0 0 +00}
+ {1396144800 3600 1 +00}
+ {1403920800 0 0 +00}
+ {1406944800 3600 1 +00}
+ {1414288800 0 0 +00}
+ {1427594400 3600 1 +00}
+ {1434247200 0 0 +00}
+ {1437271200 3600 1 +00}
+ {1445738400 0 0 +00}
+ {1459044000 3600 1 +00}
+ {1465092000 0 0 +00}
+ {1468116000 3600 1 +00}
+ {1477792800 0 0 +00}
+ {1490493600 3600 1 +00}
+ {1495332000 0 0 +00}
+ {1498960800 3600 1 +00}
+ {1509242400 0 0 +00}
+ {1521943200 3600 1 +00}
+ {1526176800 0 0 +00}
+ {1529200800 3600 1 +00}
+ {1540598400 3600 0 +01}
}
diff --git a/tcl8.6/library/tzdata/Africa/Ceuta b/tcl8.6/library/tzdata/Africa/Ceuta
index 057ca22..18af8c1 100644
--- a/tcl8.6/library/tzdata/Africa/Ceuta
+++ b/tcl8.6/library/tzdata/Africa/Ceuta
@@ -15,6 +15,7 @@ set TZData(:Africa/Ceuta) {
{-1316390400 3600 1 WEST}
{-1301270400 0 0 WET}
{-1293840000 0 0 WET}
+ {-94694400 0 0 WET}
{-81432000 3600 1 WEST}
{-71110800 0 0 WET}
{141264000 3600 1 WEST}
diff --git a/tcl8.6/library/tzdata/Africa/El_Aaiun b/tcl8.6/library/tzdata/Africa/El_Aaiun
index 7bdc496..e0f5e1c 100644
--- a/tcl8.6/library/tzdata/Africa/El_Aaiun
+++ b/tcl8.6/library/tzdata/Africa/El_Aaiun
@@ -3,217 +3,47 @@
set TZData(:Africa/El_Aaiun) {
{-9223372036854775808 -3168 0 LMT}
{-1136070432 -3600 0 -01}
- {198291600 0 0 WET}
- {199756800 3600 1 WEST}
- {207702000 0 0 WET}
- {231292800 3600 1 WEST}
- {244249200 0 0 WET}
- {265507200 3600 1 WEST}
- {271033200 0 0 WET}
- {1212278400 3600 1 WEST}
- {1220223600 0 0 WET}
- {1243814400 3600 1 WEST}
- {1250809200 0 0 WET}
- {1272758400 3600 1 WEST}
- {1281222000 0 0 WET}
- {1301788800 3600 1 WEST}
- {1312066800 0 0 WET}
- {1335664800 3600 1 WEST}
- {1342749600 0 0 WET}
- {1345428000 3600 1 WEST}
- {1348970400 0 0 WET}
- {1367114400 3600 1 WEST}
- {1373162400 0 0 WET}
- {1376100000 3600 1 WEST}
- {1382839200 0 0 WET}
- {1396144800 3600 1 WEST}
- {1403920800 0 0 WET}
- {1406944800 3600 1 WEST}
- {1414288800 0 0 WET}
- {1427594400 3600 1 WEST}
- {1434247200 0 0 WET}
- {1437271200 3600 1 WEST}
- {1445738400 0 0 WET}
- {1459044000 3600 1 WEST}
- {1465092000 0 0 WET}
- {1468116000 3600 1 WEST}
- {1477792800 0 0 WET}
- {1490493600 3600 1 WEST}
- {1495332000 0 0 WET}
- {1498960800 3600 1 WEST}
- {1509242400 0 0 WET}
- {1521943200 3600 1 WEST}
- {1526176800 0 0 WET}
- {1529200800 3600 1 WEST}
- {1540692000 0 0 WET}
- {1553997600 3600 1 WEST}
- {1557021600 0 0 WET}
- {1560045600 3600 1 WEST}
- {1572141600 0 0 WET}
- {1585447200 3600 1 WEST}
- {1587261600 0 0 WET}
- {1590285600 3600 1 WEST}
- {1603591200 0 0 WET}
- {1616896800 3600 1 WEST}
- {1618106400 0 0 WET}
- {1621130400 3600 1 WEST}
- {1635645600 0 0 WET}
- {1651975200 3600 1 WEST}
- {1667095200 0 0 WET}
- {1682215200 3600 1 WEST}
- {1698544800 0 0 WET}
- {1713060000 3600 1 WEST}
- {1729994400 0 0 WET}
- {1743904800 3600 1 WEST}
- {1761444000 0 0 WET}
- {1774749600 3600 1 WEST}
- {1792893600 0 0 WET}
- {1806199200 3600 1 WEST}
- {1824948000 0 0 WET}
- {1837648800 3600 1 WEST}
- {1856397600 0 0 WET}
- {1869098400 3600 1 WEST}
- {1887847200 0 0 WET}
- {1901152800 3600 1 WEST}
- {1919296800 0 0 WET}
- {1932602400 3600 1 WEST}
- {1950746400 0 0 WET}
- {1964052000 3600 1 WEST}
- {1982800800 0 0 WET}
- {1995501600 3600 1 WEST}
- {2014250400 0 0 WET}
- {2026951200 3600 1 WEST}
- {2045700000 0 0 WET}
- {2058400800 3600 1 WEST}
- {2077149600 0 0 WET}
- {2090455200 3600 1 WEST}
- {2107994400 0 0 WET}
- {2108602800 0 0 WET}
- {2121904800 3600 1 WEST}
- {2138234400 0 0 WET}
- {2140052400 0 0 WET}
- {2153354400 3600 1 WEST}
- {2172103200 0 0 WET}
- {2184804000 3600 1 WEST}
- {2203552800 0 0 WET}
- {2216253600 3600 1 WEST}
- {2235002400 0 0 WET}
- {2248308000 3600 1 WEST}
- {2266452000 0 0 WET}
- {2279757600 3600 1 WEST}
- {2297901600 0 0 WET}
- {2311207200 3600 1 WEST}
- {2329351200 0 0 WET}
- {2342656800 3600 1 WEST}
- {2361405600 0 0 WET}
- {2374106400 3600 1 WEST}
- {2392855200 0 0 WET}
- {2405556000 3600 1 WEST}
- {2424304800 0 0 WET}
- {2437610400 3600 1 WEST}
- {2455754400 0 0 WET}
- {2469060000 3600 1 WEST}
- {2487204000 0 0 WET}
- {2500509600 3600 1 WEST}
- {2519258400 0 0 WET}
- {2531959200 3600 1 WEST}
- {2550708000 0 0 WET}
- {2563408800 3600 1 WEST}
- {2582157600 0 0 WET}
- {2595463200 3600 1 WEST}
- {2613607200 0 0 WET}
- {2626912800 3600 1 WEST}
- {2645056800 0 0 WET}
- {2658362400 3600 1 WEST}
- {2676506400 0 0 WET}
- {2689812000 3600 1 WEST}
- {2708560800 0 0 WET}
- {2721261600 3600 1 WEST}
- {2740010400 0 0 WET}
- {2752711200 3600 1 WEST}
- {2771460000 0 0 WET}
- {2784765600 3600 1 WEST}
- {2802909600 0 0 WET}
- {2816215200 3600 1 WEST}
- {2834359200 0 0 WET}
- {2847664800 3600 1 WEST}
- {2866413600 0 0 WET}
- {2879114400 3600 1 WEST}
- {2897863200 0 0 WET}
- {2910564000 3600 1 WEST}
- {2929312800 0 0 WET}
- {2942013600 3600 1 WEST}
- {2960762400 0 0 WET}
- {2974068000 3600 1 WEST}
- {2992212000 0 0 WET}
- {3005517600 3600 1 WEST}
- {3023661600 0 0 WET}
- {3036967200 3600 1 WEST}
- {3055716000 0 0 WET}
- {3068416800 3600 1 WEST}
- {3087165600 0 0 WET}
- {3099866400 3600 1 WEST}
- {3118615200 0 0 WET}
- {3131920800 3600 1 WEST}
- {3150064800 0 0 WET}
- {3163370400 3600 1 WEST}
- {3181514400 0 0 WET}
- {3194820000 3600 1 WEST}
- {3212964000 0 0 WET}
- {3226269600 3600 1 WEST}
- {3245018400 0 0 WET}
- {3257719200 3600 1 WEST}
- {3276468000 0 0 WET}
- {3289168800 3600 1 WEST}
- {3307917600 0 0 WET}
- {3321223200 3600 1 WEST}
- {3339367200 0 0 WET}
- {3352672800 3600 1 WEST}
- {3370816800 0 0 WET}
- {3384122400 3600 1 WEST}
- {3402871200 0 0 WET}
- {3415572000 3600 1 WEST}
- {3434320800 0 0 WET}
- {3447021600 3600 1 WEST}
- {3465770400 0 0 WET}
- {3479076000 3600 1 WEST}
- {3497220000 0 0 WET}
- {3510525600 3600 1 WEST}
- {3528669600 0 0 WET}
- {3541975200 3600 1 WEST}
- {3560119200 0 0 WET}
- {3573424800 3600 1 WEST}
- {3592173600 0 0 WET}
- {3604874400 3600 1 WEST}
- {3623623200 0 0 WET}
- {3636324000 3600 1 WEST}
- {3655072800 0 0 WET}
- {3668378400 3600 1 WEST}
- {3686522400 0 0 WET}
- {3699828000 3600 1 WEST}
- {3717972000 0 0 WET}
- {3731277600 3600 1 WEST}
- {3750026400 0 0 WET}
- {3762727200 3600 1 WEST}
- {3781476000 0 0 WET}
- {3794176800 3600 1 WEST}
- {3812925600 0 0 WET}
- {3825626400 3600 1 WEST}
- {3844375200 0 0 WET}
- {3857680800 3600 1 WEST}
- {3875824800 0 0 WET}
- {3889130400 3600 1 WEST}
- {3907274400 0 0 WET}
- {3920580000 3600 1 WEST}
- {3939328800 0 0 WET}
- {3952029600 3600 1 WEST}
- {3970778400 0 0 WET}
- {3983479200 3600 1 WEST}
- {4002228000 0 0 WET}
- {4015533600 3600 1 WEST}
- {4033677600 0 0 WET}
- {4046983200 3600 1 WEST}
- {4065127200 0 0 WET}
- {4078432800 3600 1 WEST}
- {4096576800 0 0 WET}
+ {198291600 0 0 +00}
+ {199756800 3600 1 +00}
+ {207702000 0 0 +00}
+ {231292800 3600 1 +00}
+ {244249200 0 0 +00}
+ {265507200 3600 1 +00}
+ {271033200 0 0 +00}
+ {1212278400 3600 1 +00}
+ {1220223600 0 0 +00}
+ {1243814400 3600 1 +00}
+ {1250809200 0 0 +00}
+ {1272758400 3600 1 +00}
+ {1281222000 0 0 +00}
+ {1301788800 3600 1 +00}
+ {1312066800 0 0 +00}
+ {1335664800 3600 1 +00}
+ {1342749600 0 0 +00}
+ {1345428000 3600 1 +00}
+ {1348970400 0 0 +00}
+ {1367114400 3600 1 +00}
+ {1373162400 0 0 +00}
+ {1376100000 3600 1 +00}
+ {1382839200 0 0 +00}
+ {1396144800 3600 1 +00}
+ {1403920800 0 0 +00}
+ {1406944800 3600 1 +00}
+ {1414288800 0 0 +00}
+ {1427594400 3600 1 +00}
+ {1434247200 0 0 +00}
+ {1437271200 3600 1 +00}
+ {1445738400 0 0 +00}
+ {1459044000 3600 1 +00}
+ {1465092000 0 0 +00}
+ {1468116000 3600 1 +00}
+ {1477792800 0 0 +00}
+ {1490493600 3600 1 +00}
+ {1495332000 0 0 +00}
+ {1498960800 3600 1 +00}
+ {1509242400 0 0 +00}
+ {1521943200 3600 1 +00}
+ {1526176800 0 0 +00}
+ {1529200800 3600 1 +00}
+ {1540598400 3600 0 +01}
}
diff --git a/tcl8.6/library/tzdata/Africa/Sao_Tome b/tcl8.6/library/tzdata/Africa/Sao_Tome
index 078591d..6a60f5c 100644
--- a/tcl8.6/library/tzdata/Africa/Sao_Tome
+++ b/tcl8.6/library/tzdata/Africa/Sao_Tome
@@ -1,5 +1,8 @@
# created by tools/tclZIC.tcl - do not edit
-if {![info exists TZData(Africa/Abidjan)]} {
- LoadTimeZoneFile Africa/Abidjan
+
+set TZData(:Africa/Sao_Tome) {
+ {-9223372036854775808 1616 0 LMT}
+ {-2713912016 -2205 0 LMT}
+ {-1830384000 0 0 GMT}
+ {1514768400 3600 0 WAT}
}
-set TZData(:Africa/Sao_Tome) $TZData(:Africa/Abidjan)
diff --git a/tcl8.6/library/tzdata/Africa/Windhoek b/tcl8.6/library/tzdata/Africa/Windhoek
index 974ebda..d03c8b8 100644
--- a/tcl8.6/library/tzdata/Africa/Windhoek
+++ b/tcl8.6/library/tzdata/Africa/Windhoek
@@ -7,53 +7,52 @@ set TZData(:Africa/Windhoek) {
{-860976000 10800 1 SAST}
{-845254800 7200 0 SAST}
{637970400 7200 0 CAT}
- {764200800 3600 0 WAT}
- {764204400 3600 0 WAT}
- {778640400 7200 1 WAST}
- {796780800 3600 0 WAT}
- {810090000 7200 1 WAST}
- {828835200 3600 0 WAT}
- {841539600 7200 1 WAST}
- {860284800 3600 0 WAT}
- {873594000 7200 1 WAST}
- {891734400 3600 0 WAT}
- {905043600 7200 1 WAST}
- {923184000 3600 0 WAT}
- {936493200 7200 1 WAST}
- {954633600 3600 0 WAT}
- {967942800 7200 1 WAST}
- {986083200 3600 0 WAT}
- {999392400 7200 1 WAST}
- {1018137600 3600 0 WAT}
- {1030842000 7200 1 WAST}
- {1049587200 3600 0 WAT}
- {1062896400 7200 1 WAST}
- {1081036800 3600 0 WAT}
- {1094346000 7200 1 WAST}
- {1112486400 3600 0 WAT}
- {1125795600 7200 1 WAST}
- {1143936000 3600 0 WAT}
- {1157245200 7200 1 WAST}
- {1175385600 3600 0 WAT}
- {1188694800 7200 1 WAST}
- {1207440000 3600 0 WAT}
- {1220749200 7200 1 WAST}
- {1238889600 3600 0 WAT}
- {1252198800 7200 1 WAST}
- {1270339200 3600 0 WAT}
- {1283648400 7200 1 WAST}
- {1301788800 3600 0 WAT}
- {1315098000 7200 1 WAST}
- {1333238400 3600 0 WAT}
- {1346547600 7200 1 WAST}
- {1365292800 3600 0 WAT}
- {1377997200 7200 1 WAST}
- {1396742400 3600 0 WAT}
- {1410051600 7200 1 WAST}
- {1428192000 3600 0 WAT}
- {1441501200 7200 1 WAST}
- {1459641600 3600 0 WAT}
- {1472950800 7200 1 WAST}
- {1491091200 3600 0 WAT}
+ {764200800 3600 1 WAT}
+ {778640400 7200 0 CAT}
+ {796780800 3600 1 WAT}
+ {810090000 7200 0 CAT}
+ {828835200 3600 1 WAT}
+ {841539600 7200 0 CAT}
+ {860284800 3600 1 WAT}
+ {873594000 7200 0 CAT}
+ {891734400 3600 1 WAT}
+ {905043600 7200 0 CAT}
+ {923184000 3600 1 WAT}
+ {936493200 7200 0 CAT}
+ {954633600 3600 1 WAT}
+ {967942800 7200 0 CAT}
+ {986083200 3600 1 WAT}
+ {999392400 7200 0 CAT}
+ {1018137600 3600 1 WAT}
+ {1030842000 7200 0 CAT}
+ {1049587200 3600 1 WAT}
+ {1062896400 7200 0 CAT}
+ {1081036800 3600 1 WAT}
+ {1094346000 7200 0 CAT}
+ {1112486400 3600 1 WAT}
+ {1125795600 7200 0 CAT}
+ {1143936000 3600 1 WAT}
+ {1157245200 7200 0 CAT}
+ {1175385600 3600 1 WAT}
+ {1188694800 7200 0 CAT}
+ {1207440000 3600 1 WAT}
+ {1220749200 7200 0 CAT}
+ {1238889600 3600 1 WAT}
+ {1252198800 7200 0 CAT}
+ {1270339200 3600 1 WAT}
+ {1283648400 7200 0 CAT}
+ {1301788800 3600 1 WAT}
+ {1315098000 7200 0 CAT}
+ {1333238400 3600 1 WAT}
+ {1346547600 7200 0 CAT}
+ {1365292800 3600 1 WAT}
+ {1377997200 7200 0 CAT}
+ {1396742400 3600 1 WAT}
+ {1410051600 7200 0 CAT}
+ {1428192000 3600 1 WAT}
+ {1441501200 7200 0 CAT}
+ {1459641600 3600 1 WAT}
+ {1472950800 7200 0 CAT}
+ {1491091200 3600 1 WAT}
{1504400400 7200 0 CAT}
}
diff --git a/tcl8.6/library/tzdata/America/Araguaina b/tcl8.6/library/tzdata/America/Araguaina
index b9e2aec..ca64292 100644
--- a/tcl8.6/library/tzdata/America/Araguaina
+++ b/tcl8.6/library/tzdata/America/Araguaina
@@ -3,58 +3,58 @@
set TZData(:America/Araguaina) {
{-9223372036854775808 -11568 0 LMT}
{-1767214032 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
{653536800 -10800 0 -03}
{811047600 -10800 0 -03}
- {813726000 -7200 1 -02}
+ {813726000 -7200 1 -03}
{824004000 -10800 0 -03}
- {844570800 -7200 1 -02}
+ {844570800 -7200 1 -03}
{856058400 -10800 0 -03}
- {876106800 -7200 1 -02}
+ {876106800 -7200 1 -03}
{888717600 -10800 0 -03}
- {908074800 -7200 1 -02}
+ {908074800 -7200 1 -03}
{919562400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{982461600 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
- {1036292400 -7200 1 -02}
+ {1036292400 -7200 1 -03}
{1045360800 -10800 0 -03}
{1064368800 -10800 0 -03}
- {1350788400 -7200 0 -02}
+ {1350788400 -7200 0 -03}
{1361066400 -10800 0 -03}
{1378000800 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Buenos_Aires b/tcl8.6/library/tzdata/America/Argentina/Buenos_Aires
index 8be2c45..40f1912 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Buenos_Aires
+++ b/tcl8.6/library/tzdata/America/Argentina/Buenos_Aires
@@ -4,64 +4,64 @@ set TZData(:America/Argentina/Buenos_Aires) {
{-9223372036854775808 -14028 0 LMT}
{-2372097972 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
- {1224385200 -7200 1 -02}
+ {1224385200 -7200 1 -03}
{1237082400 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Catamarca b/tcl8.6/library/tzdata/America/Argentina/Catamarca
index a546bfc..da5b42a 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Catamarca
+++ b/tcl8.6/library/tzdata/America/Argentina/Catamarca
@@ -4,65 +4,65 @@ set TZData(:America/Argentina/Catamarca) {
{-9223372036854775808 -15788 0 LMT}
{-2372096212 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -14400 0 -04}
- {687931200 -7200 0 -02}
+ {687931200 -7200 0 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1086058800 -14400 0 -04}
{1087704000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Cordoba b/tcl8.6/library/tzdata/America/Argentina/Cordoba
index ec6978e..6a1426e 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Cordoba
+++ b/tcl8.6/library/tzdata/America/Argentina/Cordoba
@@ -4,64 +4,64 @@ set TZData(:America/Argentina/Cordoba) {
{-9223372036854775808 -15408 0 LMT}
{-2372096592 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -14400 0 -04}
- {687931200 -7200 0 -02}
+ {687931200 -7200 0 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
- {1224385200 -7200 1 -02}
+ {1224385200 -7200 1 -03}
{1237082400 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Jujuy b/tcl8.6/library/tzdata/America/Argentina/Jujuy
index 0e11ba2..72080f5 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Jujuy
+++ b/tcl8.6/library/tzdata/America/Argentina/Jujuy
@@ -4,64 +4,64 @@ set TZData(:America/Argentina/Jujuy) {
{-9223372036854775808 -15672 0 LMT}
{-2372096328 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -14400 0 -04}
{657086400 -10800 1 -03}
{669178800 -14400 0 -04}
{686721600 -7200 1 -02}
{694231200 -7200 0 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/La_Rioja b/tcl8.6/library/tzdata/America/Argentina/La_Rioja
index 90e0030..fb7b237 100644
--- a/tcl8.6/library/tzdata/America/Argentina/La_Rioja
+++ b/tcl8.6/library/tzdata/America/Argentina/La_Rioja
@@ -4,66 +4,66 @@ set TZData(:America/Argentina/La_Rioja) {
{-9223372036854775808 -16044 0 LMT}
{-2372095956 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667792800 -14400 0 -04}
{673588800 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1086058800 -14400 0 -04}
{1087704000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Mendoza b/tcl8.6/library/tzdata/America/Argentina/Mendoza
index 8dfcd2b..af7342e 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Mendoza
+++ b/tcl8.6/library/tzdata/America/Argentina/Mendoza
@@ -4,65 +4,65 @@ set TZData(:America/Argentina/Mendoza) {
{-9223372036854775808 -16516 0 LMT}
{-2372095484 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -14400 0 -04}
{655963200 -10800 1 -03}
{667796400 -14400 0 -04}
{687499200 -10800 1 -03}
{699418800 -14400 0 -04}
- {719380800 -7200 0 -02}
+ {719380800 -7200 0 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1085281200 -14400 0 -04}
{1096171200 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Rio_Gallegos b/tcl8.6/library/tzdata/America/Argentina/Rio_Gallegos
index 4b2a348..2a197a4 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Rio_Gallegos
+++ b/tcl8.6/library/tzdata/America/Argentina/Rio_Gallegos
@@ -4,65 +4,65 @@ set TZData(:America/Argentina/Rio_Gallegos) {
{-9223372036854775808 -16612 0 LMT}
{-2372095388 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1086058800 -14400 0 -04}
{1087704000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Salta b/tcl8.6/library/tzdata/America/Argentina/Salta
index 4f9ccf9..d49e82f 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Salta
+++ b/tcl8.6/library/tzdata/America/Argentina/Salta
@@ -4,63 +4,63 @@ set TZData(:America/Argentina/Salta) {
{-9223372036854775808 -15700 0 LMT}
{-2372096300 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -14400 0 -04}
- {687931200 -7200 0 -02}
+ {687931200 -7200 0 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/San_Juan b/tcl8.6/library/tzdata/America/Argentina/San_Juan
index 1f0530a..d67f688 100644
--- a/tcl8.6/library/tzdata/America/Argentina/San_Juan
+++ b/tcl8.6/library/tzdata/America/Argentina/San_Juan
@@ -4,66 +4,66 @@ set TZData(:America/Argentina/San_Juan) {
{-9223372036854775808 -16444 0 LMT}
{-2372095556 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667792800 -14400 0 -04}
{673588800 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1085972400 -14400 0 -04}
{1090728000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/San_Luis b/tcl8.6/library/tzdata/America/Argentina/San_Luis
index 3583a39..4d27c32 100644
--- a/tcl8.6/library/tzdata/America/Argentina/San_Luis
+++ b/tcl8.6/library/tzdata/America/Argentina/San_Luis
@@ -4,52 +4,52 @@ set TZData(:America/Argentina/San_Luis) {
{-9223372036854775808 -15924 0 LMT}
{-2372096076 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{631159200 -7200 1 -02}
{637380000 -14400 0 -04}
{655963200 -10800 1 -03}
@@ -59,10 +59,10 @@ set TZData(:America/Argentina/San_Luis) {
{952052400 -10800 0 -03}
{1085972400 -14400 0 -04}
{1090728000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1200880800 -10800 0 -04}
{1205031600 -14400 0 -04}
- {1223784000 -10800 1 -03}
+ {1223784000 -10800 1 -04}
{1236481200 -14400 0 -04}
{1255233600 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Tucuman b/tcl8.6/library/tzdata/America/Argentina/Tucuman
index 15c5c63..6809800 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Tucuman
+++ b/tcl8.6/library/tzdata/America/Argentina/Tucuman
@@ -4,66 +4,66 @@ set TZData(:America/Argentina/Tucuman) {
{-9223372036854775808 -15652 0 LMT}
{-2372096348 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -14400 0 -04}
- {687931200 -7200 0 -02}
+ {687931200 -7200 0 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1086058800 -14400 0 -04}
{1087099200 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
- {1224385200 -7200 1 -02}
+ {1224385200 -7200 1 -03}
{1237082400 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Argentina/Ushuaia b/tcl8.6/library/tzdata/America/Argentina/Ushuaia
index 4214c1d..c62ca0d 100644
--- a/tcl8.6/library/tzdata/America/Argentina/Ushuaia
+++ b/tcl8.6/library/tzdata/America/Argentina/Ushuaia
@@ -4,65 +4,65 @@ set TZData(:America/Argentina/Ushuaia) {
{-9223372036854775808 -16392 0 LMT}
{-2372095608 -15408 0 CMT}
{-1567453392 -14400 0 -04}
- {-1233432000 -10800 0 -03}
+ {-1233432000 -10800 0 -04}
{-1222981200 -14400 0 -04}
- {-1205956800 -10800 1 -03}
+ {-1205956800 -10800 1 -04}
{-1194037200 -14400 0 -04}
- {-1172865600 -10800 1 -03}
+ {-1172865600 -10800 1 -04}
{-1162501200 -14400 0 -04}
- {-1141329600 -10800 1 -03}
+ {-1141329600 -10800 1 -04}
{-1130965200 -14400 0 -04}
- {-1109793600 -10800 1 -03}
+ {-1109793600 -10800 1 -04}
{-1099429200 -14400 0 -04}
- {-1078257600 -10800 1 -03}
+ {-1078257600 -10800 1 -04}
{-1067806800 -14400 0 -04}
- {-1046635200 -10800 1 -03}
+ {-1046635200 -10800 1 -04}
{-1036270800 -14400 0 -04}
- {-1015099200 -10800 1 -03}
+ {-1015099200 -10800 1 -04}
{-1004734800 -14400 0 -04}
- {-983563200 -10800 1 -03}
+ {-983563200 -10800 1 -04}
{-973198800 -14400 0 -04}
- {-952027200 -10800 1 -03}
+ {-952027200 -10800 1 -04}
{-941576400 -14400 0 -04}
- {-931032000 -10800 1 -03}
+ {-931032000 -10800 1 -04}
{-900882000 -14400 0 -04}
- {-890337600 -10800 1 -03}
+ {-890337600 -10800 1 -04}
{-833749200 -14400 0 -04}
- {-827265600 -10800 1 -03}
+ {-827265600 -10800 1 -04}
{-752274000 -14400 0 -04}
- {-733780800 -10800 1 -03}
+ {-733780800 -10800 1 -04}
{-197326800 -14400 0 -04}
- {-190843200 -10800 1 -03}
+ {-190843200 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-164491200 -10800 1 -03}
+ {-164491200 -10800 1 -04}
{-152658000 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
- {596948400 -7200 1 -02}
+ {596948400 -7200 1 -03}
{605066400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{667965600 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{731469600 -10800 0 -03}
{938916000 -10800 0 -04}
- {938919600 -10800 1 -03}
+ {938919600 -10800 1 -04}
{952056000 -10800 0 -03}
{1085886000 -14400 0 -04}
{1087704000 -10800 0 -03}
- {1198983600 -7200 1 -02}
+ {1198983600 -7200 1 -03}
{1205632800 -10800 0 -03}
{1224295200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Asuncion b/tcl8.6/library/tzdata/America/Asuncion
index 606db57..8e6c1b0 100644
--- a/tcl8.6/library/tzdata/America/Asuncion
+++ b/tcl8.6/library/tzdata/America/Asuncion
@@ -7,253 +7,253 @@ set TZData(:America/Asuncion) {
{86760000 -10800 0 -03}
{134017200 -14400 0 -04}
{162878400 -14400 0 -04}
- {181368000 -10800 1 -03}
+ {181368000 -10800 1 -04}
{194497200 -14400 0 -04}
- {212990400 -10800 1 -03}
+ {212990400 -10800 1 -04}
{226033200 -14400 0 -04}
- {244526400 -10800 1 -03}
+ {244526400 -10800 1 -04}
{257569200 -14400 0 -04}
- {276062400 -10800 1 -03}
+ {276062400 -10800 1 -04}
{291783600 -14400 0 -04}
- {307598400 -10800 1 -03}
+ {307598400 -10800 1 -04}
{323406000 -14400 0 -04}
- {339220800 -10800 1 -03}
+ {339220800 -10800 1 -04}
{354942000 -14400 0 -04}
- {370756800 -10800 1 -03}
+ {370756800 -10800 1 -04}
{386478000 -14400 0 -04}
- {402292800 -10800 1 -03}
+ {402292800 -10800 1 -04}
{418014000 -14400 0 -04}
- {433828800 -10800 1 -03}
+ {433828800 -10800 1 -04}
{449636400 -14400 0 -04}
- {465451200 -10800 1 -03}
+ {465451200 -10800 1 -04}
{481172400 -14400 0 -04}
- {496987200 -10800 1 -03}
+ {496987200 -10800 1 -04}
{512708400 -14400 0 -04}
- {528523200 -10800 1 -03}
+ {528523200 -10800 1 -04}
{544244400 -14400 0 -04}
- {560059200 -10800 1 -03}
+ {560059200 -10800 1 -04}
{575866800 -14400 0 -04}
- {591681600 -10800 1 -03}
+ {591681600 -10800 1 -04}
{607402800 -14400 0 -04}
- {625032000 -10800 1 -03}
+ {625032000 -10800 1 -04}
{638938800 -14400 0 -04}
- {654753600 -10800 1 -03}
+ {654753600 -10800 1 -04}
{670474800 -14400 0 -04}
- {686721600 -10800 1 -03}
+ {686721600 -10800 1 -04}
{699418800 -14400 0 -04}
- {718257600 -10800 1 -03}
+ {718257600 -10800 1 -04}
{733546800 -14400 0 -04}
- {749448000 -10800 1 -03}
+ {749448000 -10800 1 -04}
{762318000 -14400 0 -04}
- {780984000 -10800 1 -03}
+ {780984000 -10800 1 -04}
{793767600 -14400 0 -04}
- {812520000 -10800 1 -03}
+ {812520000 -10800 1 -04}
{825649200 -14400 0 -04}
- {844574400 -10800 1 -03}
+ {844574400 -10800 1 -04}
{856666800 -14400 0 -04}
- {876024000 -10800 1 -03}
+ {876024000 -10800 1 -04}
{888721200 -14400 0 -04}
- {907473600 -10800 1 -03}
+ {907473600 -10800 1 -04}
{920775600 -14400 0 -04}
- {938923200 -10800 1 -03}
+ {938923200 -10800 1 -04}
{952225200 -14400 0 -04}
- {970372800 -10800 1 -03}
+ {970372800 -10800 1 -04}
{983674800 -14400 0 -04}
- {1002427200 -10800 1 -03}
+ {1002427200 -10800 1 -04}
{1018148400 -14400 0 -04}
- {1030852800 -10800 1 -03}
+ {1030852800 -10800 1 -04}
{1049598000 -14400 0 -04}
- {1062907200 -10800 1 -03}
+ {1062907200 -10800 1 -04}
{1081047600 -14400 0 -04}
- {1097985600 -10800 1 -03}
+ {1097985600 -10800 1 -04}
{1110682800 -14400 0 -04}
- {1129435200 -10800 1 -03}
+ {1129435200 -10800 1 -04}
{1142132400 -14400 0 -04}
- {1160884800 -10800 1 -03}
+ {1160884800 -10800 1 -04}
{1173582000 -14400 0 -04}
- {1192939200 -10800 1 -03}
+ {1192939200 -10800 1 -04}
{1205031600 -14400 0 -04}
- {1224388800 -10800 1 -03}
+ {1224388800 -10800 1 -04}
{1236481200 -14400 0 -04}
- {1255838400 -10800 1 -03}
+ {1255838400 -10800 1 -04}
{1270954800 -14400 0 -04}
- {1286078400 -10800 1 -03}
+ {1286078400 -10800 1 -04}
{1302404400 -14400 0 -04}
- {1317528000 -10800 1 -03}
+ {1317528000 -10800 1 -04}
{1333854000 -14400 0 -04}
- {1349582400 -10800 1 -03}
+ {1349582400 -10800 1 -04}
{1364094000 -14400 0 -04}
- {1381032000 -10800 1 -03}
+ {1381032000 -10800 1 -04}
{1395543600 -14400 0 -04}
- {1412481600 -10800 1 -03}
+ {1412481600 -10800 1 -04}
{1426993200 -14400 0 -04}
- {1443931200 -10800 1 -03}
+ {1443931200 -10800 1 -04}
{1459047600 -14400 0 -04}
- {1475380800 -10800 1 -03}
+ {1475380800 -10800 1 -04}
{1490497200 -14400 0 -04}
- {1506830400 -10800 1 -03}
+ {1506830400 -10800 1 -04}
{1521946800 -14400 0 -04}
- {1538884800 -10800 1 -03}
+ {1538884800 -10800 1 -04}
{1553396400 -14400 0 -04}
- {1570334400 -10800 1 -03}
+ {1570334400 -10800 1 -04}
{1584846000 -14400 0 -04}
- {1601784000 -10800 1 -03}
+ {1601784000 -10800 1 -04}
{1616900400 -14400 0 -04}
- {1633233600 -10800 1 -03}
+ {1633233600 -10800 1 -04}
{1648350000 -14400 0 -04}
- {1664683200 -10800 1 -03}
+ {1664683200 -10800 1 -04}
{1679799600 -14400 0 -04}
- {1696132800 -10800 1 -03}
+ {1696132800 -10800 1 -04}
{1711249200 -14400 0 -04}
- {1728187200 -10800 1 -03}
+ {1728187200 -10800 1 -04}
{1742698800 -14400 0 -04}
- {1759636800 -10800 1 -03}
+ {1759636800 -10800 1 -04}
{1774148400 -14400 0 -04}
- {1791086400 -10800 1 -03}
+ {1791086400 -10800 1 -04}
{1806202800 -14400 0 -04}
- {1822536000 -10800 1 -03}
+ {1822536000 -10800 1 -04}
{1837652400 -14400 0 -04}
- {1853985600 -10800 1 -03}
+ {1853985600 -10800 1 -04}
{1869102000 -14400 0 -04}
- {1886040000 -10800 1 -03}
+ {1886040000 -10800 1 -04}
{1900551600 -14400 0 -04}
- {1917489600 -10800 1 -03}
+ {1917489600 -10800 1 -04}
{1932001200 -14400 0 -04}
- {1948939200 -10800 1 -03}
+ {1948939200 -10800 1 -04}
{1964055600 -14400 0 -04}
- {1980388800 -10800 1 -03}
+ {1980388800 -10800 1 -04}
{1995505200 -14400 0 -04}
- {2011838400 -10800 1 -03}
+ {2011838400 -10800 1 -04}
{2026954800 -14400 0 -04}
- {2043288000 -10800 1 -03}
+ {2043288000 -10800 1 -04}
{2058404400 -14400 0 -04}
- {2075342400 -10800 1 -03}
+ {2075342400 -10800 1 -04}
{2089854000 -14400 0 -04}
- {2106792000 -10800 1 -03}
+ {2106792000 -10800 1 -04}
{2121303600 -14400 0 -04}
- {2138241600 -10800 1 -03}
+ {2138241600 -10800 1 -04}
{2153358000 -14400 0 -04}
- {2169691200 -10800 1 -03}
+ {2169691200 -10800 1 -04}
{2184807600 -14400 0 -04}
- {2201140800 -10800 1 -03}
+ {2201140800 -10800 1 -04}
{2216257200 -14400 0 -04}
- {2233195200 -10800 1 -03}
+ {2233195200 -10800 1 -04}
{2247706800 -14400 0 -04}
- {2264644800 -10800 1 -03}
+ {2264644800 -10800 1 -04}
{2279156400 -14400 0 -04}
- {2296094400 -10800 1 -03}
+ {2296094400 -10800 1 -04}
{2310606000 -14400 0 -04}
- {2327544000 -10800 1 -03}
+ {2327544000 -10800 1 -04}
{2342660400 -14400 0 -04}
- {2358993600 -10800 1 -03}
+ {2358993600 -10800 1 -04}
{2374110000 -14400 0 -04}
- {2390443200 -10800 1 -03}
+ {2390443200 -10800 1 -04}
{2405559600 -14400 0 -04}
- {2422497600 -10800 1 -03}
+ {2422497600 -10800 1 -04}
{2437009200 -14400 0 -04}
- {2453947200 -10800 1 -03}
+ {2453947200 -10800 1 -04}
{2468458800 -14400 0 -04}
- {2485396800 -10800 1 -03}
+ {2485396800 -10800 1 -04}
{2500513200 -14400 0 -04}
- {2516846400 -10800 1 -03}
+ {2516846400 -10800 1 -04}
{2531962800 -14400 0 -04}
- {2548296000 -10800 1 -03}
+ {2548296000 -10800 1 -04}
{2563412400 -14400 0 -04}
- {2579745600 -10800 1 -03}
+ {2579745600 -10800 1 -04}
{2594862000 -14400 0 -04}
- {2611800000 -10800 1 -03}
+ {2611800000 -10800 1 -04}
{2626311600 -14400 0 -04}
- {2643249600 -10800 1 -03}
+ {2643249600 -10800 1 -04}
{2657761200 -14400 0 -04}
- {2674699200 -10800 1 -03}
+ {2674699200 -10800 1 -04}
{2689815600 -14400 0 -04}
- {2706148800 -10800 1 -03}
+ {2706148800 -10800 1 -04}
{2721265200 -14400 0 -04}
- {2737598400 -10800 1 -03}
+ {2737598400 -10800 1 -04}
{2752714800 -14400 0 -04}
- {2769652800 -10800 1 -03}
+ {2769652800 -10800 1 -04}
{2784164400 -14400 0 -04}
- {2801102400 -10800 1 -03}
+ {2801102400 -10800 1 -04}
{2815614000 -14400 0 -04}
- {2832552000 -10800 1 -03}
+ {2832552000 -10800 1 -04}
{2847668400 -14400 0 -04}
- {2864001600 -10800 1 -03}
+ {2864001600 -10800 1 -04}
{2879118000 -14400 0 -04}
- {2895451200 -10800 1 -03}
+ {2895451200 -10800 1 -04}
{2910567600 -14400 0 -04}
- {2926900800 -10800 1 -03}
+ {2926900800 -10800 1 -04}
{2942017200 -14400 0 -04}
- {2958955200 -10800 1 -03}
+ {2958955200 -10800 1 -04}
{2973466800 -14400 0 -04}
- {2990404800 -10800 1 -03}
+ {2990404800 -10800 1 -04}
{3004916400 -14400 0 -04}
- {3021854400 -10800 1 -03}
+ {3021854400 -10800 1 -04}
{3036970800 -14400 0 -04}
- {3053304000 -10800 1 -03}
+ {3053304000 -10800 1 -04}
{3068420400 -14400 0 -04}
- {3084753600 -10800 1 -03}
+ {3084753600 -10800 1 -04}
{3099870000 -14400 0 -04}
- {3116808000 -10800 1 -03}
+ {3116808000 -10800 1 -04}
{3131319600 -14400 0 -04}
- {3148257600 -10800 1 -03}
+ {3148257600 -10800 1 -04}
{3162769200 -14400 0 -04}
- {3179707200 -10800 1 -03}
+ {3179707200 -10800 1 -04}
{3194218800 -14400 0 -04}
- {3211156800 -10800 1 -03}
+ {3211156800 -10800 1 -04}
{3226273200 -14400 0 -04}
- {3242606400 -10800 1 -03}
+ {3242606400 -10800 1 -04}
{3257722800 -14400 0 -04}
- {3274056000 -10800 1 -03}
+ {3274056000 -10800 1 -04}
{3289172400 -14400 0 -04}
- {3306110400 -10800 1 -03}
+ {3306110400 -10800 1 -04}
{3320622000 -14400 0 -04}
- {3337560000 -10800 1 -03}
+ {3337560000 -10800 1 -04}
{3352071600 -14400 0 -04}
- {3369009600 -10800 1 -03}
+ {3369009600 -10800 1 -04}
{3384126000 -14400 0 -04}
- {3400459200 -10800 1 -03}
+ {3400459200 -10800 1 -04}
{3415575600 -14400 0 -04}
- {3431908800 -10800 1 -03}
+ {3431908800 -10800 1 -04}
{3447025200 -14400 0 -04}
- {3463358400 -10800 1 -03}
+ {3463358400 -10800 1 -04}
{3478474800 -14400 0 -04}
- {3495412800 -10800 1 -03}
+ {3495412800 -10800 1 -04}
{3509924400 -14400 0 -04}
- {3526862400 -10800 1 -03}
+ {3526862400 -10800 1 -04}
{3541374000 -14400 0 -04}
- {3558312000 -10800 1 -03}
+ {3558312000 -10800 1 -04}
{3573428400 -14400 0 -04}
- {3589761600 -10800 1 -03}
+ {3589761600 -10800 1 -04}
{3604878000 -14400 0 -04}
- {3621211200 -10800 1 -03}
+ {3621211200 -10800 1 -04}
{3636327600 -14400 0 -04}
- {3653265600 -10800 1 -03}
+ {3653265600 -10800 1 -04}
{3667777200 -14400 0 -04}
- {3684715200 -10800 1 -03}
+ {3684715200 -10800 1 -04}
{3699226800 -14400 0 -04}
- {3716164800 -10800 1 -03}
+ {3716164800 -10800 1 -04}
{3731281200 -14400 0 -04}
- {3747614400 -10800 1 -03}
+ {3747614400 -10800 1 -04}
{3762730800 -14400 0 -04}
- {3779064000 -10800 1 -03}
+ {3779064000 -10800 1 -04}
{3794180400 -14400 0 -04}
- {3810513600 -10800 1 -03}
+ {3810513600 -10800 1 -04}
{3825630000 -14400 0 -04}
- {3842568000 -10800 1 -03}
+ {3842568000 -10800 1 -04}
{3857079600 -14400 0 -04}
- {3874017600 -10800 1 -03}
+ {3874017600 -10800 1 -04}
{3888529200 -14400 0 -04}
- {3905467200 -10800 1 -03}
+ {3905467200 -10800 1 -04}
{3920583600 -14400 0 -04}
- {3936916800 -10800 1 -03}
+ {3936916800 -10800 1 -04}
{3952033200 -14400 0 -04}
- {3968366400 -10800 1 -03}
+ {3968366400 -10800 1 -04}
{3983482800 -14400 0 -04}
- {4000420800 -10800 1 -03}
+ {4000420800 -10800 1 -04}
{4014932400 -14400 0 -04}
- {4031870400 -10800 1 -03}
+ {4031870400 -10800 1 -04}
{4046382000 -14400 0 -04}
- {4063320000 -10800 1 -03}
+ {4063320000 -10800 1 -04}
{4077831600 -14400 0 -04}
- {4094769600 -10800 1 -03}
+ {4094769600 -10800 1 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Bahia b/tcl8.6/library/tzdata/America/Bahia
index 7dbcb90..7aaf834 100644
--- a/tcl8.6/library/tzdata/America/Bahia
+++ b/tcl8.6/library/tzdata/America/Bahia
@@ -3,66 +3,66 @@
set TZData(:America/Bahia) {
{-9223372036854775808 -9244 0 LMT}
{-1767216356 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{666756000 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{697600800 -10800 0 -03}
- {719982000 -7200 1 -02}
+ {719982000 -7200 1 -03}
{728445600 -10800 0 -03}
- {750826800 -7200 1 -02}
+ {750826800 -7200 1 -03}
{761709600 -10800 0 -03}
- {782276400 -7200 1 -02}
+ {782276400 -7200 1 -03}
{793159200 -10800 0 -03}
- {813726000 -7200 1 -02}
+ {813726000 -7200 1 -03}
{824004000 -10800 0 -03}
- {844570800 -7200 1 -02}
+ {844570800 -7200 1 -03}
{856058400 -10800 0 -03}
- {876106800 -7200 1 -02}
+ {876106800 -7200 1 -03}
{888717600 -10800 0 -03}
- {908074800 -7200 1 -02}
+ {908074800 -7200 1 -03}
{919562400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{982461600 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
- {1036292400 -7200 1 -02}
+ {1036292400 -7200 1 -03}
{1045360800 -10800 0 -03}
{1064368800 -10800 0 -03}
- {1318734000 -7200 0 -02}
+ {1318734000 -7200 0 -03}
{1330221600 -10800 0 -03}
{1350784800 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Belem b/tcl8.6/library/tzdata/America/Belem
index b2bf3a6..42a3ec5 100644
--- a/tcl8.6/library/tzdata/America/Belem
+++ b/tcl8.6/library/tzdata/America/Belem
@@ -3,33 +3,33 @@
set TZData(:America/Belem) {
{-9223372036854775808 -11636 0 LMT}
{-1767213964 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
{590032800 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Boa_Vista b/tcl8.6/library/tzdata/America/Boa_Vista
index 982249b..0af989e 100644
--- a/tcl8.6/library/tzdata/America/Boa_Vista
+++ b/tcl8.6/library/tzdata/America/Boa_Vista
@@ -3,38 +3,38 @@
set TZData(:America/Boa_Vista) {
{-9223372036854775808 -14560 0 LMT}
{-1767211040 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
{590036400 -14400 0 -04}
{938664000 -14400 0 -04}
- {938923200 -10800 1 -03}
+ {938923200 -10800 1 -04}
{951620400 -14400 0 -04}
- {970977600 -10800 1 -03}
+ {970977600 -10800 1 -04}
{971578800 -14400 0 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Bogota b/tcl8.6/library/tzdata/America/Bogota
index 69e4557..8ca39ba 100644
--- a/tcl8.6/library/tzdata/America/Bogota
+++ b/tcl8.6/library/tzdata/America/Bogota
@@ -4,6 +4,6 @@ set TZData(:America/Bogota) {
{-9223372036854775808 -17776 0 LMT}
{-2707671824 -17776 0 BMT}
{-1739041424 -18000 0 -05}
- {704869200 -14400 1 -04}
+ {704869200 -14400 1 -05}
{733896000 -18000 0 -05}
}
diff --git a/tcl8.6/library/tzdata/America/Campo_Grande b/tcl8.6/library/tzdata/America/Campo_Grande
index 77cb4d1..5ec7112 100644
--- a/tcl8.6/library/tzdata/America/Campo_Grande
+++ b/tcl8.6/library/tzdata/America/Campo_Grande
@@ -3,255 +3,255 @@
set TZData(:America/Campo_Grande) {
{-9223372036854775808 -13108 0 LMT}
{-1767212492 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
- {592977600 -10800 1 -03}
+ {592977600 -10800 1 -04}
{602046000 -14400 0 -04}
- {624427200 -10800 1 -03}
+ {624427200 -10800 1 -04}
{634705200 -14400 0 -04}
- {656481600 -10800 1 -03}
+ {656481600 -10800 1 -04}
{666759600 -14400 0 -04}
- {687931200 -10800 1 -03}
+ {687931200 -10800 1 -04}
{697604400 -14400 0 -04}
- {719985600 -10800 1 -03}
+ {719985600 -10800 1 -04}
{728449200 -14400 0 -04}
- {750830400 -10800 1 -03}
+ {750830400 -10800 1 -04}
{761713200 -14400 0 -04}
- {782280000 -10800 1 -03}
+ {782280000 -10800 1 -04}
{793162800 -14400 0 -04}
- {813729600 -10800 1 -03}
+ {813729600 -10800 1 -04}
{824007600 -14400 0 -04}
- {844574400 -10800 1 -03}
+ {844574400 -10800 1 -04}
{856062000 -14400 0 -04}
- {876110400 -10800 1 -03}
+ {876110400 -10800 1 -04}
{888721200 -14400 0 -04}
- {908078400 -10800 1 -03}
+ {908078400 -10800 1 -04}
{919566000 -14400 0 -04}
- {938923200 -10800 1 -03}
+ {938923200 -10800 1 -04}
{951620400 -14400 0 -04}
- {970977600 -10800 1 -03}
+ {970977600 -10800 1 -04}
{982465200 -14400 0 -04}
- {1003032000 -10800 1 -03}
+ {1003032000 -10800 1 -04}
{1013914800 -14400 0 -04}
- {1036296000 -10800 1 -03}
+ {1036296000 -10800 1 -04}
{1045364400 -14400 0 -04}
- {1066536000 -10800 1 -03}
+ {1066536000 -10800 1 -04}
{1076814000 -14400 0 -04}
- {1099368000 -10800 1 -03}
+ {1099368000 -10800 1 -04}
{1108868400 -14400 0 -04}
- {1129435200 -10800 1 -03}
+ {1129435200 -10800 1 -04}
{1140318000 -14400 0 -04}
- {1162699200 -10800 1 -03}
+ {1162699200 -10800 1 -04}
{1172372400 -14400 0 -04}
- {1192334400 -10800 1 -03}
+ {1192334400 -10800 1 -04}
{1203217200 -14400 0 -04}
- {1224388800 -10800 1 -03}
+ {1224388800 -10800 1 -04}
{1234666800 -14400 0 -04}
- {1255838400 -10800 1 -03}
+ {1255838400 -10800 1 -04}
{1266721200 -14400 0 -04}
- {1287288000 -10800 1 -03}
+ {1287288000 -10800 1 -04}
{1298170800 -14400 0 -04}
- {1318737600 -10800 1 -03}
+ {1318737600 -10800 1 -04}
{1330225200 -14400 0 -04}
- {1350792000 -10800 1 -03}
+ {1350792000 -10800 1 -04}
{1361070000 -14400 0 -04}
- {1382241600 -10800 1 -03}
+ {1382241600 -10800 1 -04}
{1392519600 -14400 0 -04}
- {1413691200 -10800 1 -03}
+ {1413691200 -10800 1 -04}
{1424574000 -14400 0 -04}
- {1445140800 -10800 1 -03}
+ {1445140800 -10800 1 -04}
{1456023600 -14400 0 -04}
- {1476590400 -10800 1 -03}
+ {1476590400 -10800 1 -04}
{1487473200 -14400 0 -04}
- {1508040000 -10800 1 -03}
+ {1508040000 -10800 1 -04}
{1518922800 -14400 0 -04}
- {1540094400 -10800 1 -03}
+ {1541304000 -10800 1 -04}
{1550372400 -14400 0 -04}
- {1571544000 -10800 1 -03}
+ {1572753600 -10800 1 -04}
{1581822000 -14400 0 -04}
- {1602993600 -10800 1 -03}
+ {1604203200 -10800 1 -04}
{1613876400 -14400 0 -04}
- {1634443200 -10800 1 -03}
+ {1636257600 -10800 1 -04}
{1645326000 -14400 0 -04}
- {1665892800 -10800 1 -03}
+ {1667707200 -10800 1 -04}
{1677380400 -14400 0 -04}
- {1697342400 -10800 1 -03}
+ {1699156800 -10800 1 -04}
{1708225200 -14400 0 -04}
- {1729396800 -10800 1 -03}
+ {1730606400 -10800 1 -04}
{1739674800 -14400 0 -04}
- {1760846400 -10800 1 -03}
+ {1762056000 -10800 1 -04}
{1771729200 -14400 0 -04}
- {1792296000 -10800 1 -03}
+ {1793505600 -10800 1 -04}
{1803178800 -14400 0 -04}
- {1823745600 -10800 1 -03}
+ {1825560000 -10800 1 -04}
{1834628400 -14400 0 -04}
- {1855195200 -10800 1 -03}
+ {1857009600 -10800 1 -04}
{1866078000 -14400 0 -04}
- {1887249600 -10800 1 -03}
+ {1888459200 -10800 1 -04}
{1897527600 -14400 0 -04}
- {1918699200 -10800 1 -03}
+ {1919908800 -10800 1 -04}
{1928977200 -14400 0 -04}
- {1950148800 -10800 1 -03}
+ {1951358400 -10800 1 -04}
{1960426800 -14400 0 -04}
- {1981598400 -10800 1 -03}
+ {1983412800 -10800 1 -04}
{1992481200 -14400 0 -04}
- {2013048000 -10800 1 -03}
+ {2014862400 -10800 1 -04}
{2024535600 -14400 0 -04}
- {2044497600 -10800 1 -03}
+ {2046312000 -10800 1 -04}
{2055380400 -14400 0 -04}
- {2076552000 -10800 1 -03}
+ {2077761600 -10800 1 -04}
{2086830000 -14400 0 -04}
- {2108001600 -10800 1 -03}
+ {2109211200 -10800 1 -04}
{2118884400 -14400 0 -04}
- {2139451200 -10800 1 -03}
+ {2140660800 -10800 1 -04}
{2150334000 -14400 0 -04}
- {2170900800 -10800 1 -03}
+ {2172715200 -10800 1 -04}
{2181783600 -14400 0 -04}
- {2202350400 -10800 1 -03}
+ {2204164800 -10800 1 -04}
{2213233200 -14400 0 -04}
- {2234404800 -10800 1 -03}
+ {2235614400 -10800 1 -04}
{2244682800 -14400 0 -04}
- {2265854400 -10800 1 -03}
+ {2267064000 -10800 1 -04}
{2276132400 -14400 0 -04}
- {2297304000 -10800 1 -03}
+ {2298513600 -10800 1 -04}
{2307582000 -14400 0 -04}
- {2328753600 -10800 1 -03}
+ {2329963200 -10800 1 -04}
{2339636400 -14400 0 -04}
- {2360203200 -10800 1 -03}
+ {2362017600 -10800 1 -04}
{2371086000 -14400 0 -04}
- {2391652800 -10800 1 -03}
+ {2393467200 -10800 1 -04}
{2402535600 -14400 0 -04}
- {2423707200 -10800 1 -03}
+ {2424916800 -10800 1 -04}
{2433985200 -14400 0 -04}
- {2455156800 -10800 1 -03}
+ {2456366400 -10800 1 -04}
{2465434800 -14400 0 -04}
- {2486606400 -10800 1 -03}
+ {2487816000 -10800 1 -04}
{2497489200 -14400 0 -04}
- {2518056000 -10800 1 -03}
+ {2519870400 -10800 1 -04}
{2528938800 -14400 0 -04}
- {2549505600 -10800 1 -03}
+ {2551320000 -10800 1 -04}
{2560388400 -14400 0 -04}
- {2580955200 -10800 1 -03}
+ {2582769600 -10800 1 -04}
{2591838000 -14400 0 -04}
- {2613009600 -10800 1 -03}
+ {2614219200 -10800 1 -04}
{2623287600 -14400 0 -04}
- {2644459200 -10800 1 -03}
+ {2645668800 -10800 1 -04}
{2654737200 -14400 0 -04}
- {2675908800 -10800 1 -03}
+ {2677118400 -10800 1 -04}
{2686791600 -14400 0 -04}
- {2707358400 -10800 1 -03}
+ {2709172800 -10800 1 -04}
{2718241200 -14400 0 -04}
- {2738808000 -10800 1 -03}
+ {2740622400 -10800 1 -04}
{2749690800 -14400 0 -04}
- {2770862400 -10800 1 -03}
+ {2772072000 -10800 1 -04}
{2781140400 -14400 0 -04}
- {2802312000 -10800 1 -03}
+ {2803521600 -10800 1 -04}
{2812590000 -14400 0 -04}
- {2833761600 -10800 1 -03}
+ {2834971200 -10800 1 -04}
{2844039600 -14400 0 -04}
- {2865211200 -10800 1 -03}
+ {2867025600 -10800 1 -04}
{2876094000 -14400 0 -04}
- {2896660800 -10800 1 -03}
+ {2898475200 -10800 1 -04}
{2907543600 -14400 0 -04}
- {2928110400 -10800 1 -03}
+ {2929924800 -10800 1 -04}
{2938993200 -14400 0 -04}
- {2960164800 -10800 1 -03}
+ {2961374400 -10800 1 -04}
{2970442800 -14400 0 -04}
- {2991614400 -10800 1 -03}
+ {2992824000 -10800 1 -04}
{3001892400 -14400 0 -04}
- {3023064000 -10800 1 -03}
+ {3024273600 -10800 1 -04}
{3033946800 -14400 0 -04}
- {3054513600 -10800 1 -03}
+ {3056328000 -10800 1 -04}
{3065396400 -14400 0 -04}
- {3085963200 -10800 1 -03}
+ {3087777600 -10800 1 -04}
{3096846000 -14400 0 -04}
- {3118017600 -10800 1 -03}
+ {3119227200 -10800 1 -04}
{3128295600 -14400 0 -04}
- {3149467200 -10800 1 -03}
+ {3150676800 -10800 1 -04}
{3159745200 -14400 0 -04}
- {3180916800 -10800 1 -03}
+ {3182126400 -10800 1 -04}
{3191194800 -14400 0 -04}
- {3212366400 -10800 1 -03}
+ {3213576000 -10800 1 -04}
{3223249200 -14400 0 -04}
- {3243816000 -10800 1 -03}
+ {3245630400 -10800 1 -04}
{3254698800 -14400 0 -04}
- {3275265600 -10800 1 -03}
+ {3277080000 -10800 1 -04}
{3286148400 -14400 0 -04}
- {3307320000 -10800 1 -03}
+ {3308529600 -10800 1 -04}
{3317598000 -14400 0 -04}
- {3338769600 -10800 1 -03}
+ {3339979200 -10800 1 -04}
{3349047600 -14400 0 -04}
- {3370219200 -10800 1 -03}
+ {3371428800 -10800 1 -04}
{3381102000 -14400 0 -04}
- {3401668800 -10800 1 -03}
+ {3403483200 -10800 1 -04}
{3412551600 -14400 0 -04}
- {3433118400 -10800 1 -03}
+ {3434932800 -10800 1 -04}
{3444001200 -14400 0 -04}
- {3464568000 -10800 1 -03}
+ {3466382400 -10800 1 -04}
{3475450800 -14400 0 -04}
- {3496622400 -10800 1 -03}
+ {3497832000 -10800 1 -04}
{3506900400 -14400 0 -04}
- {3528072000 -10800 1 -03}
+ {3529281600 -10800 1 -04}
{3538350000 -14400 0 -04}
- {3559521600 -10800 1 -03}
+ {3560731200 -10800 1 -04}
{3570404400 -14400 0 -04}
- {3590971200 -10800 1 -03}
+ {3592785600 -10800 1 -04}
{3601854000 -14400 0 -04}
- {3622420800 -10800 1 -03}
+ {3624235200 -10800 1 -04}
{3633303600 -14400 0 -04}
- {3654475200 -10800 1 -03}
+ {3655684800 -10800 1 -04}
{3664753200 -14400 0 -04}
- {3685924800 -10800 1 -03}
+ {3687134400 -10800 1 -04}
{3696202800 -14400 0 -04}
- {3717374400 -10800 1 -03}
+ {3718584000 -10800 1 -04}
{3727652400 -14400 0 -04}
- {3748824000 -10800 1 -03}
+ {3750638400 -10800 1 -04}
{3759706800 -14400 0 -04}
- {3780273600 -10800 1 -03}
+ {3782088000 -10800 1 -04}
{3791156400 -14400 0 -04}
- {3811723200 -10800 1 -03}
+ {3813537600 -10800 1 -04}
{3822606000 -14400 0 -04}
- {3843777600 -10800 1 -03}
+ {3844987200 -10800 1 -04}
{3854055600 -14400 0 -04}
- {3875227200 -10800 1 -03}
+ {3876436800 -10800 1 -04}
{3885505200 -14400 0 -04}
- {3906676800 -10800 1 -03}
+ {3907886400 -10800 1 -04}
{3917559600 -14400 0 -04}
- {3938126400 -10800 1 -03}
+ {3939940800 -10800 1 -04}
{3949009200 -14400 0 -04}
- {3969576000 -10800 1 -03}
+ {3971390400 -10800 1 -04}
{3980458800 -14400 0 -04}
- {4001630400 -10800 1 -03}
+ {4002840000 -10800 1 -04}
{4011908400 -14400 0 -04}
- {4033080000 -10800 1 -03}
+ {4034289600 -10800 1 -04}
{4043358000 -14400 0 -04}
- {4064529600 -10800 1 -03}
+ {4065739200 -10800 1 -04}
{4074807600 -14400 0 -04}
- {4095979200 -10800 1 -03}
+ {4097188800 -10800 1 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Cuiaba b/tcl8.6/library/tzdata/America/Cuiaba
index 57cd38c..09f5b1f 100644
--- a/tcl8.6/library/tzdata/America/Cuiaba
+++ b/tcl8.6/library/tzdata/America/Cuiaba
@@ -3,255 +3,255 @@
set TZData(:America/Cuiaba) {
{-9223372036854775808 -13460 0 LMT}
{-1767212140 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
- {592977600 -10800 1 -03}
+ {592977600 -10800 1 -04}
{602046000 -14400 0 -04}
- {624427200 -10800 1 -03}
+ {624427200 -10800 1 -04}
{634705200 -14400 0 -04}
- {656481600 -10800 1 -03}
+ {656481600 -10800 1 -04}
{666759600 -14400 0 -04}
- {687931200 -10800 1 -03}
+ {687931200 -10800 1 -04}
{697604400 -14400 0 -04}
- {719985600 -10800 1 -03}
+ {719985600 -10800 1 -04}
{728449200 -14400 0 -04}
- {750830400 -10800 1 -03}
+ {750830400 -10800 1 -04}
{761713200 -14400 0 -04}
- {782280000 -10800 1 -03}
+ {782280000 -10800 1 -04}
{793162800 -14400 0 -04}
- {813729600 -10800 1 -03}
+ {813729600 -10800 1 -04}
{824007600 -14400 0 -04}
- {844574400 -10800 1 -03}
+ {844574400 -10800 1 -04}
{856062000 -14400 0 -04}
- {876110400 -10800 1 -03}
+ {876110400 -10800 1 -04}
{888721200 -14400 0 -04}
- {908078400 -10800 1 -03}
+ {908078400 -10800 1 -04}
{919566000 -14400 0 -04}
- {938923200 -10800 1 -03}
+ {938923200 -10800 1 -04}
{951620400 -14400 0 -04}
- {970977600 -10800 1 -03}
+ {970977600 -10800 1 -04}
{982465200 -14400 0 -04}
- {1003032000 -10800 1 -03}
+ {1003032000 -10800 1 -04}
{1013914800 -14400 0 -04}
- {1036296000 -10800 1 -03}
+ {1036296000 -10800 1 -04}
{1045364400 -14400 0 -04}
{1064372400 -14400 0 -04}
{1096603200 -14400 0 -04}
- {1099368000 -10800 1 -03}
+ {1099368000 -10800 1 -04}
{1108868400 -14400 0 -04}
- {1129435200 -10800 1 -03}
+ {1129435200 -10800 1 -04}
{1140318000 -14400 0 -04}
- {1162699200 -10800 1 -03}
+ {1162699200 -10800 1 -04}
{1172372400 -14400 0 -04}
- {1192334400 -10800 1 -03}
+ {1192334400 -10800 1 -04}
{1203217200 -14400 0 -04}
- {1224388800 -10800 1 -03}
+ {1224388800 -10800 1 -04}
{1234666800 -14400 0 -04}
- {1255838400 -10800 1 -03}
+ {1255838400 -10800 1 -04}
{1266721200 -14400 0 -04}
- {1287288000 -10800 1 -03}
+ {1287288000 -10800 1 -04}
{1298170800 -14400 0 -04}
- {1318737600 -10800 1 -03}
+ {1318737600 -10800 1 -04}
{1330225200 -14400 0 -04}
- {1350792000 -10800 1 -03}
+ {1350792000 -10800 1 -04}
{1361070000 -14400 0 -04}
- {1382241600 -10800 1 -03}
+ {1382241600 -10800 1 -04}
{1392519600 -14400 0 -04}
- {1413691200 -10800 1 -03}
+ {1413691200 -10800 1 -04}
{1424574000 -14400 0 -04}
- {1445140800 -10800 1 -03}
+ {1445140800 -10800 1 -04}
{1456023600 -14400 0 -04}
- {1476590400 -10800 1 -03}
+ {1476590400 -10800 1 -04}
{1487473200 -14400 0 -04}
- {1508040000 -10800 1 -03}
+ {1508040000 -10800 1 -04}
{1518922800 -14400 0 -04}
- {1540094400 -10800 1 -03}
+ {1541304000 -10800 1 -04}
{1550372400 -14400 0 -04}
- {1571544000 -10800 1 -03}
+ {1572753600 -10800 1 -04}
{1581822000 -14400 0 -04}
- {1602993600 -10800 1 -03}
+ {1604203200 -10800 1 -04}
{1613876400 -14400 0 -04}
- {1634443200 -10800 1 -03}
+ {1636257600 -10800 1 -04}
{1645326000 -14400 0 -04}
- {1665892800 -10800 1 -03}
+ {1667707200 -10800 1 -04}
{1677380400 -14400 0 -04}
- {1697342400 -10800 1 -03}
+ {1699156800 -10800 1 -04}
{1708225200 -14400 0 -04}
- {1729396800 -10800 1 -03}
+ {1730606400 -10800 1 -04}
{1739674800 -14400 0 -04}
- {1760846400 -10800 1 -03}
+ {1762056000 -10800 1 -04}
{1771729200 -14400 0 -04}
- {1792296000 -10800 1 -03}
+ {1793505600 -10800 1 -04}
{1803178800 -14400 0 -04}
- {1823745600 -10800 1 -03}
+ {1825560000 -10800 1 -04}
{1834628400 -14400 0 -04}
- {1855195200 -10800 1 -03}
+ {1857009600 -10800 1 -04}
{1866078000 -14400 0 -04}
- {1887249600 -10800 1 -03}
+ {1888459200 -10800 1 -04}
{1897527600 -14400 0 -04}
- {1918699200 -10800 1 -03}
+ {1919908800 -10800 1 -04}
{1928977200 -14400 0 -04}
- {1950148800 -10800 1 -03}
+ {1951358400 -10800 1 -04}
{1960426800 -14400 0 -04}
- {1981598400 -10800 1 -03}
+ {1983412800 -10800 1 -04}
{1992481200 -14400 0 -04}
- {2013048000 -10800 1 -03}
+ {2014862400 -10800 1 -04}
{2024535600 -14400 0 -04}
- {2044497600 -10800 1 -03}
+ {2046312000 -10800 1 -04}
{2055380400 -14400 0 -04}
- {2076552000 -10800 1 -03}
+ {2077761600 -10800 1 -04}
{2086830000 -14400 0 -04}
- {2108001600 -10800 1 -03}
+ {2109211200 -10800 1 -04}
{2118884400 -14400 0 -04}
- {2139451200 -10800 1 -03}
+ {2140660800 -10800 1 -04}
{2150334000 -14400 0 -04}
- {2170900800 -10800 1 -03}
+ {2172715200 -10800 1 -04}
{2181783600 -14400 0 -04}
- {2202350400 -10800 1 -03}
+ {2204164800 -10800 1 -04}
{2213233200 -14400 0 -04}
- {2234404800 -10800 1 -03}
+ {2235614400 -10800 1 -04}
{2244682800 -14400 0 -04}
- {2265854400 -10800 1 -03}
+ {2267064000 -10800 1 -04}
{2276132400 -14400 0 -04}
- {2297304000 -10800 1 -03}
+ {2298513600 -10800 1 -04}
{2307582000 -14400 0 -04}
- {2328753600 -10800 1 -03}
+ {2329963200 -10800 1 -04}
{2339636400 -14400 0 -04}
- {2360203200 -10800 1 -03}
+ {2362017600 -10800 1 -04}
{2371086000 -14400 0 -04}
- {2391652800 -10800 1 -03}
+ {2393467200 -10800 1 -04}
{2402535600 -14400 0 -04}
- {2423707200 -10800 1 -03}
+ {2424916800 -10800 1 -04}
{2433985200 -14400 0 -04}
- {2455156800 -10800 1 -03}
+ {2456366400 -10800 1 -04}
{2465434800 -14400 0 -04}
- {2486606400 -10800 1 -03}
+ {2487816000 -10800 1 -04}
{2497489200 -14400 0 -04}
- {2518056000 -10800 1 -03}
+ {2519870400 -10800 1 -04}
{2528938800 -14400 0 -04}
- {2549505600 -10800 1 -03}
+ {2551320000 -10800 1 -04}
{2560388400 -14400 0 -04}
- {2580955200 -10800 1 -03}
+ {2582769600 -10800 1 -04}
{2591838000 -14400 0 -04}
- {2613009600 -10800 1 -03}
+ {2614219200 -10800 1 -04}
{2623287600 -14400 0 -04}
- {2644459200 -10800 1 -03}
+ {2645668800 -10800 1 -04}
{2654737200 -14400 0 -04}
- {2675908800 -10800 1 -03}
+ {2677118400 -10800 1 -04}
{2686791600 -14400 0 -04}
- {2707358400 -10800 1 -03}
+ {2709172800 -10800 1 -04}
{2718241200 -14400 0 -04}
- {2738808000 -10800 1 -03}
+ {2740622400 -10800 1 -04}
{2749690800 -14400 0 -04}
- {2770862400 -10800 1 -03}
+ {2772072000 -10800 1 -04}
{2781140400 -14400 0 -04}
- {2802312000 -10800 1 -03}
+ {2803521600 -10800 1 -04}
{2812590000 -14400 0 -04}
- {2833761600 -10800 1 -03}
+ {2834971200 -10800 1 -04}
{2844039600 -14400 0 -04}
- {2865211200 -10800 1 -03}
+ {2867025600 -10800 1 -04}
{2876094000 -14400 0 -04}
- {2896660800 -10800 1 -03}
+ {2898475200 -10800 1 -04}
{2907543600 -14400 0 -04}
- {2928110400 -10800 1 -03}
+ {2929924800 -10800 1 -04}
{2938993200 -14400 0 -04}
- {2960164800 -10800 1 -03}
+ {2961374400 -10800 1 -04}
{2970442800 -14400 0 -04}
- {2991614400 -10800 1 -03}
+ {2992824000 -10800 1 -04}
{3001892400 -14400 0 -04}
- {3023064000 -10800 1 -03}
+ {3024273600 -10800 1 -04}
{3033946800 -14400 0 -04}
- {3054513600 -10800 1 -03}
+ {3056328000 -10800 1 -04}
{3065396400 -14400 0 -04}
- {3085963200 -10800 1 -03}
+ {3087777600 -10800 1 -04}
{3096846000 -14400 0 -04}
- {3118017600 -10800 1 -03}
+ {3119227200 -10800 1 -04}
{3128295600 -14400 0 -04}
- {3149467200 -10800 1 -03}
+ {3150676800 -10800 1 -04}
{3159745200 -14400 0 -04}
- {3180916800 -10800 1 -03}
+ {3182126400 -10800 1 -04}
{3191194800 -14400 0 -04}
- {3212366400 -10800 1 -03}
+ {3213576000 -10800 1 -04}
{3223249200 -14400 0 -04}
- {3243816000 -10800 1 -03}
+ {3245630400 -10800 1 -04}
{3254698800 -14400 0 -04}
- {3275265600 -10800 1 -03}
+ {3277080000 -10800 1 -04}
{3286148400 -14400 0 -04}
- {3307320000 -10800 1 -03}
+ {3308529600 -10800 1 -04}
{3317598000 -14400 0 -04}
- {3338769600 -10800 1 -03}
+ {3339979200 -10800 1 -04}
{3349047600 -14400 0 -04}
- {3370219200 -10800 1 -03}
+ {3371428800 -10800 1 -04}
{3381102000 -14400 0 -04}
- {3401668800 -10800 1 -03}
+ {3403483200 -10800 1 -04}
{3412551600 -14400 0 -04}
- {3433118400 -10800 1 -03}
+ {3434932800 -10800 1 -04}
{3444001200 -14400 0 -04}
- {3464568000 -10800 1 -03}
+ {3466382400 -10800 1 -04}
{3475450800 -14400 0 -04}
- {3496622400 -10800 1 -03}
+ {3497832000 -10800 1 -04}
{3506900400 -14400 0 -04}
- {3528072000 -10800 1 -03}
+ {3529281600 -10800 1 -04}
{3538350000 -14400 0 -04}
- {3559521600 -10800 1 -03}
+ {3560731200 -10800 1 -04}
{3570404400 -14400 0 -04}
- {3590971200 -10800 1 -03}
+ {3592785600 -10800 1 -04}
{3601854000 -14400 0 -04}
- {3622420800 -10800 1 -03}
+ {3624235200 -10800 1 -04}
{3633303600 -14400 0 -04}
- {3654475200 -10800 1 -03}
+ {3655684800 -10800 1 -04}
{3664753200 -14400 0 -04}
- {3685924800 -10800 1 -03}
+ {3687134400 -10800 1 -04}
{3696202800 -14400 0 -04}
- {3717374400 -10800 1 -03}
+ {3718584000 -10800 1 -04}
{3727652400 -14400 0 -04}
- {3748824000 -10800 1 -03}
+ {3750638400 -10800 1 -04}
{3759706800 -14400 0 -04}
- {3780273600 -10800 1 -03}
+ {3782088000 -10800 1 -04}
{3791156400 -14400 0 -04}
- {3811723200 -10800 1 -03}
+ {3813537600 -10800 1 -04}
{3822606000 -14400 0 -04}
- {3843777600 -10800 1 -03}
+ {3844987200 -10800 1 -04}
{3854055600 -14400 0 -04}
- {3875227200 -10800 1 -03}
+ {3876436800 -10800 1 -04}
{3885505200 -14400 0 -04}
- {3906676800 -10800 1 -03}
+ {3907886400 -10800 1 -04}
{3917559600 -14400 0 -04}
- {3938126400 -10800 1 -03}
+ {3939940800 -10800 1 -04}
{3949009200 -14400 0 -04}
- {3969576000 -10800 1 -03}
+ {3971390400 -10800 1 -04}
{3980458800 -14400 0 -04}
- {4001630400 -10800 1 -03}
+ {4002840000 -10800 1 -04}
{4011908400 -14400 0 -04}
- {4033080000 -10800 1 -03}
+ {4034289600 -10800 1 -04}
{4043358000 -14400 0 -04}
- {4064529600 -10800 1 -03}
+ {4065739200 -10800 1 -04}
{4074807600 -14400 0 -04}
- {4095979200 -10800 1 -03}
+ {4097188800 -10800 1 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Eirunepe b/tcl8.6/library/tzdata/America/Eirunepe
index 41b4cc9..a81b09e 100644
--- a/tcl8.6/library/tzdata/America/Eirunepe
+++ b/tcl8.6/library/tzdata/America/Eirunepe
@@ -3,37 +3,37 @@
set TZData(:America/Eirunepe) {
{-9223372036854775808 -16768 0 LMT}
{-1767208832 -18000 0 -05}
- {-1206950400 -14400 1 -04}
+ {-1206950400 -14400 1 -05}
{-1191355200 -18000 0 -05}
- {-1175367600 -14400 1 -04}
+ {-1175367600 -14400 1 -05}
{-1159819200 -18000 0 -05}
- {-633812400 -14400 1 -04}
+ {-633812400 -14400 1 -05}
{-622062000 -18000 0 -05}
- {-602276400 -14400 1 -04}
+ {-602276400 -14400 1 -05}
{-591825600 -18000 0 -05}
- {-570740400 -14400 1 -04}
+ {-570740400 -14400 1 -05}
{-560203200 -18000 0 -05}
- {-539118000 -14400 1 -04}
+ {-539118000 -14400 1 -05}
{-531345600 -18000 0 -05}
- {-191358000 -14400 1 -04}
+ {-191358000 -14400 1 -05}
{-184190400 -18000 0 -05}
- {-155156400 -14400 1 -04}
+ {-155156400 -14400 1 -05}
{-150062400 -18000 0 -05}
- {-128890800 -14400 1 -04}
+ {-128890800 -14400 1 -05}
{-121118400 -18000 0 -05}
- {-99946800 -14400 1 -04}
+ {-99946800 -14400 1 -05}
{-89582400 -18000 0 -05}
- {-68410800 -14400 1 -04}
+ {-68410800 -14400 1 -05}
{-57960000 -18000 0 -05}
- {499755600 -14400 1 -04}
+ {499755600 -14400 1 -05}
{511243200 -18000 0 -05}
- {530600400 -14400 1 -04}
+ {530600400 -14400 1 -05}
{540273600 -18000 0 -05}
- {562136400 -14400 1 -04}
+ {562136400 -14400 1 -05}
{571204800 -18000 0 -05}
{590040000 -18000 0 -05}
{749192400 -18000 0 -05}
- {750834000 -14400 1 -04}
+ {750834000 -14400 1 -05}
{761716800 -18000 0 -05}
{780206400 -18000 0 -05}
{1214283600 -14400 0 -04}
diff --git a/tcl8.6/library/tzdata/America/Fortaleza b/tcl8.6/library/tzdata/America/Fortaleza
index 06c7b84..bd806f1 100644
--- a/tcl8.6/library/tzdata/America/Fortaleza
+++ b/tcl8.6/library/tzdata/America/Fortaleza
@@ -3,46 +3,46 @@
set TZData(:America/Fortaleza) {
{-9223372036854775808 -9240 0 LMT}
{-1767216360 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
{653536800 -10800 0 -03}
{938660400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{972180000 -10800 0 -03}
{1000350000 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
{1033437600 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Grand_Turk b/tcl8.6/library/tzdata/America/Grand_Turk
index c963adc..da5f09b 100644
--- a/tcl8.6/library/tzdata/America/Grand_Turk
+++ b/tcl8.6/library/tzdata/America/Grand_Turk
@@ -2,8 +2,8 @@
set TZData(:America/Grand_Turk) {
{-9223372036854775808 -17072 0 LMT}
- {-2524504528 -18431 0 KMT}
- {-1827687169 -18000 0 EST}
+ {-2524504528 -18430 0 KMT}
+ {-1827687170 -18000 0 EST}
{284014800 -18000 0 EST}
{294217200 -14400 1 EDT}
{309938400 -18000 0 EST}
diff --git a/tcl8.6/library/tzdata/America/Guayaquil b/tcl8.6/library/tzdata/America/Guayaquil
index 353eb69..6ba7b93 100644
--- a/tcl8.6/library/tzdata/America/Guayaquil
+++ b/tcl8.6/library/tzdata/America/Guayaquil
@@ -4,6 +4,6 @@ set TZData(:America/Guayaquil) {
{-9223372036854775808 -19160 0 LMT}
{-2524502440 -18840 0 QMT}
{-1230749160 -18000 0 -05}
- {722926800 -14400 1 -04}
+ {722926800 -14400 1 -05}
{728884800 -18000 0 -05}
}
diff --git a/tcl8.6/library/tzdata/America/Jamaica b/tcl8.6/library/tzdata/America/Jamaica
index f752842..0f758bd 100644
--- a/tcl8.6/library/tzdata/America/Jamaica
+++ b/tcl8.6/library/tzdata/America/Jamaica
@@ -1,9 +1,9 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Jamaica) {
- {-9223372036854775808 -18431 0 LMT}
- {-2524503169 -18431 0 KMT}
- {-1827687169 -18000 0 EST}
+ {-9223372036854775808 -18430 0 LMT}
+ {-2524503170 -18430 0 KMT}
+ {-1827687170 -18000 0 EST}
{126248400 -18000 0 EST}
{126687600 -14400 1 EDT}
{152085600 -18000 0 EST}
diff --git a/tcl8.6/library/tzdata/America/La_Paz b/tcl8.6/library/tzdata/America/La_Paz
index a245afd..ea2f711 100644
--- a/tcl8.6/library/tzdata/America/La_Paz
+++ b/tcl8.6/library/tzdata/America/La_Paz
@@ -3,6 +3,6 @@
set TZData(:America/La_Paz) {
{-9223372036854775808 -16356 0 LMT}
{-2524505244 -16356 0 CMT}
- {-1205954844 -12756 1 BOST}
+ {-1205954844 -12756 1 BST}
{-1192307244 -14400 0 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Lima b/tcl8.6/library/tzdata/America/Lima
index b224a64..e8b69d6 100644
--- a/tcl8.6/library/tzdata/America/Lima
+++ b/tcl8.6/library/tzdata/America/Lima
@@ -3,11 +3,11 @@
set TZData(:America/Lima) {
{-9223372036854775808 -18492 0 LMT}
{-2524503108 -18516 0 LMT}
- {-1938538284 -14400 0 -04}
+ {-1938538284 -14400 0 -05}
{-1002052800 -18000 0 -05}
- {-986756400 -14400 1 -04}
+ {-986756400 -14400 1 -05}
{-971035200 -18000 0 -05}
- {-955306800 -14400 1 -04}
+ {-955306800 -14400 1 -05}
{-939585600 -18000 0 -05}
{512712000 -18000 0 -05}
{544248000 -18000 0 -05}
diff --git a/tcl8.6/library/tzdata/America/Maceio b/tcl8.6/library/tzdata/America/Maceio
index e6ed548..eab534e 100644
--- a/tcl8.6/library/tzdata/America/Maceio
+++ b/tcl8.6/library/tzdata/America/Maceio
@@ -3,50 +3,50 @@
set TZData(:America/Maceio) {
{-9223372036854775808 -8572 0 LMT}
{-1767217028 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
{653536800 -10800 0 -03}
{813553200 -10800 0 -03}
- {813726000 -7200 1 -02}
+ {813726000 -7200 1 -03}
{824004000 -10800 0 -03}
{841802400 -10800 0 -03}
{938660400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{972180000 -10800 0 -03}
{1000350000 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
{1033437600 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Manaus b/tcl8.6/library/tzdata/America/Manaus
index f17023c..a855062 100644
--- a/tcl8.6/library/tzdata/America/Manaus
+++ b/tcl8.6/library/tzdata/America/Manaus
@@ -3,37 +3,37 @@
set TZData(:America/Manaus) {
{-9223372036854775808 -14404 0 LMT}
{-1767211196 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
{590036400 -14400 0 -04}
{749188800 -14400 0 -04}
- {750830400 -10800 1 -03}
+ {750830400 -10800 1 -04}
{761713200 -14400 0 -04}
{780202800 -14400 0 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Montevideo b/tcl8.6/library/tzdata/America/Montevideo
index ff85fb3..27fb76e 100644
--- a/tcl8.6/library/tzdata/America/Montevideo
+++ b/tcl8.6/library/tzdata/America/Montevideo
@@ -1,96 +1,96 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:America/Montevideo) {
- {-9223372036854775808 -13484 0 LMT}
- {-2256668116 -13484 0 MMT}
- {-1567455316 -12600 0 -0330}
- {-1459542600 -10800 1 -03}
+ {-9223372036854775808 -13491 0 LMT}
+ {-1942690509 -13491 0 MMT}
+ {-1567455309 -14400 0 -04}
+ {-1459627200 -10800 0 -0330}
{-1443819600 -12600 0 -0330}
- {-1428006600 -10800 1 -03}
+ {-1428006600 -10800 1 -0330}
{-1412283600 -12600 0 -0330}
- {-1396470600 -10800 1 -03}
+ {-1396470600 -10800 1 -0330}
{-1380747600 -12600 0 -0330}
- {-1141590600 -10800 1 -03}
+ {-1141590600 -10800 1 -0330}
{-1128286800 -12600 0 -0330}
- {-1110141000 -10800 1 -03}
+ {-1110141000 -10800 1 -0330}
{-1096837200 -12600 0 -0330}
- {-1078691400 -10800 1 -03}
+ {-1078691400 -10800 1 -0330}
{-1065387600 -12600 0 -0330}
- {-1046637000 -10800 1 -03}
+ {-1047241800 -10800 1 -0330}
{-1033938000 -12600 0 -0330}
- {-1015187400 -10800 1 -03}
+ {-1015187400 -10800 1 -0330}
{-1002488400 -12600 0 -0330}
- {-983737800 -10800 1 -03}
+ {-983737800 -10800 1 -0330}
{-971038800 -12600 0 -0330}
- {-952288200 -10800 1 -03}
+ {-954707400 -10800 1 -0330}
{-938984400 -12600 0 -0330}
- {-920838600 -10800 1 -03}
+ {-920838600 -10800 1 -0330}
{-907534800 -12600 0 -0330}
- {-896819400 -10800 1 -03}
- {-853623000 -10800 0 -03}
- {-853621200 -7200 1 -02}
- {-845848800 -10800 0 -03}
- {-334789200 -7200 1 -02}
- {-319672800 -10800 0 -03}
- {-314226000 -7200 1 -02}
+ {-896819400 -10800 1 -0330}
+ {-853621200 -9000 0 -03}
+ {-845847000 -10800 0 -03}
+ {-334789200 -9000 1 -03}
+ {-319671000 -10800 0 -03}
+ {-315608400 -10800 0 -03}
+ {-314226000 -7200 1 -03}
{-309996000 -10800 0 -03}
- {-149720400 -7200 1 -02}
+ {-149720400 -7200 1 -03}
{-134604000 -10800 0 -03}
- {-118270800 -7200 1 -02}
- {-100044000 -10800 0 -03}
- {-86821200 -7200 1 -02}
- {-68508000 -10800 0 -03}
{-63147600 -10800 0 -03}
- {-50446800 -9000 1 -0230}
- {-34119000 -10800 0 -03}
- {-18910800 -9000 1 -0230}
- {-2583000 -10800 0 -03}
- {12625200 -9000 1 -0230}
- {28953000 -10800 0 -03}
- {31546800 -10800 0 -03}
- {72932400 -7200 1 -02}
- {82692000 -10800 0 -03}
+ {-50446800 -9000 1 -03}
+ {-34205400 -10800 0 -03}
+ {10800 -10800 0 -03}
+ {9860400 -7200 1 -03}
+ {14176800 -10800 0 -03}
+ {72846000 -7200 1 -03}
+ {80100000 -10800 0 -03}
{126241200 -10800 0 -03}
- {132116400 -9000 1 -0230}
- {156909600 -9000 0 -02}
- {156911400 -7200 1 -02}
- {212983200 -10800 0 -03}
- {250052400 -7200 1 -02}
- {260244000 -10800 0 -03}
- {307594800 -7200 1 -02}
- {325994400 -10800 0 -03}
- {566449200 -7200 1 -02}
- {574308000 -10800 0 -03}
- {597812400 -7200 1 -02}
- {605671200 -10800 0 -03}
- {625633200 -7200 1 -02}
- {636516000 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {127278000 -5400 1 -03}
+ {132112800 -9000 0 -03}
+ {147234600 -10800 0 -03}
+ {156909600 -10800 0 -03}
+ {156913200 -7200 1 -03}
+ {165376800 -10800 0 -03}
+ {219812400 -7200 1 -03}
+ {226461600 -10800 0 -03}
+ {250052400 -7200 1 -03}
+ {257911200 -10800 0 -03}
+ {282711600 -7200 1 -03}
+ {289360800 -10800 0 -03}
+ {294202800 -7200 1 -03}
+ {322020000 -10800 0 -03}
+ {566449200 -7200 1 -03}
+ {573012000 -10800 0 -03}
+ {597812400 -7200 1 -03}
+ {605066400 -10800 0 -03}
+ {625633200 -7200 1 -03}
+ {635911200 -10800 0 -03}
+ {656478000 -7200 1 -03}
{667965600 -10800 0 -03}
- {688532400 -7200 1 -02}
+ {688532400 -7200 1 -03}
{699415200 -10800 0 -03}
- {719377200 -7200 1 -02}
+ {719377200 -7200 1 -03}
{730864800 -10800 0 -03}
- {1095562800 -7200 1 -02}
+ {1095562800 -7200 1 -03}
{1111896000 -10800 0 -03}
- {1128834000 -7200 1 -02}
+ {1128834000 -7200 1 -03}
{1142136000 -10800 0 -03}
- {1159678800 -7200 1 -02}
+ {1159678800 -7200 1 -03}
{1173585600 -10800 0 -03}
- {1191733200 -7200 1 -02}
+ {1191733200 -7200 1 -03}
{1205035200 -10800 0 -03}
- {1223182800 -7200 1 -02}
+ {1223182800 -7200 1 -03}
{1236484800 -10800 0 -03}
- {1254632400 -7200 1 -02}
+ {1254632400 -7200 1 -03}
{1268539200 -10800 0 -03}
- {1286082000 -7200 1 -02}
+ {1286082000 -7200 1 -03}
{1299988800 -10800 0 -03}
- {1317531600 -7200 1 -02}
+ {1317531600 -7200 1 -03}
{1331438400 -10800 0 -03}
- {1349586000 -7200 1 -02}
+ {1349586000 -7200 1 -03}
{1362888000 -10800 0 -03}
- {1381035600 -7200 1 -02}
+ {1381035600 -7200 1 -03}
{1394337600 -10800 0 -03}
- {1412485200 -7200 1 -02}
+ {1412485200 -7200 1 -03}
{1425787200 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Noronha b/tcl8.6/library/tzdata/America/Noronha
index f24b412..01fb745 100644
--- a/tcl8.6/library/tzdata/America/Noronha
+++ b/tcl8.6/library/tzdata/America/Noronha
@@ -3,46 +3,46 @@
set TZData(:America/Noronha) {
{-9223372036854775808 -7780 0 LMT}
{-1767217820 -7200 0 -02}
- {-1206961200 -3600 1 -01}
+ {-1206961200 -3600 1 -02}
{-1191366000 -7200 0 -02}
- {-1175378400 -3600 1 -01}
+ {-1175378400 -3600 1 -02}
{-1159830000 -7200 0 -02}
- {-633823200 -3600 1 -01}
+ {-633823200 -3600 1 -02}
{-622072800 -7200 0 -02}
- {-602287200 -3600 1 -01}
+ {-602287200 -3600 1 -02}
{-591836400 -7200 0 -02}
- {-570751200 -3600 1 -01}
+ {-570751200 -3600 1 -02}
{-560214000 -7200 0 -02}
- {-539128800 -3600 1 -01}
+ {-539128800 -3600 1 -02}
{-531356400 -7200 0 -02}
- {-191368800 -3600 1 -01}
+ {-191368800 -3600 1 -02}
{-184201200 -7200 0 -02}
- {-155167200 -3600 1 -01}
+ {-155167200 -3600 1 -02}
{-150073200 -7200 0 -02}
- {-128901600 -3600 1 -01}
+ {-128901600 -3600 1 -02}
{-121129200 -7200 0 -02}
- {-99957600 -3600 1 -01}
+ {-99957600 -3600 1 -02}
{-89593200 -7200 0 -02}
- {-68421600 -3600 1 -01}
+ {-68421600 -3600 1 -02}
{-57970800 -7200 0 -02}
- {499744800 -3600 1 -01}
+ {499744800 -3600 1 -02}
{511232400 -7200 0 -02}
- {530589600 -3600 1 -01}
+ {530589600 -3600 1 -02}
{540262800 -7200 0 -02}
- {562125600 -3600 1 -01}
+ {562125600 -3600 1 -02}
{571194000 -7200 0 -02}
- {592970400 -3600 1 -01}
+ {592970400 -3600 1 -02}
{602038800 -7200 0 -02}
- {624420000 -3600 1 -01}
+ {624420000 -3600 1 -02}
{634698000 -7200 0 -02}
{653533200 -7200 0 -02}
{938656800 -7200 0 -02}
- {938916000 -3600 1 -01}
+ {938916000 -3600 1 -02}
{951613200 -7200 0 -02}
- {970970400 -3600 1 -01}
+ {970970400 -3600 1 -02}
{971571600 -7200 0 -02}
{1000346400 -7200 0 -02}
- {1003024800 -3600 1 -01}
+ {1003024800 -3600 1 -02}
{1013907600 -7200 0 -02}
{1033434000 -7200 0 -02}
}
diff --git a/tcl8.6/library/tzdata/America/Porto_Velho b/tcl8.6/library/tzdata/America/Porto_Velho
index 42566ad..8d7c8fd 100644
--- a/tcl8.6/library/tzdata/America/Porto_Velho
+++ b/tcl8.6/library/tzdata/America/Porto_Velho
@@ -3,33 +3,33 @@
set TZData(:America/Porto_Velho) {
{-9223372036854775808 -15336 0 LMT}
{-1767210264 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
{590036400 -14400 0 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Punta_Arenas b/tcl8.6/library/tzdata/America/Punta_Arenas
index 75487e7..5e8202a 100644
--- a/tcl8.6/library/tzdata/America/Punta_Arenas
+++ b/tcl8.6/library/tzdata/America/Punta_Arenas
@@ -8,115 +8,115 @@ set TZData(:America/Punta_Arenas) {
{-1619205434 -14400 0 -04}
{-1593806400 -16966 0 SMT}
{-1335986234 -18000 0 -05}
- {-1335985200 -14400 1 -04}
+ {-1335985200 -14400 1 -05}
{-1317585600 -18000 0 -05}
- {-1304362800 -14400 1 -04}
+ {-1304362800 -14400 1 -05}
{-1286049600 -18000 0 -05}
- {-1272826800 -14400 1 -04}
+ {-1272826800 -14400 1 -05}
{-1254513600 -18000 0 -05}
- {-1241290800 -14400 1 -04}
+ {-1241290800 -14400 1 -05}
{-1222977600 -18000 0 -05}
- {-1209754800 -14400 1 -04}
+ {-1209754800 -14400 1 -05}
{-1191355200 -18000 0 -05}
{-1178132400 -14400 0 -04}
{-870552000 -18000 0 -05}
{-865278000 -14400 0 -04}
{-718056000 -18000 0 -05}
{-713649600 -14400 0 -04}
- {-36619200 -10800 1 -03}
+ {-36619200 -10800 1 -04}
{-23922000 -14400 0 -04}
- {-3355200 -10800 1 -03}
+ {-3355200 -10800 1 -04}
{7527600 -14400 0 -04}
- {24465600 -10800 1 -03}
+ {24465600 -10800 1 -04}
{37767600 -14400 0 -04}
- {55915200 -10800 1 -03}
+ {55915200 -10800 1 -04}
{69217200 -14400 0 -04}
- {87969600 -10800 1 -03}
+ {87969600 -10800 1 -04}
{100666800 -14400 0 -04}
- {118209600 -10800 1 -03}
+ {118209600 -10800 1 -04}
{132116400 -14400 0 -04}
- {150868800 -10800 1 -03}
+ {150868800 -10800 1 -04}
{163566000 -14400 0 -04}
- {182318400 -10800 1 -03}
+ {182318400 -10800 1 -04}
{195620400 -14400 0 -04}
- {213768000 -10800 1 -03}
+ {213768000 -10800 1 -04}
{227070000 -14400 0 -04}
- {245217600 -10800 1 -03}
+ {245217600 -10800 1 -04}
{258519600 -14400 0 -04}
- {277272000 -10800 1 -03}
+ {277272000 -10800 1 -04}
{289969200 -14400 0 -04}
- {308721600 -10800 1 -03}
+ {308721600 -10800 1 -04}
{321418800 -14400 0 -04}
- {340171200 -10800 1 -03}
+ {340171200 -10800 1 -04}
{353473200 -14400 0 -04}
- {371620800 -10800 1 -03}
+ {371620800 -10800 1 -04}
{384922800 -14400 0 -04}
- {403070400 -10800 1 -03}
+ {403070400 -10800 1 -04}
{416372400 -14400 0 -04}
- {434520000 -10800 1 -03}
+ {434520000 -10800 1 -04}
{447822000 -14400 0 -04}
- {466574400 -10800 1 -03}
+ {466574400 -10800 1 -04}
{479271600 -14400 0 -04}
- {498024000 -10800 1 -03}
+ {498024000 -10800 1 -04}
{510721200 -14400 0 -04}
- {529473600 -10800 1 -03}
+ {529473600 -10800 1 -04}
{545194800 -14400 0 -04}
- {560923200 -10800 1 -03}
+ {560923200 -10800 1 -04}
{574225200 -14400 0 -04}
- {592372800 -10800 1 -03}
+ {592372800 -10800 1 -04}
{605674800 -14400 0 -04}
- {624427200 -10800 1 -03}
+ {624427200 -10800 1 -04}
{637124400 -14400 0 -04}
- {653457600 -10800 1 -03}
+ {653457600 -10800 1 -04}
{668574000 -14400 0 -04}
- {687326400 -10800 1 -03}
+ {687326400 -10800 1 -04}
{700628400 -14400 0 -04}
- {718776000 -10800 1 -03}
+ {718776000 -10800 1 -04}
{732078000 -14400 0 -04}
- {750225600 -10800 1 -03}
+ {750225600 -10800 1 -04}
{763527600 -14400 0 -04}
- {781675200 -10800 1 -03}
+ {781675200 -10800 1 -04}
{794977200 -14400 0 -04}
- {813729600 -10800 1 -03}
+ {813729600 -10800 1 -04}
{826426800 -14400 0 -04}
- {845179200 -10800 1 -03}
+ {845179200 -10800 1 -04}
{859690800 -14400 0 -04}
- {876628800 -10800 1 -03}
+ {876628800 -10800 1 -04}
{889930800 -14400 0 -04}
- {906868800 -10800 1 -03}
+ {906868800 -10800 1 -04}
{923194800 -14400 0 -04}
- {939528000 -10800 1 -03}
+ {939528000 -10800 1 -04}
{952830000 -14400 0 -04}
- {971582400 -10800 1 -03}
+ {971582400 -10800 1 -04}
{984279600 -14400 0 -04}
- {1003032000 -10800 1 -03}
+ {1003032000 -10800 1 -04}
{1015729200 -14400 0 -04}
- {1034481600 -10800 1 -03}
+ {1034481600 -10800 1 -04}
{1047178800 -14400 0 -04}
- {1065931200 -10800 1 -03}
+ {1065931200 -10800 1 -04}
{1079233200 -14400 0 -04}
- {1097380800 -10800 1 -03}
+ {1097380800 -10800 1 -04}
{1110682800 -14400 0 -04}
- {1128830400 -10800 1 -03}
+ {1128830400 -10800 1 -04}
{1142132400 -14400 0 -04}
- {1160884800 -10800 1 -03}
+ {1160884800 -10800 1 -04}
{1173582000 -14400 0 -04}
- {1192334400 -10800 1 -03}
+ {1192334400 -10800 1 -04}
{1206846000 -14400 0 -04}
- {1223784000 -10800 1 -03}
+ {1223784000 -10800 1 -04}
{1237086000 -14400 0 -04}
- {1255233600 -10800 1 -03}
+ {1255233600 -10800 1 -04}
{1270350000 -14400 0 -04}
- {1286683200 -10800 1 -03}
+ {1286683200 -10800 1 -04}
{1304823600 -14400 0 -04}
- {1313899200 -10800 1 -03}
+ {1313899200 -10800 1 -04}
{1335668400 -14400 0 -04}
- {1346558400 -10800 1 -03}
+ {1346558400 -10800 1 -04}
{1367118000 -14400 0 -04}
- {1378612800 -10800 1 -03}
+ {1378612800 -10800 1 -04}
{1398567600 -14400 0 -04}
- {1410062400 -10800 1 -03}
+ {1410062400 -10800 1 -04}
{1463281200 -14400 0 -04}
- {1471147200 -10800 1 -03}
+ {1471147200 -10800 1 -04}
{1480820400 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Recife b/tcl8.6/library/tzdata/America/Recife
index 8eae571..db0a445 100644
--- a/tcl8.6/library/tzdata/America/Recife
+++ b/tcl8.6/library/tzdata/America/Recife
@@ -3,46 +3,46 @@
set TZData(:America/Recife) {
{-9223372036854775808 -8376 0 LMT}
{-1767217224 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
- {-191365200 -7200 1 -02}
+ {-191365200 -7200 1 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
{653536800 -10800 0 -03}
{938660400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{971575200 -10800 0 -03}
{1000350000 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
{1033437600 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/America/Rio_Branco b/tcl8.6/library/tzdata/America/Rio_Branco
index e3c2f31..088800b 100644
--- a/tcl8.6/library/tzdata/America/Rio_Branco
+++ b/tcl8.6/library/tzdata/America/Rio_Branco
@@ -3,33 +3,33 @@
set TZData(:America/Rio_Branco) {
{-9223372036854775808 -16272 0 LMT}
{-1767209328 -18000 0 -05}
- {-1206950400 -14400 1 -04}
+ {-1206950400 -14400 1 -05}
{-1191355200 -18000 0 -05}
- {-1175367600 -14400 1 -04}
+ {-1175367600 -14400 1 -05}
{-1159819200 -18000 0 -05}
- {-633812400 -14400 1 -04}
+ {-633812400 -14400 1 -05}
{-622062000 -18000 0 -05}
- {-602276400 -14400 1 -04}
+ {-602276400 -14400 1 -05}
{-591825600 -18000 0 -05}
- {-570740400 -14400 1 -04}
+ {-570740400 -14400 1 -05}
{-560203200 -18000 0 -05}
- {-539118000 -14400 1 -04}
+ {-539118000 -14400 1 -05}
{-531345600 -18000 0 -05}
- {-191358000 -14400 1 -04}
+ {-191358000 -14400 1 -05}
{-184190400 -18000 0 -05}
- {-155156400 -14400 1 -04}
+ {-155156400 -14400 1 -05}
{-150062400 -18000 0 -05}
- {-128890800 -14400 1 -04}
+ {-128890800 -14400 1 -05}
{-121118400 -18000 0 -05}
- {-99946800 -14400 1 -04}
+ {-99946800 -14400 1 -05}
{-89582400 -18000 0 -05}
- {-68410800 -14400 1 -04}
+ {-68410800 -14400 1 -05}
{-57960000 -18000 0 -05}
- {499755600 -14400 1 -04}
+ {499755600 -14400 1 -05}
{511243200 -18000 0 -05}
- {530600400 -14400 1 -04}
+ {530600400 -14400 1 -05}
{540273600 -18000 0 -05}
- {562136400 -14400 1 -04}
+ {562136400 -14400 1 -05}
{571204800 -18000 0 -05}
{590040000 -18000 0 -05}
{1214283600 -14400 0 -04}
diff --git a/tcl8.6/library/tzdata/America/Santarem b/tcl8.6/library/tzdata/America/Santarem
index f81e9b6..5fa3551 100644
--- a/tcl8.6/library/tzdata/America/Santarem
+++ b/tcl8.6/library/tzdata/America/Santarem
@@ -3,33 +3,33 @@
set TZData(:America/Santarem) {
{-9223372036854775808 -13128 0 LMT}
{-1767212472 -14400 0 -04}
- {-1206954000 -10800 1 -03}
+ {-1206954000 -10800 1 -04}
{-1191358800 -14400 0 -04}
- {-1175371200 -10800 1 -03}
+ {-1175371200 -10800 1 -04}
{-1159822800 -14400 0 -04}
- {-633816000 -10800 1 -03}
+ {-633816000 -10800 1 -04}
{-622065600 -14400 0 -04}
- {-602280000 -10800 1 -03}
+ {-602280000 -10800 1 -04}
{-591829200 -14400 0 -04}
- {-570744000 -10800 1 -03}
+ {-570744000 -10800 1 -04}
{-560206800 -14400 0 -04}
- {-539121600 -10800 1 -03}
+ {-539121600 -10800 1 -04}
{-531349200 -14400 0 -04}
- {-191361600 -10800 1 -03}
+ {-191361600 -10800 1 -04}
{-184194000 -14400 0 -04}
- {-155160000 -10800 1 -03}
+ {-155160000 -10800 1 -04}
{-150066000 -14400 0 -04}
- {-128894400 -10800 1 -03}
+ {-128894400 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-99950400 -10800 1 -03}
+ {-99950400 -10800 1 -04}
{-89586000 -14400 0 -04}
- {-68414400 -10800 1 -03}
+ {-68414400 -10800 1 -04}
{-57963600 -14400 0 -04}
- {499752000 -10800 1 -03}
+ {499752000 -10800 1 -04}
{511239600 -14400 0 -04}
- {530596800 -10800 1 -03}
+ {530596800 -10800 1 -04}
{540270000 -14400 0 -04}
- {562132800 -10800 1 -03}
+ {562132800 -10800 1 -04}
{571201200 -14400 0 -04}
{590036400 -14400 0 -04}
{1214280000 -10800 0 -03}
diff --git a/tcl8.6/library/tzdata/America/Santiago b/tcl8.6/library/tzdata/America/Santiago
index 95e920d..55212b9 100644
--- a/tcl8.6/library/tzdata/America/Santiago
+++ b/tcl8.6/library/tzdata/America/Santiago
@@ -8,15 +8,15 @@ set TZData(:America/Santiago) {
{-1619205434 -14400 0 -04}
{-1593806400 -16966 0 SMT}
{-1335986234 -18000 0 -05}
- {-1335985200 -14400 1 -04}
+ {-1335985200 -14400 1 -05}
{-1317585600 -18000 0 -05}
- {-1304362800 -14400 1 -04}
+ {-1304362800 -14400 1 -05}
{-1286049600 -18000 0 -05}
- {-1272826800 -14400 1 -04}
+ {-1272826800 -14400 1 -05}
{-1254513600 -18000 0 -05}
- {-1241290800 -14400 1 -04}
+ {-1241290800 -14400 1 -05}
{-1222977600 -18000 0 -05}
- {-1209754800 -14400 1 -04}
+ {-1209754800 -14400 1 -05}
{-1191355200 -18000 0 -05}
{-1178132400 -14400 0 -04}
{-870552000 -18000 0 -05}
@@ -25,265 +25,265 @@ set TZData(:America/Santiago) {
{-736376400 -14400 0 -04}
{-718056000 -18000 0 -05}
{-713649600 -14400 0 -04}
- {-36619200 -10800 1 -03}
+ {-36619200 -10800 1 -04}
{-23922000 -14400 0 -04}
- {-3355200 -10800 1 -03}
+ {-3355200 -10800 1 -04}
{7527600 -14400 0 -04}
- {24465600 -10800 1 -03}
+ {24465600 -10800 1 -04}
{37767600 -14400 0 -04}
- {55915200 -10800 1 -03}
+ {55915200 -10800 1 -04}
{69217200 -14400 0 -04}
- {87969600 -10800 1 -03}
+ {87969600 -10800 1 -04}
{100666800 -14400 0 -04}
- {118209600 -10800 1 -03}
+ {118209600 -10800 1 -04}
{132116400 -14400 0 -04}
- {150868800 -10800 1 -03}
+ {150868800 -10800 1 -04}
{163566000 -14400 0 -04}
- {182318400 -10800 1 -03}
+ {182318400 -10800 1 -04}
{195620400 -14400 0 -04}
- {213768000 -10800 1 -03}
+ {213768000 -10800 1 -04}
{227070000 -14400 0 -04}
- {245217600 -10800 1 -03}
+ {245217600 -10800 1 -04}
{258519600 -14400 0 -04}
- {277272000 -10800 1 -03}
+ {277272000 -10800 1 -04}
{289969200 -14400 0 -04}
- {308721600 -10800 1 -03}
+ {308721600 -10800 1 -04}
{321418800 -14400 0 -04}
- {340171200 -10800 1 -03}
+ {340171200 -10800 1 -04}
{353473200 -14400 0 -04}
- {371620800 -10800 1 -03}
+ {371620800 -10800 1 -04}
{384922800 -14400 0 -04}
- {403070400 -10800 1 -03}
+ {403070400 -10800 1 -04}
{416372400 -14400 0 -04}
- {434520000 -10800 1 -03}
+ {434520000 -10800 1 -04}
{447822000 -14400 0 -04}
- {466574400 -10800 1 -03}
+ {466574400 -10800 1 -04}
{479271600 -14400 0 -04}
- {498024000 -10800 1 -03}
+ {498024000 -10800 1 -04}
{510721200 -14400 0 -04}
- {529473600 -10800 1 -03}
+ {529473600 -10800 1 -04}
{545194800 -14400 0 -04}
- {560923200 -10800 1 -03}
+ {560923200 -10800 1 -04}
{574225200 -14400 0 -04}
- {592372800 -10800 1 -03}
+ {592372800 -10800 1 -04}
{605674800 -14400 0 -04}
- {624427200 -10800 1 -03}
+ {624427200 -10800 1 -04}
{637124400 -14400 0 -04}
- {653457600 -10800 1 -03}
+ {653457600 -10800 1 -04}
{668574000 -14400 0 -04}
- {687326400 -10800 1 -03}
+ {687326400 -10800 1 -04}
{700628400 -14400 0 -04}
- {718776000 -10800 1 -03}
+ {718776000 -10800 1 -04}
{732078000 -14400 0 -04}
- {750225600 -10800 1 -03}
+ {750225600 -10800 1 -04}
{763527600 -14400 0 -04}
- {781675200 -10800 1 -03}
+ {781675200 -10800 1 -04}
{794977200 -14400 0 -04}
- {813729600 -10800 1 -03}
+ {813729600 -10800 1 -04}
{826426800 -14400 0 -04}
- {845179200 -10800 1 -03}
+ {845179200 -10800 1 -04}
{859690800 -14400 0 -04}
- {876628800 -10800 1 -03}
+ {876628800 -10800 1 -04}
{889930800 -14400 0 -04}
- {906868800 -10800 1 -03}
+ {906868800 -10800 1 -04}
{923194800 -14400 0 -04}
- {939528000 -10800 1 -03}
+ {939528000 -10800 1 -04}
{952830000 -14400 0 -04}
- {971582400 -10800 1 -03}
+ {971582400 -10800 1 -04}
{984279600 -14400 0 -04}
- {1003032000 -10800 1 -03}
+ {1003032000 -10800 1 -04}
{1015729200 -14400 0 -04}
- {1034481600 -10800 1 -03}
+ {1034481600 -10800 1 -04}
{1047178800 -14400 0 -04}
- {1065931200 -10800 1 -03}
+ {1065931200 -10800 1 -04}
{1079233200 -14400 0 -04}
- {1097380800 -10800 1 -03}
+ {1097380800 -10800 1 -04}
{1110682800 -14400 0 -04}
- {1128830400 -10800 1 -03}
+ {1128830400 -10800 1 -04}
{1142132400 -14400 0 -04}
- {1160884800 -10800 1 -03}
+ {1160884800 -10800 1 -04}
{1173582000 -14400 0 -04}
- {1192334400 -10800 1 -03}
+ {1192334400 -10800 1 -04}
{1206846000 -14400 0 -04}
- {1223784000 -10800 1 -03}
+ {1223784000 -10800 1 -04}
{1237086000 -14400 0 -04}
- {1255233600 -10800 1 -03}
+ {1255233600 -10800 1 -04}
{1270350000 -14400 0 -04}
- {1286683200 -10800 1 -03}
+ {1286683200 -10800 1 -04}
{1304823600 -14400 0 -04}
- {1313899200 -10800 1 -03}
+ {1313899200 -10800 1 -04}
{1335668400 -14400 0 -04}
- {1346558400 -10800 1 -03}
+ {1346558400 -10800 1 -04}
{1367118000 -14400 0 -04}
- {1378612800 -10800 1 -03}
+ {1378612800 -10800 1 -04}
{1398567600 -14400 0 -04}
- {1410062400 -10800 1 -03}
+ {1410062400 -10800 1 -04}
{1463281200 -14400 0 -04}
- {1471147200 -10800 1 -03}
+ {1471147200 -10800 1 -04}
{1494730800 -14400 0 -04}
- {1502596800 -10800 1 -03}
+ {1502596800 -10800 1 -04}
{1526180400 -14400 0 -04}
- {1534046400 -10800 1 -03}
- {1557630000 -14400 0 -04}
- {1565496000 -10800 1 -03}
- {1589079600 -14400 0 -04}
- {1596945600 -10800 1 -03}
- {1620529200 -14400 0 -04}
- {1629000000 -10800 1 -03}
- {1652583600 -14400 0 -04}
- {1660449600 -10800 1 -03}
- {1684033200 -14400 0 -04}
- {1691899200 -10800 1 -03}
- {1715482800 -14400 0 -04}
- {1723348800 -10800 1 -03}
- {1746932400 -14400 0 -04}
- {1754798400 -10800 1 -03}
- {1778382000 -14400 0 -04}
- {1786248000 -10800 1 -03}
- {1809831600 -14400 0 -04}
- {1818302400 -10800 1 -03}
- {1841886000 -14400 0 -04}
- {1849752000 -10800 1 -03}
- {1873335600 -14400 0 -04}
- {1881201600 -10800 1 -03}
- {1904785200 -14400 0 -04}
- {1912651200 -10800 1 -03}
- {1936234800 -14400 0 -04}
- {1944100800 -10800 1 -03}
- {1967684400 -14400 0 -04}
- {1976155200 -10800 1 -03}
- {1999738800 -14400 0 -04}
- {2007604800 -10800 1 -03}
- {2031188400 -14400 0 -04}
- {2039054400 -10800 1 -03}
- {2062638000 -14400 0 -04}
- {2070504000 -10800 1 -03}
- {2094087600 -14400 0 -04}
- {2101953600 -10800 1 -03}
- {2125537200 -14400 0 -04}
- {2133403200 -10800 1 -03}
- {2156986800 -14400 0 -04}
- {2165457600 -10800 1 -03}
- {2189041200 -14400 0 -04}
- {2196907200 -10800 1 -03}
- {2220490800 -14400 0 -04}
- {2228356800 -10800 1 -03}
- {2251940400 -14400 0 -04}
- {2259806400 -10800 1 -03}
- {2283390000 -14400 0 -04}
- {2291256000 -10800 1 -03}
- {2314839600 -14400 0 -04}
- {2322705600 -10800 1 -03}
- {2346894000 -14400 0 -04}
- {2354760000 -10800 1 -03}
- {2378343600 -14400 0 -04}
- {2386209600 -10800 1 -03}
- {2409793200 -14400 0 -04}
- {2417659200 -10800 1 -03}
- {2441242800 -14400 0 -04}
- {2449108800 -10800 1 -03}
- {2472692400 -14400 0 -04}
- {2480558400 -10800 1 -03}
- {2504142000 -14400 0 -04}
- {2512612800 -10800 1 -03}
- {2536196400 -14400 0 -04}
- {2544062400 -10800 1 -03}
- {2567646000 -14400 0 -04}
- {2575512000 -10800 1 -03}
- {2599095600 -14400 0 -04}
- {2606961600 -10800 1 -03}
- {2630545200 -14400 0 -04}
- {2638411200 -10800 1 -03}
- {2661994800 -14400 0 -04}
- {2669860800 -10800 1 -03}
- {2693444400 -14400 0 -04}
- {2701915200 -10800 1 -03}
- {2725498800 -14400 0 -04}
- {2733364800 -10800 1 -03}
- {2756948400 -14400 0 -04}
- {2764814400 -10800 1 -03}
- {2788398000 -14400 0 -04}
- {2796264000 -10800 1 -03}
- {2819847600 -14400 0 -04}
- {2827713600 -10800 1 -03}
- {2851297200 -14400 0 -04}
- {2859768000 -10800 1 -03}
- {2883351600 -14400 0 -04}
- {2891217600 -10800 1 -03}
- {2914801200 -14400 0 -04}
- {2922667200 -10800 1 -03}
- {2946250800 -14400 0 -04}
- {2954116800 -10800 1 -03}
- {2977700400 -14400 0 -04}
- {2985566400 -10800 1 -03}
- {3009150000 -14400 0 -04}
- {3017016000 -10800 1 -03}
- {3040599600 -14400 0 -04}
- {3049070400 -10800 1 -03}
- {3072654000 -14400 0 -04}
- {3080520000 -10800 1 -03}
- {3104103600 -14400 0 -04}
- {3111969600 -10800 1 -03}
- {3135553200 -14400 0 -04}
- {3143419200 -10800 1 -03}
- {3167002800 -14400 0 -04}
- {3174868800 -10800 1 -03}
- {3198452400 -14400 0 -04}
- {3206318400 -10800 1 -03}
- {3230506800 -14400 0 -04}
- {3238372800 -10800 1 -03}
- {3261956400 -14400 0 -04}
- {3269822400 -10800 1 -03}
- {3293406000 -14400 0 -04}
- {3301272000 -10800 1 -03}
- {3324855600 -14400 0 -04}
- {3332721600 -10800 1 -03}
- {3356305200 -14400 0 -04}
- {3364171200 -10800 1 -03}
- {3387754800 -14400 0 -04}
- {3396225600 -10800 1 -03}
- {3419809200 -14400 0 -04}
- {3427675200 -10800 1 -03}
- {3451258800 -14400 0 -04}
- {3459124800 -10800 1 -03}
- {3482708400 -14400 0 -04}
- {3490574400 -10800 1 -03}
- {3514158000 -14400 0 -04}
- {3522024000 -10800 1 -03}
- {3545607600 -14400 0 -04}
- {3553473600 -10800 1 -03}
- {3577057200 -14400 0 -04}
- {3585528000 -10800 1 -03}
- {3609111600 -14400 0 -04}
- {3616977600 -10800 1 -03}
- {3640561200 -14400 0 -04}
- {3648427200 -10800 1 -03}
- {3672010800 -14400 0 -04}
- {3679876800 -10800 1 -03}
- {3703460400 -14400 0 -04}
- {3711326400 -10800 1 -03}
- {3734910000 -14400 0 -04}
- {3743380800 -10800 1 -03}
- {3766964400 -14400 0 -04}
- {3774830400 -10800 1 -03}
- {3798414000 -14400 0 -04}
- {3806280000 -10800 1 -03}
- {3829863600 -14400 0 -04}
- {3837729600 -10800 1 -03}
- {3861313200 -14400 0 -04}
- {3869179200 -10800 1 -03}
- {3892762800 -14400 0 -04}
- {3900628800 -10800 1 -03}
- {3924212400 -14400 0 -04}
- {3932683200 -10800 1 -03}
- {3956266800 -14400 0 -04}
- {3964132800 -10800 1 -03}
- {3987716400 -14400 0 -04}
- {3995582400 -10800 1 -03}
- {4019166000 -14400 0 -04}
- {4027032000 -10800 1 -03}
- {4050615600 -14400 0 -04}
- {4058481600 -10800 1 -03}
- {4082065200 -14400 0 -04}
- {4089931200 -10800 1 -03}
+ {1534046400 -10800 1 -04}
+ {1554606000 -14400 0 -04}
+ {1567915200 -10800 1 -04}
+ {1586055600 -14400 0 -04}
+ {1599364800 -10800 1 -04}
+ {1617505200 -14400 0 -04}
+ {1630814400 -10800 1 -04}
+ {1648954800 -14400 0 -04}
+ {1662264000 -10800 1 -04}
+ {1680404400 -14400 0 -04}
+ {1693713600 -10800 1 -04}
+ {1712458800 -14400 0 -04}
+ {1725768000 -10800 1 -04}
+ {1743908400 -14400 0 -04}
+ {1757217600 -10800 1 -04}
+ {1775358000 -14400 0 -04}
+ {1788667200 -10800 1 -04}
+ {1806807600 -14400 0 -04}
+ {1820116800 -10800 1 -04}
+ {1838257200 -14400 0 -04}
+ {1851566400 -10800 1 -04}
+ {1870311600 -14400 0 -04}
+ {1883016000 -10800 1 -04}
+ {1901761200 -14400 0 -04}
+ {1915070400 -10800 1 -04}
+ {1933210800 -14400 0 -04}
+ {1946520000 -10800 1 -04}
+ {1964660400 -14400 0 -04}
+ {1977969600 -10800 1 -04}
+ {1996110000 -14400 0 -04}
+ {2009419200 -10800 1 -04}
+ {2027559600 -14400 0 -04}
+ {2040868800 -10800 1 -04}
+ {2059614000 -14400 0 -04}
+ {2072318400 -10800 1 -04}
+ {2091063600 -14400 0 -04}
+ {2104372800 -10800 1 -04}
+ {2122513200 -14400 0 -04}
+ {2135822400 -10800 1 -04}
+ {2153962800 -14400 0 -04}
+ {2167272000 -10800 1 -04}
+ {2185412400 -14400 0 -04}
+ {2198721600 -10800 1 -04}
+ {2217466800 -14400 0 -04}
+ {2230171200 -10800 1 -04}
+ {2248916400 -14400 0 -04}
+ {2262225600 -10800 1 -04}
+ {2280366000 -14400 0 -04}
+ {2293675200 -10800 1 -04}
+ {2311815600 -14400 0 -04}
+ {2325124800 -10800 1 -04}
+ {2343265200 -14400 0 -04}
+ {2356574400 -10800 1 -04}
+ {2374714800 -14400 0 -04}
+ {2388024000 -10800 1 -04}
+ {2406769200 -14400 0 -04}
+ {2419473600 -10800 1 -04}
+ {2438218800 -14400 0 -04}
+ {2451528000 -10800 1 -04}
+ {2469668400 -14400 0 -04}
+ {2482977600 -10800 1 -04}
+ {2501118000 -14400 0 -04}
+ {2514427200 -10800 1 -04}
+ {2532567600 -14400 0 -04}
+ {2545876800 -10800 1 -04}
+ {2564017200 -14400 0 -04}
+ {2577326400 -10800 1 -04}
+ {2596071600 -14400 0 -04}
+ {2609380800 -10800 1 -04}
+ {2627521200 -14400 0 -04}
+ {2640830400 -10800 1 -04}
+ {2658970800 -14400 0 -04}
+ {2672280000 -10800 1 -04}
+ {2690420400 -14400 0 -04}
+ {2703729600 -10800 1 -04}
+ {2721870000 -14400 0 -04}
+ {2735179200 -10800 1 -04}
+ {2753924400 -14400 0 -04}
+ {2766628800 -10800 1 -04}
+ {2785374000 -14400 0 -04}
+ {2798683200 -10800 1 -04}
+ {2816823600 -14400 0 -04}
+ {2830132800 -10800 1 -04}
+ {2848273200 -14400 0 -04}
+ {2861582400 -10800 1 -04}
+ {2879722800 -14400 0 -04}
+ {2893032000 -10800 1 -04}
+ {2911172400 -14400 0 -04}
+ {2924481600 -10800 1 -04}
+ {2943226800 -14400 0 -04}
+ {2955931200 -10800 1 -04}
+ {2974676400 -14400 0 -04}
+ {2987985600 -10800 1 -04}
+ {3006126000 -14400 0 -04}
+ {3019435200 -10800 1 -04}
+ {3037575600 -14400 0 -04}
+ {3050884800 -10800 1 -04}
+ {3069025200 -14400 0 -04}
+ {3082334400 -10800 1 -04}
+ {3101079600 -14400 0 -04}
+ {3113784000 -10800 1 -04}
+ {3132529200 -14400 0 -04}
+ {3145838400 -10800 1 -04}
+ {3163978800 -14400 0 -04}
+ {3177288000 -10800 1 -04}
+ {3195428400 -14400 0 -04}
+ {3208737600 -10800 1 -04}
+ {3226878000 -14400 0 -04}
+ {3240187200 -10800 1 -04}
+ {3258327600 -14400 0 -04}
+ {3271636800 -10800 1 -04}
+ {3290382000 -14400 0 -04}
+ {3303086400 -10800 1 -04}
+ {3321831600 -14400 0 -04}
+ {3335140800 -10800 1 -04}
+ {3353281200 -14400 0 -04}
+ {3366590400 -10800 1 -04}
+ {3384730800 -14400 0 -04}
+ {3398040000 -10800 1 -04}
+ {3416180400 -14400 0 -04}
+ {3429489600 -10800 1 -04}
+ {3447630000 -14400 0 -04}
+ {3460939200 -10800 1 -04}
+ {3479684400 -14400 0 -04}
+ {3492993600 -10800 1 -04}
+ {3511134000 -14400 0 -04}
+ {3524443200 -10800 1 -04}
+ {3542583600 -14400 0 -04}
+ {3555892800 -10800 1 -04}
+ {3574033200 -14400 0 -04}
+ {3587342400 -10800 1 -04}
+ {3605482800 -14400 0 -04}
+ {3618792000 -10800 1 -04}
+ {3637537200 -14400 0 -04}
+ {3650241600 -10800 1 -04}
+ {3668986800 -14400 0 -04}
+ {3682296000 -10800 1 -04}
+ {3700436400 -14400 0 -04}
+ {3713745600 -10800 1 -04}
+ {3731886000 -14400 0 -04}
+ {3745195200 -10800 1 -04}
+ {3763335600 -14400 0 -04}
+ {3776644800 -10800 1 -04}
+ {3794785200 -14400 0 -04}
+ {3808094400 -10800 1 -04}
+ {3826839600 -14400 0 -04}
+ {3839544000 -10800 1 -04}
+ {3858289200 -14400 0 -04}
+ {3871598400 -10800 1 -04}
+ {3889738800 -14400 0 -04}
+ {3903048000 -10800 1 -04}
+ {3921188400 -14400 0 -04}
+ {3934497600 -10800 1 -04}
+ {3952638000 -14400 0 -04}
+ {3965947200 -10800 1 -04}
+ {3984692400 -14400 0 -04}
+ {3997396800 -10800 1 -04}
+ {4016142000 -14400 0 -04}
+ {4029451200 -10800 1 -04}
+ {4047591600 -14400 0 -04}
+ {4060900800 -10800 1 -04}
+ {4079041200 -14400 0 -04}
+ {4092350400 -10800 1 -04}
}
diff --git a/tcl8.6/library/tzdata/America/Sao_Paulo b/tcl8.6/library/tzdata/America/Sao_Paulo
index a61c638..235f57a 100644
--- a/tcl8.6/library/tzdata/America/Sao_Paulo
+++ b/tcl8.6/library/tzdata/America/Sao_Paulo
@@ -3,256 +3,256 @@
set TZData(:America/Sao_Paulo) {
{-9223372036854775808 -11188 0 LMT}
{-1767214412 -10800 0 -03}
- {-1206957600 -7200 1 -02}
+ {-1206957600 -7200 1 -03}
{-1191362400 -10800 0 -03}
- {-1175374800 -7200 1 -02}
+ {-1175374800 -7200 1 -03}
{-1159826400 -10800 0 -03}
- {-633819600 -7200 1 -02}
+ {-633819600 -7200 1 -03}
{-622069200 -10800 0 -03}
- {-602283600 -7200 1 -02}
+ {-602283600 -7200 1 -03}
{-591832800 -10800 0 -03}
- {-570747600 -7200 1 -02}
+ {-570747600 -7200 1 -03}
{-560210400 -10800 0 -03}
- {-539125200 -7200 1 -02}
+ {-539125200 -7200 1 -03}
{-531352800 -10800 0 -03}
{-195429600 -7200 1 -02}
{-189381600 -7200 0 -03}
{-184197600 -10800 0 -03}
- {-155163600 -7200 1 -02}
+ {-155163600 -7200 1 -03}
{-150069600 -10800 0 -03}
- {-128898000 -7200 1 -02}
+ {-128898000 -7200 1 -03}
{-121125600 -10800 0 -03}
- {-99954000 -7200 1 -02}
+ {-99954000 -7200 1 -03}
{-89589600 -10800 0 -03}
- {-68418000 -7200 1 -02}
+ {-68418000 -7200 1 -03}
{-57967200 -10800 0 -03}
- {499748400 -7200 1 -02}
+ {499748400 -7200 1 -03}
{511236000 -10800 0 -03}
- {530593200 -7200 1 -02}
+ {530593200 -7200 1 -03}
{540266400 -10800 0 -03}
- {562129200 -7200 1 -02}
+ {562129200 -7200 1 -03}
{571197600 -10800 0 -03}
- {592974000 -7200 1 -02}
+ {592974000 -7200 1 -03}
{602042400 -10800 0 -03}
- {624423600 -7200 1 -02}
+ {624423600 -7200 1 -03}
{634701600 -10800 0 -03}
- {656478000 -7200 1 -02}
+ {656478000 -7200 1 -03}
{666756000 -10800 0 -03}
- {687927600 -7200 1 -02}
+ {687927600 -7200 1 -03}
{697600800 -10800 0 -03}
- {719982000 -7200 1 -02}
+ {719982000 -7200 1 -03}
{728445600 -10800 0 -03}
- {750826800 -7200 1 -02}
+ {750826800 -7200 1 -03}
{761709600 -10800 0 -03}
- {782276400 -7200 1 -02}
+ {782276400 -7200 1 -03}
{793159200 -10800 0 -03}
- {813726000 -7200 1 -02}
+ {813726000 -7200 1 -03}
{824004000 -10800 0 -03}
- {844570800 -7200 1 -02}
+ {844570800 -7200 1 -03}
{856058400 -10800 0 -03}
- {876106800 -7200 1 -02}
+ {876106800 -7200 1 -03}
{888717600 -10800 0 -03}
- {908074800 -7200 1 -02}
+ {908074800 -7200 1 -03}
{919562400 -10800 0 -03}
- {938919600 -7200 1 -02}
+ {938919600 -7200 1 -03}
{951616800 -10800 0 -03}
- {970974000 -7200 1 -02}
+ {970974000 -7200 1 -03}
{982461600 -10800 0 -03}
- {1003028400 -7200 1 -02}
+ {1003028400 -7200 1 -03}
{1013911200 -10800 0 -03}
- {1036292400 -7200 1 -02}
+ {1036292400 -7200 1 -03}
{1045360800 -10800 0 -03}
- {1066532400 -7200 1 -02}
+ {1066532400 -7200 1 -03}
{1076810400 -10800 0 -03}
- {1099364400 -7200 1 -02}
+ {1099364400 -7200 1 -03}
{1108864800 -10800 0 -03}
- {1129431600 -7200 1 -02}
+ {1129431600 -7200 1 -03}
{1140314400 -10800 0 -03}
- {1162695600 -7200 1 -02}
+ {1162695600 -7200 1 -03}
{1172368800 -10800 0 -03}
- {1192330800 -7200 1 -02}
+ {1192330800 -7200 1 -03}
{1203213600 -10800 0 -03}
- {1224385200 -7200 1 -02}
+ {1224385200 -7200 1 -03}
{1234663200 -10800 0 -03}
- {1255834800 -7200 1 -02}
+ {1255834800 -7200 1 -03}
{1266717600 -10800 0 -03}
- {1287284400 -7200 1 -02}
+ {1287284400 -7200 1 -03}
{1298167200 -10800 0 -03}
- {1318734000 -7200 1 -02}
+ {1318734000 -7200 1 -03}
{1330221600 -10800 0 -03}
- {1350788400 -7200 1 -02}
+ {1350788400 -7200 1 -03}
{1361066400 -10800 0 -03}
- {1382238000 -7200 1 -02}
+ {1382238000 -7200 1 -03}
{1392516000 -10800 0 -03}
- {1413687600 -7200 1 -02}
+ {1413687600 -7200 1 -03}
{1424570400 -10800 0 -03}
- {1445137200 -7200 1 -02}
+ {1445137200 -7200 1 -03}
{1456020000 -10800 0 -03}
- {1476586800 -7200 1 -02}
+ {1476586800 -7200 1 -03}
{1487469600 -10800 0 -03}
- {1508036400 -7200 1 -02}
+ {1508036400 -7200 1 -03}
{1518919200 -10800 0 -03}
- {1540090800 -7200 1 -02}
+ {1541300400 -7200 1 -03}
{1550368800 -10800 0 -03}
- {1571540400 -7200 1 -02}
+ {1572750000 -7200 1 -03}
{1581818400 -10800 0 -03}
- {1602990000 -7200 1 -02}
+ {1604199600 -7200 1 -03}
{1613872800 -10800 0 -03}
- {1634439600 -7200 1 -02}
+ {1636254000 -7200 1 -03}
{1645322400 -10800 0 -03}
- {1665889200 -7200 1 -02}
+ {1667703600 -7200 1 -03}
{1677376800 -10800 0 -03}
- {1697338800 -7200 1 -02}
+ {1699153200 -7200 1 -03}
{1708221600 -10800 0 -03}
- {1729393200 -7200 1 -02}
+ {1730602800 -7200 1 -03}
{1739671200 -10800 0 -03}
- {1760842800 -7200 1 -02}
+ {1762052400 -7200 1 -03}
{1771725600 -10800 0 -03}
- {1792292400 -7200 1 -02}
+ {1793502000 -7200 1 -03}
{1803175200 -10800 0 -03}
- {1823742000 -7200 1 -02}
+ {1825556400 -7200 1 -03}
{1834624800 -10800 0 -03}
- {1855191600 -7200 1 -02}
+ {1857006000 -7200 1 -03}
{1866074400 -10800 0 -03}
- {1887246000 -7200 1 -02}
+ {1888455600 -7200 1 -03}
{1897524000 -10800 0 -03}
- {1918695600 -7200 1 -02}
+ {1919905200 -7200 1 -03}
{1928973600 -10800 0 -03}
- {1950145200 -7200 1 -02}
+ {1951354800 -7200 1 -03}
{1960423200 -10800 0 -03}
- {1981594800 -7200 1 -02}
+ {1983409200 -7200 1 -03}
{1992477600 -10800 0 -03}
- {2013044400 -7200 1 -02}
+ {2014858800 -7200 1 -03}
{2024532000 -10800 0 -03}
- {2044494000 -7200 1 -02}
+ {2046308400 -7200 1 -03}
{2055376800 -10800 0 -03}
- {2076548400 -7200 1 -02}
+ {2077758000 -7200 1 -03}
{2086826400 -10800 0 -03}
- {2107998000 -7200 1 -02}
+ {2109207600 -7200 1 -03}
{2118880800 -10800 0 -03}
- {2139447600 -7200 1 -02}
+ {2140657200 -7200 1 -03}
{2150330400 -10800 0 -03}
- {2170897200 -7200 1 -02}
+ {2172711600 -7200 1 -03}
{2181780000 -10800 0 -03}
- {2202346800 -7200 1 -02}
+ {2204161200 -7200 1 -03}
{2213229600 -10800 0 -03}
- {2234401200 -7200 1 -02}
+ {2235610800 -7200 1 -03}
{2244679200 -10800 0 -03}
- {2265850800 -7200 1 -02}
+ {2267060400 -7200 1 -03}
{2276128800 -10800 0 -03}
- {2297300400 -7200 1 -02}
+ {2298510000 -7200 1 -03}
{2307578400 -10800 0 -03}
- {2328750000 -7200 1 -02}
+ {2329959600 -7200 1 -03}
{2339632800 -10800 0 -03}
- {2360199600 -7200 1 -02}
+ {2362014000 -7200 1 -03}
{2371082400 -10800 0 -03}
- {2391649200 -7200 1 -02}
+ {2393463600 -7200 1 -03}
{2402532000 -10800 0 -03}
- {2423703600 -7200 1 -02}
+ {2424913200 -7200 1 -03}
{2433981600 -10800 0 -03}
- {2455153200 -7200 1 -02}
+ {2456362800 -7200 1 -03}
{2465431200 -10800 0 -03}
- {2486602800 -7200 1 -02}
+ {2487812400 -7200 1 -03}
{2497485600 -10800 0 -03}
- {2518052400 -7200 1 -02}
+ {2519866800 -7200 1 -03}
{2528935200 -10800 0 -03}
- {2549502000 -7200 1 -02}
+ {2551316400 -7200 1 -03}
{2560384800 -10800 0 -03}
- {2580951600 -7200 1 -02}
+ {2582766000 -7200 1 -03}
{2591834400 -10800 0 -03}
- {2613006000 -7200 1 -02}
+ {2614215600 -7200 1 -03}
{2623284000 -10800 0 -03}
- {2644455600 -7200 1 -02}
+ {2645665200 -7200 1 -03}
{2654733600 -10800 0 -03}
- {2675905200 -7200 1 -02}
+ {2677114800 -7200 1 -03}
{2686788000 -10800 0 -03}
- {2707354800 -7200 1 -02}
+ {2709169200 -7200 1 -03}
{2718237600 -10800 0 -03}
- {2738804400 -7200 1 -02}
+ {2740618800 -7200 1 -03}
{2749687200 -10800 0 -03}
- {2770858800 -7200 1 -02}
+ {2772068400 -7200 1 -03}
{2781136800 -10800 0 -03}
- {2802308400 -7200 1 -02}
+ {2803518000 -7200 1 -03}
{2812586400 -10800 0 -03}
- {2833758000 -7200 1 -02}
+ {2834967600 -7200 1 -03}
{2844036000 -10800 0 -03}
- {2865207600 -7200 1 -02}
+ {2867022000 -7200 1 -03}
{2876090400 -10800 0 -03}
- {2896657200 -7200 1 -02}
+ {2898471600 -7200 1 -03}
{2907540000 -10800 0 -03}
- {2928106800 -7200 1 -02}
+ {2929921200 -7200 1 -03}
{2938989600 -10800 0 -03}
- {2960161200 -7200 1 -02}
+ {2961370800 -7200 1 -03}
{2970439200 -10800 0 -03}
- {2991610800 -7200 1 -02}
+ {2992820400 -7200 1 -03}
{3001888800 -10800 0 -03}
- {3023060400 -7200 1 -02}
+ {3024270000 -7200 1 -03}
{3033943200 -10800 0 -03}
- {3054510000 -7200 1 -02}
+ {3056324400 -7200 1 -03}
{3065392800 -10800 0 -03}
- {3085959600 -7200 1 -02}
+ {3087774000 -7200 1 -03}
{3096842400 -10800 0 -03}
- {3118014000 -7200 1 -02}
+ {3119223600 -7200 1 -03}
{3128292000 -10800 0 -03}
- {3149463600 -7200 1 -02}
+ {3150673200 -7200 1 -03}
{3159741600 -10800 0 -03}
- {3180913200 -7200 1 -02}
+ {3182122800 -7200 1 -03}
{3191191200 -10800 0 -03}
- {3212362800 -7200 1 -02}
+ {3213572400 -7200 1 -03}
{3223245600 -10800 0 -03}
- {3243812400 -7200 1 -02}
+ {3245626800 -7200 1 -03}
{3254695200 -10800 0 -03}
- {3275262000 -7200 1 -02}
+ {3277076400 -7200 1 -03}
{3286144800 -10800 0 -03}
- {3307316400 -7200 1 -02}
+ {3308526000 -7200 1 -03}
{3317594400 -10800 0 -03}
- {3338766000 -7200 1 -02}
+ {3339975600 -7200 1 -03}
{3349044000 -10800 0 -03}
- {3370215600 -7200 1 -02}
+ {3371425200 -7200 1 -03}
{3381098400 -10800 0 -03}
- {3401665200 -7200 1 -02}
+ {3403479600 -7200 1 -03}
{3412548000 -10800 0 -03}
- {3433114800 -7200 1 -02}
+ {3434929200 -7200 1 -03}
{3443997600 -10800 0 -03}
- {3464564400 -7200 1 -02}
+ {3466378800 -7200 1 -03}
{3475447200 -10800 0 -03}
- {3496618800 -7200 1 -02}
+ {3497828400 -7200 1 -03}
{3506896800 -10800 0 -03}
- {3528068400 -7200 1 -02}
+ {3529278000 -7200 1 -03}
{3538346400 -10800 0 -03}
- {3559518000 -7200 1 -02}
+ {3560727600 -7200 1 -03}
{3570400800 -10800 0 -03}
- {3590967600 -7200 1 -02}
+ {3592782000 -7200 1 -03}
{3601850400 -10800 0 -03}
- {3622417200 -7200 1 -02}
+ {3624231600 -7200 1 -03}
{3633300000 -10800 0 -03}
- {3654471600 -7200 1 -02}
+ {3655681200 -7200 1 -03}
{3664749600 -10800 0 -03}
- {3685921200 -7200 1 -02}
+ {3687130800 -7200 1 -03}
{3696199200 -10800 0 -03}
- {3717370800 -7200 1 -02}
+ {3718580400 -7200 1 -03}
{3727648800 -10800 0 -03}
- {3748820400 -7200 1 -02}
+ {3750634800 -7200 1 -03}
{3759703200 -10800 0 -03}
- {3780270000 -7200 1 -02}
+ {3782084400 -7200 1 -03}
{3791152800 -10800 0 -03}
- {3811719600 -7200 1 -02}
+ {3813534000 -7200 1 -03}
{3822602400 -10800 0 -03}
- {3843774000 -7200 1 -02}
+ {3844983600 -7200 1 -03}
{3854052000 -10800 0 -03}
- {3875223600 -7200 1 -02}
+ {3876433200 -7200 1 -03}
{3885501600 -10800 0 -03}
- {3906673200 -7200 1 -02}
+ {3907882800 -7200 1 -03}
{3917556000 -10800 0 -03}
- {3938122800 -7200 1 -02}
+ {3939937200 -7200 1 -03}
{3949005600 -10800 0 -03}
- {3969572400 -7200 1 -02}
+ {3971386800 -7200 1 -03}
{3980455200 -10800 0 -03}
- {4001626800 -7200 1 -02}
+ {4002836400 -7200 1 -03}
{4011904800 -10800 0 -03}
- {4033076400 -7200 1 -02}
+ {4034286000 -7200 1 -03}
{4043354400 -10800 0 -03}
- {4064526000 -7200 1 -02}
+ {4065735600 -7200 1 -03}
{4074804000 -10800 0 -03}
- {4095975600 -7200 1 -02}
+ {4097185200 -7200 1 -03}
}
diff --git a/tcl8.6/library/tzdata/Antarctica/Casey b/tcl8.6/library/tzdata/Antarctica/Casey
index beb0f9e..aa37480 100644
--- a/tcl8.6/library/tzdata/Antarctica/Casey
+++ b/tcl8.6/library/tzdata/Antarctica/Casey
@@ -8,4 +8,5 @@ set TZData(:Antarctica/Casey) {
{1319738400 39600 0 +11}
{1329843600 28800 0 +08}
{1477065600 39600 0 +11}
+ {1520701200 28800 0 +08}
}
diff --git a/tcl8.6/library/tzdata/Antarctica/Palmer b/tcl8.6/library/tzdata/Antarctica/Palmer
index bb2be4d..f450e3b 100644
--- a/tcl8.6/library/tzdata/Antarctica/Palmer
+++ b/tcl8.6/library/tzdata/Antarctica/Palmer
@@ -4,84 +4,84 @@ set TZData(:Antarctica/Palmer) {
{-9223372036854775808 0 0 -00}
{-157766400 -14400 0 -04}
{-152654400 -14400 0 -04}
- {-132955200 -10800 1 -03}
+ {-132955200 -10800 1 -04}
{-121122000 -14400 0 -04}
- {-101419200 -10800 1 -03}
+ {-101419200 -10800 1 -04}
{-86821200 -14400 0 -04}
- {-71092800 -10800 1 -03}
+ {-71092800 -10800 1 -04}
{-54766800 -14400 0 -04}
- {-39038400 -10800 1 -03}
+ {-39038400 -10800 1 -04}
{-23317200 -14400 0 -04}
{-7588800 -10800 0 -03}
- {128142000 -7200 1 -02}
+ {128142000 -7200 1 -03}
{136605600 -10800 0 -03}
{389070000 -14400 0 -04}
- {403070400 -10800 1 -03}
+ {403070400 -10800 1 -04}
{416372400 -14400 0 -04}
- {434520000 -10800 1 -03}
+ {434520000 -10800 1 -04}
{447822000 -14400 0 -04}
- {466574400 -10800 1 -03}
+ {466574400 -10800 1 -04}
{479271600 -14400 0 -04}
- {498024000 -10800 1 -03}
+ {498024000 -10800 1 -04}
{510721200 -14400 0 -04}
- {529473600 -10800 1 -03}
+ {529473600 -10800 1 -04}
{545194800 -14400 0 -04}
- {560923200 -10800 1 -03}
+ {560923200 -10800 1 -04}
{574225200 -14400 0 -04}
- {592372800 -10800 1 -03}
+ {592372800 -10800 1 -04}
{605674800 -14400 0 -04}
- {624427200 -10800 1 -03}
+ {624427200 -10800 1 -04}
{637124400 -14400 0 -04}
- {653457600 -10800 1 -03}
+ {653457600 -10800 1 -04}
{668574000 -14400 0 -04}
- {687326400 -10800 1 -03}
+ {687326400 -10800 1 -04}
{700628400 -14400 0 -04}
- {718776000 -10800 1 -03}
+ {718776000 -10800 1 -04}
{732078000 -14400 0 -04}
- {750225600 -10800 1 -03}
+ {750225600 -10800 1 -04}
{763527600 -14400 0 -04}
- {781675200 -10800 1 -03}
+ {781675200 -10800 1 -04}
{794977200 -14400 0 -04}
- {813729600 -10800 1 -03}
+ {813729600 -10800 1 -04}
{826426800 -14400 0 -04}
- {845179200 -10800 1 -03}
+ {845179200 -10800 1 -04}
{859690800 -14400 0 -04}
- {876628800 -10800 1 -03}
+ {876628800 -10800 1 -04}
{889930800 -14400 0 -04}
- {906868800 -10800 1 -03}
+ {906868800 -10800 1 -04}
{923194800 -14400 0 -04}
- {939528000 -10800 1 -03}
+ {939528000 -10800 1 -04}
{952830000 -14400 0 -04}
- {971582400 -10800 1 -03}
+ {971582400 -10800 1 -04}
{984279600 -14400 0 -04}
- {1003032000 -10800 1 -03}
+ {1003032000 -10800 1 -04}
{1015729200 -14400 0 -04}
- {1034481600 -10800 1 -03}
+ {1034481600 -10800 1 -04}
{1047178800 -14400 0 -04}
- {1065931200 -10800 1 -03}
+ {1065931200 -10800 1 -04}
{1079233200 -14400 0 -04}
- {1097380800 -10800 1 -03}
+ {1097380800 -10800 1 -04}
{1110682800 -14400 0 -04}
- {1128830400 -10800 1 -03}
+ {1128830400 -10800 1 -04}
{1142132400 -14400 0 -04}
- {1160884800 -10800 1 -03}
+ {1160884800 -10800 1 -04}
{1173582000 -14400 0 -04}
- {1192334400 -10800 1 -03}
+ {1192334400 -10800 1 -04}
{1206846000 -14400 0 -04}
- {1223784000 -10800 1 -03}
+ {1223784000 -10800 1 -04}
{1237086000 -14400 0 -04}
- {1255233600 -10800 1 -03}
+ {1255233600 -10800 1 -04}
{1270350000 -14400 0 -04}
- {1286683200 -10800 1 -03}
+ {1286683200 -10800 1 -04}
{1304823600 -14400 0 -04}
- {1313899200 -10800 1 -03}
+ {1313899200 -10800 1 -04}
{1335668400 -14400 0 -04}
- {1346558400 -10800 1 -03}
+ {1346558400 -10800 1 -04}
{1367118000 -14400 0 -04}
- {1378612800 -10800 1 -03}
+ {1378612800 -10800 1 -04}
{1398567600 -14400 0 -04}
- {1410062400 -10800 1 -03}
+ {1410062400 -10800 1 -04}
{1463281200 -14400 0 -04}
- {1471147200 -10800 1 -03}
+ {1471147200 -10800 1 -04}
{1480820400 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/Asia/Almaty b/tcl8.6/library/tzdata/Asia/Almaty
index 2b83197..f42935d 100644
--- a/tcl8.6/library/tzdata/Asia/Almaty
+++ b/tcl8.6/library/tzdata/Asia/Almaty
@@ -4,54 +4,54 @@ set TZData(:Asia/Almaty) {
{-9223372036854775808 18468 0 LMT}
{-1441170468 18000 0 +05}
{-1247547600 21600 0 +06}
- {354909600 25200 1 +07}
+ {354909600 25200 1 +06}
{370717200 21600 0 +06}
- {386445600 25200 1 +07}
+ {386445600 25200 1 +06}
{402253200 21600 0 +06}
- {417981600 25200 1 +07}
+ {417981600 25200 1 +06}
{433789200 21600 0 +06}
- {449604000 25200 1 +07}
+ {449604000 25200 1 +06}
{465336000 21600 0 +06}
- {481060800 25200 1 +07}
+ {481060800 25200 1 +06}
{496785600 21600 0 +06}
- {512510400 25200 1 +07}
+ {512510400 25200 1 +06}
{528235200 21600 0 +06}
- {543960000 25200 1 +07}
+ {543960000 25200 1 +06}
{559684800 21600 0 +06}
- {575409600 25200 1 +07}
+ {575409600 25200 1 +06}
{591134400 21600 0 +06}
- {606859200 25200 1 +07}
+ {606859200 25200 1 +06}
{622584000 21600 0 +06}
- {638308800 25200 1 +07}
+ {638308800 25200 1 +06}
{654638400 21600 0 +06}
{670363200 18000 0 +05}
- {670366800 21600 1 +06}
+ {670366800 21600 1 +05}
{686091600 18000 0 +05}
{695768400 21600 0 +06}
- {701812800 25200 1 +07}
+ {701812800 25200 1 +06}
{717537600 21600 0 +06}
- {733262400 25200 1 +07}
+ {733262400 25200 1 +06}
{748987200 21600 0 +06}
- {764712000 25200 1 +07}
+ {764712000 25200 1 +06}
{780436800 21600 0 +06}
- {796161600 25200 1 +07}
+ {796161600 25200 1 +06}
{811886400 21600 0 +06}
- {828216000 25200 1 +07}
+ {828216000 25200 1 +06}
{846360000 21600 0 +06}
- {859665600 25200 1 +07}
+ {859665600 25200 1 +06}
{877809600 21600 0 +06}
- {891115200 25200 1 +07}
+ {891115200 25200 1 +06}
{909259200 21600 0 +06}
- {922564800 25200 1 +07}
+ {922564800 25200 1 +06}
{941313600 21600 0 +06}
- {954014400 25200 1 +07}
+ {954014400 25200 1 +06}
{972763200 21600 0 +06}
- {985464000 25200 1 +07}
+ {985464000 25200 1 +06}
{1004212800 21600 0 +06}
- {1017518400 25200 1 +07}
+ {1017518400 25200 1 +06}
{1035662400 21600 0 +06}
- {1048968000 25200 1 +07}
+ {1048968000 25200 1 +06}
{1067112000 21600 0 +06}
- {1080417600 25200 1 +07}
+ {1080417600 25200 1 +06}
{1099166400 21600 0 +06}
}
diff --git a/tcl8.6/library/tzdata/Asia/Aqtau b/tcl8.6/library/tzdata/Asia/Aqtau
index c128b27..41da2ca 100644
--- a/tcl8.6/library/tzdata/Asia/Aqtau
+++ b/tcl8.6/library/tzdata/Asia/Aqtau
@@ -6,53 +6,53 @@ set TZData(:Asia/Aqtau) {
{-1247544000 18000 0 +05}
{370724400 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
- {701816400 21600 1 +06}
+ {701816400 21600 1 +05}
{717541200 18000 0 +05}
- {733266000 21600 1 +06}
+ {733266000 21600 1 +05}
{748990800 18000 0 +05}
- {764715600 21600 1 +06}
- {780440400 18000 0 +05}
+ {764715600 21600 1 +05}
+ {780440400 18000 0 +04}
{780444000 14400 0 +04}
- {796168800 18000 1 +05}
+ {796168800 18000 1 +04}
{811893600 14400 0 +04}
- {828223200 18000 1 +05}
+ {828223200 18000 1 +04}
{846367200 14400 0 +04}
- {859672800 18000 1 +05}
+ {859672800 18000 1 +04}
{877816800 14400 0 +04}
- {891122400 18000 1 +05}
+ {891122400 18000 1 +04}
{909266400 14400 0 +04}
- {922572000 18000 1 +05}
+ {922572000 18000 1 +04}
{941320800 14400 0 +04}
- {954021600 18000 1 +05}
+ {954021600 18000 1 +04}
{972770400 14400 0 +04}
- {985471200 18000 1 +05}
+ {985471200 18000 1 +04}
{1004220000 14400 0 +04}
- {1017525600 18000 1 +05}
+ {1017525600 18000 1 +04}
{1035669600 14400 0 +04}
- {1048975200 18000 1 +05}
+ {1048975200 18000 1 +04}
{1067119200 14400 0 +04}
- {1080424800 18000 1 +05}
+ {1080424800 18000 1 +04}
{1099173600 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Aqtobe b/tcl8.6/library/tzdata/Asia/Aqtobe
index 55ef556..2316e68 100644
--- a/tcl8.6/library/tzdata/Asia/Aqtobe
+++ b/tcl8.6/library/tzdata/Asia/Aqtobe
@@ -7,52 +7,52 @@ set TZData(:Asia/Aqtobe) {
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
- {701816400 21600 1 +06}
+ {701816400 21600 1 +05}
{717541200 18000 0 +05}
- {733266000 21600 1 +06}
+ {733266000 21600 1 +05}
{748990800 18000 0 +05}
- {764715600 21600 1 +06}
+ {764715600 21600 1 +05}
{780440400 18000 0 +05}
- {796165200 21600 1 +06}
+ {796165200 21600 1 +05}
{811890000 18000 0 +05}
- {828219600 21600 1 +06}
+ {828219600 21600 1 +05}
{846363600 18000 0 +05}
- {859669200 21600 1 +06}
+ {859669200 21600 1 +05}
{877813200 18000 0 +05}
- {891118800 21600 1 +06}
+ {891118800 21600 1 +05}
{909262800 18000 0 +05}
- {922568400 21600 1 +06}
+ {922568400 21600 1 +05}
{941317200 18000 0 +05}
- {954018000 21600 1 +06}
+ {954018000 21600 1 +05}
{972766800 18000 0 +05}
- {985467600 21600 1 +06}
+ {985467600 21600 1 +05}
{1004216400 18000 0 +05}
- {1017522000 21600 1 +06}
+ {1017522000 21600 1 +05}
{1035666000 18000 0 +05}
- {1048971600 21600 1 +06}
+ {1048971600 21600 1 +05}
{1067115600 18000 0 +05}
- {1080421200 21600 1 +06}
+ {1080421200 21600 1 +05}
{1099170000 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Ashgabat b/tcl8.6/library/tzdata/Asia/Ashgabat
index fa6a619..feb7725 100644
--- a/tcl8.6/library/tzdata/Asia/Ashgabat
+++ b/tcl8.6/library/tzdata/Asia/Ashgabat
@@ -4,28 +4,28 @@ set TZData(:Asia/Ashgabat) {
{-9223372036854775808 14012 0 LMT}
{-1441166012 14400 0 +04}
{-1247544000 18000 0 +05}
- {354913200 21600 1 +06}
+ {354913200 21600 1 +05}
{370720800 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Atyrau b/tcl8.6/library/tzdata/Asia/Atyrau
index c31ff11..b6d8253 100644
--- a/tcl8.6/library/tzdata/Asia/Atyrau
+++ b/tcl8.6/library/tzdata/Asia/Atyrau
@@ -6,53 +6,53 @@ set TZData(:Asia/Atyrau) {
{-1247540400 18000 0 +05}
{370724400 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{686095200 14400 0 +04}
{695772000 18000 0 +05}
- {701816400 21600 1 +06}
+ {701816400 21600 1 +05}
{717541200 18000 0 +05}
- {733266000 21600 1 +06}
+ {733266000 21600 1 +05}
{748990800 18000 0 +05}
- {764715600 21600 1 +06}
+ {764715600 21600 1 +05}
{780440400 18000 0 +05}
- {796165200 21600 1 +06}
+ {796165200 21600 1 +05}
{811890000 18000 0 +05}
- {828219600 21600 1 +06}
+ {828219600 21600 1 +05}
{846363600 18000 0 +05}
- {859669200 21600 1 +06}
+ {859669200 21600 1 +05}
{877813200 18000 0 +05}
- {891118800 21600 1 +06}
+ {891118800 21600 1 +05}
{909262800 18000 0 +05}
{922568400 14400 0 +04}
- {922572000 18000 1 +05}
+ {922572000 18000 1 +04}
{941320800 14400 0 +04}
- {954021600 18000 1 +05}
+ {954021600 18000 1 +04}
{972770400 14400 0 +04}
- {985471200 18000 1 +05}
+ {985471200 18000 1 +04}
{1004220000 14400 0 +04}
- {1017525600 18000 1 +05}
+ {1017525600 18000 1 +04}
{1035669600 14400 0 +04}
- {1048975200 18000 1 +05}
+ {1048975200 18000 1 +04}
{1067119200 14400 0 +04}
- {1080424800 18000 1 +05}
+ {1080424800 18000 1 +04}
{1099173600 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Baghdad b/tcl8.6/library/tzdata/Asia/Baghdad
index 623e310..c76a6a1 100644
--- a/tcl8.6/library/tzdata/Asia/Baghdad
+++ b/tcl8.6/library/tzdata/Asia/Baghdad
@@ -4,56 +4,56 @@ set TZData(:Asia/Baghdad) {
{-9223372036854775808 10660 0 LMT}
{-2524532260 10656 0 BMT}
{-1641005856 10800 0 +03}
- {389048400 14400 0 +04}
- {402264000 10800 0 +04}
- {417906000 14400 1 +04}
- {433800000 10800 0 +04}
- {449614800 14400 1 +04}
- {465422400 10800 0 +04}
- {481150800 14400 1 +04}
- {496792800 10800 0 +04}
- {512517600 14400 1 +04}
- {528242400 10800 0 +04}
- {543967200 14400 1 +04}
- {559692000 10800 0 +04}
- {575416800 14400 1 +04}
- {591141600 10800 0 +04}
- {606866400 14400 1 +04}
- {622591200 10800 0 +04}
- {638316000 14400 1 +04}
- {654645600 10800 0 +04}
- {670464000 14400 1 +04}
- {686275200 10800 0 +04}
- {702086400 14400 1 +04}
- {717897600 10800 0 +04}
- {733622400 14400 1 +04}
- {749433600 10800 0 +04}
- {765158400 14400 1 +04}
- {780969600 10800 0 +04}
- {796694400 14400 1 +04}
- {812505600 10800 0 +04}
- {828316800 14400 1 +04}
- {844128000 10800 0 +04}
- {859852800 14400 1 +04}
- {875664000 10800 0 +04}
- {891388800 14400 1 +04}
- {907200000 10800 0 +04}
- {922924800 14400 1 +04}
- {938736000 10800 0 +04}
- {954547200 14400 1 +04}
- {970358400 10800 0 +04}
- {986083200 14400 1 +04}
- {1001894400 10800 0 +04}
- {1017619200 14400 1 +04}
- {1033430400 10800 0 +04}
- {1049155200 14400 1 +04}
- {1064966400 10800 0 +04}
- {1080777600 14400 1 +04}
- {1096588800 10800 0 +04}
- {1112313600 14400 1 +04}
- {1128124800 10800 0 +04}
- {1143849600 14400 1 +04}
- {1159660800 10800 0 +04}
- {1175385600 14400 1 +04}
- {1191196800 10800 0 +04}
+ {389048400 14400 0 +03}
+ {402264000 10800 0 +03}
+ {417906000 14400 1 +03}
+ {433800000 10800 0 +03}
+ {449614800 14400 1 +03}
+ {465422400 10800 0 +03}
+ {481150800 14400 1 +03}
+ {496792800 10800 0 +03}
+ {512517600 14400 1 +03}
+ {528242400 10800 0 +03}
+ {543967200 14400 1 +03}
+ {559692000 10800 0 +03}
+ {575416800 14400 1 +03}
+ {591141600 10800 0 +03}
+ {606866400 14400 1 +03}
+ {622591200 10800 0 +03}
+ {638316000 14400 1 +03}
+ {654645600 10800 0 +03}
+ {670464000 14400 1 +03}
+ {686275200 10800 0 +03}
+ {702086400 14400 1 +03}
+ {717897600 10800 0 +03}
+ {733622400 14400 1 +03}
+ {749433600 10800 0 +03}
+ {765158400 14400 1 +03}
+ {780969600 10800 0 +03}
+ {796694400 14400 1 +03}
+ {812505600 10800 0 +03}
+ {828316800 14400 1 +03}
+ {844128000 10800 0 +03}
+ {859852800 14400 1 +03}
+ {875664000 10800 0 +03}
+ {891388800 14400 1 +03}
+ {907200000 10800 0 +03}
+ {922924800 14400 1 +03}
+ {938736000 10800 0 +03}
+ {954547200 14400 1 +03}
+ {970358400 10800 0 +03}
+ {986083200 14400 1 +03}
+ {1001894400 10800 0 +03}
+ {1017619200 14400 1 +03}
+ {1033430400 10800 0 +03}
+ {1049155200 14400 1 +03}
+ {1064966400 10800 0 +03}
+ {1080777600 14400 1 +03}
+ {1096588800 10800 0 +03}
+ {1112313600 14400 1 +03}
+ {1128124800 10800 0 +03}
+ {1143849600 14400 1 +03}
+ {1159660800 10800 0 +03}
+ {1175385600 14400 1 +03}
+ {1191196800 10800 0 +03}
}
diff --git a/tcl8.6/library/tzdata/Asia/Baku b/tcl8.6/library/tzdata/Asia/Baku
index f945b89..03dee19 100644
--- a/tcl8.6/library/tzdata/Asia/Baku
+++ b/tcl8.6/library/tzdata/Asia/Baku
@@ -4,71 +4,71 @@ set TZData(:Asia/Baku) {
{-9223372036854775808 11964 0 LMT}
{-1441163964 10800 0 +03}
{-405140400 14400 0 +04}
- {354916800 18000 1 +05}
+ {354916800 18000 1 +04}
{370724400 14400 0 +04}
- {386452800 18000 1 +05}
+ {386452800 18000 1 +04}
{402260400 14400 0 +04}
- {417988800 18000 1 +05}
+ {417988800 18000 1 +04}
{433796400 14400 0 +04}
- {449611200 18000 1 +05}
+ {449611200 18000 1 +04}
{465343200 14400 0 +04}
- {481068000 18000 1 +05}
+ {481068000 18000 1 +04}
{496792800 14400 0 +04}
- {512517600 18000 1 +05}
+ {512517600 18000 1 +04}
{528242400 14400 0 +04}
- {543967200 18000 1 +05}
+ {543967200 18000 1 +04}
{559692000 14400 0 +04}
- {575416800 18000 1 +05}
+ {575416800 18000 1 +04}
{591141600 14400 0 +04}
- {606866400 18000 1 +05}
+ {606866400 18000 1 +04}
{622591200 14400 0 +04}
- {638316000 18000 1 +05}
+ {638316000 18000 1 +04}
{654645600 14400 0 +04}
{670370400 10800 0 +03}
- {670374000 14400 1 +04}
+ {670374000 14400 1 +03}
{686098800 10800 0 +03}
- {701823600 14400 1 +04}
+ {701823600 14400 1 +03}
{717548400 14400 0 +04}
{820440000 14400 0 +04}
{828234000 18000 1 +05}
{846378000 14400 0 +04}
{852062400 14400 0 +04}
- {859680000 18000 1 +05}
+ {859680000 18000 1 +04}
{877824000 14400 0 +04}
- {891129600 18000 1 +05}
+ {891129600 18000 1 +04}
{909273600 14400 0 +04}
- {922579200 18000 1 +05}
+ {922579200 18000 1 +04}
{941328000 14400 0 +04}
- {954028800 18000 1 +05}
+ {954028800 18000 1 +04}
{972777600 14400 0 +04}
- {985478400 18000 1 +05}
+ {985478400 18000 1 +04}
{1004227200 14400 0 +04}
- {1017532800 18000 1 +05}
+ {1017532800 18000 1 +04}
{1035676800 14400 0 +04}
- {1048982400 18000 1 +05}
+ {1048982400 18000 1 +04}
{1067126400 14400 0 +04}
- {1080432000 18000 1 +05}
+ {1080432000 18000 1 +04}
{1099180800 14400 0 +04}
- {1111881600 18000 1 +05}
+ {1111881600 18000 1 +04}
{1130630400 14400 0 +04}
- {1143331200 18000 1 +05}
+ {1143331200 18000 1 +04}
{1162080000 14400 0 +04}
- {1174780800 18000 1 +05}
+ {1174780800 18000 1 +04}
{1193529600 14400 0 +04}
- {1206835200 18000 1 +05}
+ {1206835200 18000 1 +04}
{1224979200 14400 0 +04}
- {1238284800 18000 1 +05}
+ {1238284800 18000 1 +04}
{1256428800 14400 0 +04}
- {1269734400 18000 1 +05}
+ {1269734400 18000 1 +04}
{1288483200 14400 0 +04}
- {1301184000 18000 1 +05}
+ {1301184000 18000 1 +04}
{1319932800 14400 0 +04}
- {1332633600 18000 1 +05}
+ {1332633600 18000 1 +04}
{1351382400 14400 0 +04}
- {1364688000 18000 1 +05}
+ {1364688000 18000 1 +04}
{1382832000 14400 0 +04}
- {1396137600 18000 1 +05}
+ {1396137600 18000 1 +04}
{1414281600 14400 0 +04}
- {1427587200 18000 1 +05}
+ {1427587200 18000 1 +04}
{1445731200 14400 0 +04}
}
diff --git a/tcl8.6/library/tzdata/Asia/Bishkek b/tcl8.6/library/tzdata/Asia/Bishkek
index a02d789..bc4cbdd 100644
--- a/tcl8.6/library/tzdata/Asia/Bishkek
+++ b/tcl8.6/library/tzdata/Asia/Bishkek
@@ -4,55 +4,55 @@ set TZData(:Asia/Bishkek) {
{-9223372036854775808 17904 0 LMT}
{-1441169904 18000 0 +05}
{-1247547600 21600 0 +06}
- {354909600 25200 1 +07}
+ {354909600 25200 1 +06}
{370717200 21600 0 +06}
- {386445600 25200 1 +07}
+ {386445600 25200 1 +06}
{402253200 21600 0 +06}
- {417981600 25200 1 +07}
+ {417981600 25200 1 +06}
{433789200 21600 0 +06}
- {449604000 25200 1 +07}
+ {449604000 25200 1 +06}
{465336000 21600 0 +06}
- {481060800 25200 1 +07}
+ {481060800 25200 1 +06}
{496785600 21600 0 +06}
- {512510400 25200 1 +07}
+ {512510400 25200 1 +06}
{528235200 21600 0 +06}
- {543960000 25200 1 +07}
+ {543960000 25200 1 +06}
{559684800 21600 0 +06}
- {575409600 25200 1 +07}
+ {575409600 25200 1 +06}
{591134400 21600 0 +06}
- {606859200 25200 1 +07}
+ {606859200 25200 1 +06}
{622584000 21600 0 +06}
- {638308800 25200 1 +07}
+ {638308800 25200 1 +06}
{654638400 21600 0 +06}
{670363200 18000 0 +05}
- {670366800 21600 1 +06}
+ {670366800 21600 1 +05}
{683586000 18000 0 +05}
- {703018800 21600 1 +06}
+ {703018800 21600 1 +05}
{717530400 18000 0 +05}
- {734468400 21600 1 +06}
+ {734468400 21600 1 +05}
{748980000 18000 0 +05}
- {765918000 21600 1 +06}
+ {765918000 21600 1 +05}
{780429600 18000 0 +05}
- {797367600 21600 1 +06}
+ {797367600 21600 1 +05}
{811879200 18000 0 +05}
- {828817200 21600 1 +06}
+ {828817200 21600 1 +05}
{843933600 18000 0 +05}
- {859671000 21600 1 +06}
+ {859671000 21600 1 +05}
{877811400 18000 0 +05}
- {891120600 21600 1 +06}
+ {891120600 21600 1 +05}
{909261000 18000 0 +05}
- {922570200 21600 1 +06}
+ {922570200 21600 1 +05}
{941315400 18000 0 +05}
- {954019800 21600 1 +06}
+ {954019800 21600 1 +05}
{972765000 18000 0 +05}
- {985469400 21600 1 +06}
+ {985469400 21600 1 +05}
{1004214600 18000 0 +05}
- {1017523800 21600 1 +06}
+ {1017523800 21600 1 +05}
{1035664200 18000 0 +05}
- {1048973400 21600 1 +06}
+ {1048973400 21600 1 +05}
{1067113800 18000 0 +05}
- {1080423000 21600 1 +06}
+ {1080423000 21600 1 +05}
{1099168200 18000 0 +05}
- {1111872600 21600 1 +06}
+ {1111872600 21600 1 +05}
{1123783200 21600 0 +06}
}
diff --git a/tcl8.6/library/tzdata/Asia/Choibalsan b/tcl8.6/library/tzdata/Asia/Choibalsan
index 3db65de..b072c76 100644
--- a/tcl8.6/library/tzdata/Asia/Choibalsan
+++ b/tcl8.6/library/tzdata/Asia/Choibalsan
@@ -4,53 +4,53 @@ set TZData(:Asia/Choibalsan) {
{-9223372036854775808 27480 0 LMT}
{-2032933080 25200 0 +07}
{252435600 28800 0 +08}
- {417974400 36000 0 +10}
+ {417974400 36000 0 +09}
{433778400 32400 0 +09}
- {449593200 36000 1 +10}
+ {449593200 36000 1 +09}
{465314400 32400 0 +09}
- {481042800 36000 1 +10}
+ {481042800 36000 1 +09}
{496764000 32400 0 +09}
- {512492400 36000 1 +10}
+ {512492400 36000 1 +09}
{528213600 32400 0 +09}
- {543942000 36000 1 +10}
+ {543942000 36000 1 +09}
{559663200 32400 0 +09}
- {575391600 36000 1 +10}
+ {575391600 36000 1 +09}
{591112800 32400 0 +09}
- {606841200 36000 1 +10}
+ {606841200 36000 1 +09}
{622562400 32400 0 +09}
- {638290800 36000 1 +10}
+ {638290800 36000 1 +09}
{654616800 32400 0 +09}
- {670345200 36000 1 +10}
+ {670345200 36000 1 +09}
{686066400 32400 0 +09}
- {701794800 36000 1 +10}
+ {701794800 36000 1 +09}
{717516000 32400 0 +09}
- {733244400 36000 1 +10}
+ {733244400 36000 1 +09}
{748965600 32400 0 +09}
- {764694000 36000 1 +10}
+ {764694000 36000 1 +09}
{780415200 32400 0 +09}
- {796143600 36000 1 +10}
+ {796143600 36000 1 +09}
{811864800 32400 0 +09}
- {828198000 36000 1 +10}
+ {828198000 36000 1 +09}
{843919200 32400 0 +09}
- {859647600 36000 1 +10}
+ {859647600 36000 1 +09}
{875368800 32400 0 +09}
- {891097200 36000 1 +10}
+ {891097200 36000 1 +09}
{906818400 32400 0 +09}
- {988390800 36000 1 +10}
+ {988390800 36000 1 +09}
{1001692800 32400 0 +09}
- {1017421200 36000 1 +10}
+ {1017421200 36000 1 +09}
{1033142400 32400 0 +09}
- {1048870800 36000 1 +10}
+ {1048870800 36000 1 +09}
{1064592000 32400 0 +09}
- {1080320400 36000 1 +10}
+ {1080320400 36000 1 +09}
{1096041600 32400 0 +09}
- {1111770000 36000 1 +10}
+ {1111770000 36000 1 +09}
{1127491200 32400 0 +09}
- {1143219600 36000 1 +10}
+ {1143219600 36000 1 +09}
{1159545600 32400 0 +09}
{1206889200 28800 0 +08}
- {1427479200 32400 1 +09}
+ {1427479200 32400 1 +08}
{1443193200 28800 0 +08}
- {1458928800 32400 1 +09}
+ {1458928800 32400 1 +08}
{1474642800 28800 0 +08}
}
diff --git a/tcl8.6/library/tzdata/Asia/Dhaka b/tcl8.6/library/tzdata/Asia/Dhaka
index 0dc3987..c044095 100644
--- a/tcl8.6/library/tzdata/Asia/Dhaka
+++ b/tcl8.6/library/tzdata/Asia/Dhaka
@@ -8,6 +8,6 @@ set TZData(:Asia/Dhaka) {
{-862637400 23400 0 +0630}
{-576138600 21600 0 +06}
{1230746400 21600 0 +06}
- {1245430800 25200 1 +07}
+ {1245430800 25200 1 +06}
{1262278800 21600 0 +06}
}
diff --git a/tcl8.6/library/tzdata/Asia/Dushanbe b/tcl8.6/library/tzdata/Asia/Dushanbe
index e9ed132..fe82ce7 100644
--- a/tcl8.6/library/tzdata/Asia/Dushanbe
+++ b/tcl8.6/library/tzdata/Asia/Dushanbe
@@ -4,25 +4,25 @@ set TZData(:Asia/Dushanbe) {
{-9223372036854775808 16512 0 LMT}
{-1441168512 18000 0 +05}
{-1247547600 21600 0 +06}
- {354909600 25200 1 +07}
+ {354909600 25200 1 +06}
{370717200 21600 0 +06}
- {386445600 25200 1 +07}
+ {386445600 25200 1 +06}
{402253200 21600 0 +06}
- {417981600 25200 1 +07}
+ {417981600 25200 1 +06}
{433789200 21600 0 +06}
- {449604000 25200 1 +07}
+ {449604000 25200 1 +06}
{465336000 21600 0 +06}
- {481060800 25200 1 +07}
+ {481060800 25200 1 +06}
{496785600 21600 0 +06}
- {512510400 25200 1 +07}
+ {512510400 25200 1 +06}
{528235200 21600 0 +06}
- {543960000 25200 1 +07}
+ {543960000 25200 1 +06}
{559684800 21600 0 +06}
- {575409600 25200 1 +07}
+ {575409600 25200 1 +06}
{591134400 21600 0 +06}
- {606859200 25200 1 +07}
+ {606859200 25200 1 +06}
{622584000 21600 0 +06}
- {638308800 25200 1 +07}
+ {638308800 25200 1 +06}
{654638400 21600 0 +06}
{670363200 21600 1 +06}
{684363600 18000 0 +05}
diff --git a/tcl8.6/library/tzdata/Asia/Gaza b/tcl8.6/library/tzdata/Asia/Gaza
index 1149d51..85b9f67 100644
--- a/tcl8.6/library/tzdata/Asia/Gaza
+++ b/tcl8.6/library/tzdata/Asia/Gaza
@@ -111,9 +111,9 @@ set TZData(:Asia/Gaza) {
{1477692000 7200 0 EET}
{1490396400 10800 1 EEST}
{1509141600 7200 0 EET}
- {1522450800 10800 1 EEST}
+ {1521846000 10800 1 EEST}
{1540591200 7200 0 EET}
- {1553900400 10800 1 EEST}
+ {1553295600 10800 1 EEST}
{1572040800 7200 0 EET}
{1585350000 10800 1 EEST}
{1604095200 7200 0 EET}
@@ -123,9 +123,9 @@ set TZData(:Asia/Gaza) {
{1666994400 7200 0 EET}
{1679698800 10800 1 EEST}
{1698444000 7200 0 EET}
- {1711753200 10800 1 EEST}
+ {1711148400 10800 1 EEST}
{1729893600 7200 0 EET}
- {1743202800 10800 1 EEST}
+ {1742598000 10800 1 EEST}
{1761343200 7200 0 EET}
{1774652400 10800 1 EEST}
{1793397600 7200 0 EET}
@@ -133,11 +133,11 @@ set TZData(:Asia/Gaza) {
{1824847200 7200 0 EET}
{1837551600 10800 1 EEST}
{1856296800 7200 0 EET}
- {1869606000 10800 1 EEST}
+ {1869001200 10800 1 EEST}
{1887746400 7200 0 EET}
- {1901055600 10800 1 EEST}
+ {1900450800 10800 1 EEST}
{1919196000 7200 0 EET}
- {1932505200 10800 1 EEST}
+ {1931900400 10800 1 EEST}
{1950645600 7200 0 EET}
{1963954800 10800 1 EEST}
{1982700000 7200 0 EET}
@@ -145,9 +145,9 @@ set TZData(:Asia/Gaza) {
{2014149600 7200 0 EET}
{2026854000 10800 1 EEST}
{2045599200 7200 0 EET}
- {2058908400 10800 1 EEST}
+ {2058303600 10800 1 EEST}
{2077048800 7200 0 EET}
- {2090358000 10800 1 EEST}
+ {2089753200 10800 1 EEST}
{2108498400 7200 0 EET}
{2121807600 10800 1 EEST}
{2140552800 7200 0 EET}
@@ -155,11 +155,11 @@ set TZData(:Asia/Gaza) {
{2172002400 7200 0 EET}
{2184706800 10800 1 EEST}
{2203452000 7200 0 EET}
- {2216761200 10800 1 EEST}
+ {2216156400 10800 1 EEST}
{2234901600 7200 0 EET}
- {2248210800 10800 1 EEST}
+ {2247606000 10800 1 EEST}
{2266351200 7200 0 EET}
- {2279660400 10800 1 EEST}
+ {2279055600 10800 1 EEST}
{2297800800 7200 0 EET}
{2311110000 10800 1 EEST}
{2329855200 7200 0 EET}
@@ -167,9 +167,9 @@ set TZData(:Asia/Gaza) {
{2361304800 7200 0 EET}
{2374009200 10800 1 EEST}
{2392754400 7200 0 EET}
- {2406063600 10800 1 EEST}
+ {2405458800 10800 1 EEST}
{2424204000 7200 0 EET}
- {2437513200 10800 1 EEST}
+ {2436908400 10800 1 EEST}
{2455653600 7200 0 EET}
{2468962800 10800 1 EEST}
{2487708000 7200 0 EET}
@@ -179,9 +179,9 @@ set TZData(:Asia/Gaza) {
{2550607200 7200 0 EET}
{2563311600 10800 1 EEST}
{2582056800 7200 0 EET}
- {2595366000 10800 1 EEST}
+ {2594761200 10800 1 EEST}
{2613506400 7200 0 EET}
- {2626815600 10800 1 EEST}
+ {2626210800 10800 1 EEST}
{2644956000 7200 0 EET}
{2658265200 10800 1 EEST}
{2677010400 7200 0 EET}
@@ -189,11 +189,11 @@ set TZData(:Asia/Gaza) {
{2708460000 7200 0 EET}
{2721164400 10800 1 EEST}
{2739909600 7200 0 EET}
- {2753218800 10800 1 EEST}
+ {2752614000 10800 1 EEST}
{2771359200 7200 0 EET}
- {2784668400 10800 1 EEST}
+ {2784063600 10800 1 EEST}
{2802808800 7200 0 EET}
- {2816118000 10800 1 EEST}
+ {2815513200 10800 1 EEST}
{2834258400 7200 0 EET}
{2847567600 10800 1 EEST}
{2866312800 7200 0 EET}
@@ -201,9 +201,9 @@ set TZData(:Asia/Gaza) {
{2897762400 7200 0 EET}
{2910466800 10800 1 EEST}
{2929212000 7200 0 EET}
- {2942521200 10800 1 EEST}
+ {2941916400 10800 1 EEST}
{2960661600 7200 0 EET}
- {2973970800 10800 1 EEST}
+ {2973366000 10800 1 EEST}
{2992111200 7200 0 EET}
{3005420400 10800 1 EEST}
{3024165600 7200 0 EET}
@@ -211,11 +211,11 @@ set TZData(:Asia/Gaza) {
{3055615200 7200 0 EET}
{3068319600 10800 1 EEST}
{3087064800 7200 0 EET}
- {3100374000 10800 1 EEST}
+ {3099769200 10800 1 EEST}
{3118514400 7200 0 EET}
- {3131823600 10800 1 EEST}
+ {3131218800 10800 1 EEST}
{3149964000 7200 0 EET}
- {3163273200 10800 1 EEST}
+ {3162668400 10800 1 EEST}
{3181413600 7200 0 EET}
{3194722800 10800 1 EEST}
{3213468000 7200 0 EET}
@@ -223,9 +223,9 @@ set TZData(:Asia/Gaza) {
{3244917600 7200 0 EET}
{3257622000 10800 1 EEST}
{3276367200 7200 0 EET}
- {3289676400 10800 1 EEST}
+ {3289071600 10800 1 EEST}
{3307816800 7200 0 EET}
- {3321126000 10800 1 EEST}
+ {3320521200 10800 1 EEST}
{3339266400 7200 0 EET}
{3352575600 10800 1 EEST}
{3371320800 7200 0 EET}
@@ -235,9 +235,9 @@ set TZData(:Asia/Gaza) {
{3434220000 7200 0 EET}
{3446924400 10800 1 EEST}
{3465669600 7200 0 EET}
- {3478978800 10800 1 EEST}
+ {3478374000 10800 1 EEST}
{3497119200 7200 0 EET}
- {3510428400 10800 1 EEST}
+ {3509823600 10800 1 EEST}
{3528568800 7200 0 EET}
{3541878000 10800 1 EEST}
{3560623200 7200 0 EET}
@@ -245,11 +245,11 @@ set TZData(:Asia/Gaza) {
{3592072800 7200 0 EET}
{3604777200 10800 1 EEST}
{3623522400 7200 0 EET}
- {3636831600 10800 1 EEST}
+ {3636226800 10800 1 EEST}
{3654972000 7200 0 EET}
- {3668281200 10800 1 EEST}
+ {3667676400 10800 1 EEST}
{3686421600 7200 0 EET}
- {3699730800 10800 1 EEST}
+ {3699126000 10800 1 EEST}
{3717871200 7200 0 EET}
{3731180400 10800 1 EEST}
{3749925600 7200 0 EET}
@@ -257,9 +257,9 @@ set TZData(:Asia/Gaza) {
{3781375200 7200 0 EET}
{3794079600 10800 1 EEST}
{3812824800 7200 0 EET}
- {3826134000 10800 1 EEST}
+ {3825529200 10800 1 EEST}
{3844274400 7200 0 EET}
- {3857583600 10800 1 EEST}
+ {3856978800 10800 1 EEST}
{3875724000 7200 0 EET}
{3889033200 10800 1 EEST}
{3907778400 7200 0 EET}
@@ -267,11 +267,11 @@ set TZData(:Asia/Gaza) {
{3939228000 7200 0 EET}
{3951932400 10800 1 EEST}
{3970677600 7200 0 EET}
- {3983986800 10800 1 EEST}
+ {3983382000 10800 1 EEST}
{4002127200 7200 0 EET}
- {4015436400 10800 1 EEST}
+ {4014831600 10800 1 EEST}
{4033576800 7200 0 EET}
- {4046886000 10800 1 EEST}
+ {4046281200 10800 1 EEST}
{4065026400 7200 0 EET}
{4078335600 10800 1 EEST}
{4097080800 7200 0 EET}
diff --git a/tcl8.6/library/tzdata/Asia/Hebron b/tcl8.6/library/tzdata/Asia/Hebron
index 5d312b8..c0f5447 100644
--- a/tcl8.6/library/tzdata/Asia/Hebron
+++ b/tcl8.6/library/tzdata/Asia/Hebron
@@ -110,9 +110,9 @@ set TZData(:Asia/Hebron) {
{1477692000 7200 0 EET}
{1490396400 10800 1 EEST}
{1509141600 7200 0 EET}
- {1522450800 10800 1 EEST}
+ {1521846000 10800 1 EEST}
{1540591200 7200 0 EET}
- {1553900400 10800 1 EEST}
+ {1553295600 10800 1 EEST}
{1572040800 7200 0 EET}
{1585350000 10800 1 EEST}
{1604095200 7200 0 EET}
@@ -122,9 +122,9 @@ set TZData(:Asia/Hebron) {
{1666994400 7200 0 EET}
{1679698800 10800 1 EEST}
{1698444000 7200 0 EET}
- {1711753200 10800 1 EEST}
+ {1711148400 10800 1 EEST}
{1729893600 7200 0 EET}
- {1743202800 10800 1 EEST}
+ {1742598000 10800 1 EEST}
{1761343200 7200 0 EET}
{1774652400 10800 1 EEST}
{1793397600 7200 0 EET}
@@ -132,11 +132,11 @@ set TZData(:Asia/Hebron) {
{1824847200 7200 0 EET}
{1837551600 10800 1 EEST}
{1856296800 7200 0 EET}
- {1869606000 10800 1 EEST}
+ {1869001200 10800 1 EEST}
{1887746400 7200 0 EET}
- {1901055600 10800 1 EEST}
+ {1900450800 10800 1 EEST}
{1919196000 7200 0 EET}
- {1932505200 10800 1 EEST}
+ {1931900400 10800 1 EEST}
{1950645600 7200 0 EET}
{1963954800 10800 1 EEST}
{1982700000 7200 0 EET}
@@ -144,9 +144,9 @@ set TZData(:Asia/Hebron) {
{2014149600 7200 0 EET}
{2026854000 10800 1 EEST}
{2045599200 7200 0 EET}
- {2058908400 10800 1 EEST}
+ {2058303600 10800 1 EEST}
{2077048800 7200 0 EET}
- {2090358000 10800 1 EEST}
+ {2089753200 10800 1 EEST}
{2108498400 7200 0 EET}
{2121807600 10800 1 EEST}
{2140552800 7200 0 EET}
@@ -154,11 +154,11 @@ set TZData(:Asia/Hebron) {
{2172002400 7200 0 EET}
{2184706800 10800 1 EEST}
{2203452000 7200 0 EET}
- {2216761200 10800 1 EEST}
+ {2216156400 10800 1 EEST}
{2234901600 7200 0 EET}
- {2248210800 10800 1 EEST}
+ {2247606000 10800 1 EEST}
{2266351200 7200 0 EET}
- {2279660400 10800 1 EEST}
+ {2279055600 10800 1 EEST}
{2297800800 7200 0 EET}
{2311110000 10800 1 EEST}
{2329855200 7200 0 EET}
@@ -166,9 +166,9 @@ set TZData(:Asia/Hebron) {
{2361304800 7200 0 EET}
{2374009200 10800 1 EEST}
{2392754400 7200 0 EET}
- {2406063600 10800 1 EEST}
+ {2405458800 10800 1 EEST}
{2424204000 7200 0 EET}
- {2437513200 10800 1 EEST}
+ {2436908400 10800 1 EEST}
{2455653600 7200 0 EET}
{2468962800 10800 1 EEST}
{2487708000 7200 0 EET}
@@ -178,9 +178,9 @@ set TZData(:Asia/Hebron) {
{2550607200 7200 0 EET}
{2563311600 10800 1 EEST}
{2582056800 7200 0 EET}
- {2595366000 10800 1 EEST}
+ {2594761200 10800 1 EEST}
{2613506400 7200 0 EET}
- {2626815600 10800 1 EEST}
+ {2626210800 10800 1 EEST}
{2644956000 7200 0 EET}
{2658265200 10800 1 EEST}
{2677010400 7200 0 EET}
@@ -188,11 +188,11 @@ set TZData(:Asia/Hebron) {
{2708460000 7200 0 EET}
{2721164400 10800 1 EEST}
{2739909600 7200 0 EET}
- {2753218800 10800 1 EEST}
+ {2752614000 10800 1 EEST}
{2771359200 7200 0 EET}
- {2784668400 10800 1 EEST}
+ {2784063600 10800 1 EEST}
{2802808800 7200 0 EET}
- {2816118000 10800 1 EEST}
+ {2815513200 10800 1 EEST}
{2834258400 7200 0 EET}
{2847567600 10800 1 EEST}
{2866312800 7200 0 EET}
@@ -200,9 +200,9 @@ set TZData(:Asia/Hebron) {
{2897762400 7200 0 EET}
{2910466800 10800 1 EEST}
{2929212000 7200 0 EET}
- {2942521200 10800 1 EEST}
+ {2941916400 10800 1 EEST}
{2960661600 7200 0 EET}
- {2973970800 10800 1 EEST}
+ {2973366000 10800 1 EEST}
{2992111200 7200 0 EET}
{3005420400 10800 1 EEST}
{3024165600 7200 0 EET}
@@ -210,11 +210,11 @@ set TZData(:Asia/Hebron) {
{3055615200 7200 0 EET}
{3068319600 10800 1 EEST}
{3087064800 7200 0 EET}
- {3100374000 10800 1 EEST}
+ {3099769200 10800 1 EEST}
{3118514400 7200 0 EET}
- {3131823600 10800 1 EEST}
+ {3131218800 10800 1 EEST}
{3149964000 7200 0 EET}
- {3163273200 10800 1 EEST}
+ {3162668400 10800 1 EEST}
{3181413600 7200 0 EET}
{3194722800 10800 1 EEST}
{3213468000 7200 0 EET}
@@ -222,9 +222,9 @@ set TZData(:Asia/Hebron) {
{3244917600 7200 0 EET}
{3257622000 10800 1 EEST}
{3276367200 7200 0 EET}
- {3289676400 10800 1 EEST}
+ {3289071600 10800 1 EEST}
{3307816800 7200 0 EET}
- {3321126000 10800 1 EEST}
+ {3320521200 10800 1 EEST}
{3339266400 7200 0 EET}
{3352575600 10800 1 EEST}
{3371320800 7200 0 EET}
@@ -234,9 +234,9 @@ set TZData(:Asia/Hebron) {
{3434220000 7200 0 EET}
{3446924400 10800 1 EEST}
{3465669600 7200 0 EET}
- {3478978800 10800 1 EEST}
+ {3478374000 10800 1 EEST}
{3497119200 7200 0 EET}
- {3510428400 10800 1 EEST}
+ {3509823600 10800 1 EEST}
{3528568800 7200 0 EET}
{3541878000 10800 1 EEST}
{3560623200 7200 0 EET}
@@ -244,11 +244,11 @@ set TZData(:Asia/Hebron) {
{3592072800 7200 0 EET}
{3604777200 10800 1 EEST}
{3623522400 7200 0 EET}
- {3636831600 10800 1 EEST}
+ {3636226800 10800 1 EEST}
{3654972000 7200 0 EET}
- {3668281200 10800 1 EEST}
+ {3667676400 10800 1 EEST}
{3686421600 7200 0 EET}
- {3699730800 10800 1 EEST}
+ {3699126000 10800 1 EEST}
{3717871200 7200 0 EET}
{3731180400 10800 1 EEST}
{3749925600 7200 0 EET}
@@ -256,9 +256,9 @@ set TZData(:Asia/Hebron) {
{3781375200 7200 0 EET}
{3794079600 10800 1 EEST}
{3812824800 7200 0 EET}
- {3826134000 10800 1 EEST}
+ {3825529200 10800 1 EEST}
{3844274400 7200 0 EET}
- {3857583600 10800 1 EEST}
+ {3856978800 10800 1 EEST}
{3875724000 7200 0 EET}
{3889033200 10800 1 EEST}
{3907778400 7200 0 EET}
@@ -266,11 +266,11 @@ set TZData(:Asia/Hebron) {
{3939228000 7200 0 EET}
{3951932400 10800 1 EEST}
{3970677600 7200 0 EET}
- {3983986800 10800 1 EEST}
+ {3983382000 10800 1 EEST}
{4002127200 7200 0 EET}
- {4015436400 10800 1 EEST}
+ {4014831600 10800 1 EEST}
{4033576800 7200 0 EET}
- {4046886000 10800 1 EEST}
+ {4046281200 10800 1 EEST}
{4065026400 7200 0 EET}
{4078335600 10800 1 EEST}
{4097080800 7200 0 EET}
diff --git a/tcl8.6/library/tzdata/Asia/Hovd b/tcl8.6/library/tzdata/Asia/Hovd
index a9c995b..9b14d5b 100644
--- a/tcl8.6/library/tzdata/Asia/Hovd
+++ b/tcl8.6/library/tzdata/Asia/Hovd
@@ -4,52 +4,52 @@ set TZData(:Asia/Hovd) {
{-9223372036854775808 21996 0 LMT}
{-2032927596 21600 0 +06}
{252439200 25200 0 +07}
- {417978000 28800 1 +08}
+ {417978000 28800 1 +07}
{433785600 25200 0 +07}
- {449600400 28800 1 +08}
+ {449600400 28800 1 +07}
{465321600 25200 0 +07}
- {481050000 28800 1 +08}
+ {481050000 28800 1 +07}
{496771200 25200 0 +07}
- {512499600 28800 1 +08}
+ {512499600 28800 1 +07}
{528220800 25200 0 +07}
- {543949200 28800 1 +08}
+ {543949200 28800 1 +07}
{559670400 25200 0 +07}
- {575398800 28800 1 +08}
+ {575398800 28800 1 +07}
{591120000 25200 0 +07}
- {606848400 28800 1 +08}
+ {606848400 28800 1 +07}
{622569600 25200 0 +07}
- {638298000 28800 1 +08}
+ {638298000 28800 1 +07}
{654624000 25200 0 +07}
- {670352400 28800 1 +08}
+ {670352400 28800 1 +07}
{686073600 25200 0 +07}
- {701802000 28800 1 +08}
+ {701802000 28800 1 +07}
{717523200 25200 0 +07}
- {733251600 28800 1 +08}
+ {733251600 28800 1 +07}
{748972800 25200 0 +07}
- {764701200 28800 1 +08}
+ {764701200 28800 1 +07}
{780422400 25200 0 +07}
- {796150800 28800 1 +08}
+ {796150800 28800 1 +07}
{811872000 25200 0 +07}
- {828205200 28800 1 +08}
+ {828205200 28800 1 +07}
{843926400 25200 0 +07}
- {859654800 28800 1 +08}
+ {859654800 28800 1 +07}
{875376000 25200 0 +07}
- {891104400 28800 1 +08}
+ {891104400 28800 1 +07}
{906825600 25200 0 +07}
- {988398000 28800 1 +08}
+ {988398000 28800 1 +07}
{1001700000 25200 0 +07}
- {1017428400 28800 1 +08}
+ {1017428400 28800 1 +07}
{1033149600 25200 0 +07}
- {1048878000 28800 1 +08}
+ {1048878000 28800 1 +07}
{1064599200 25200 0 +07}
- {1080327600 28800 1 +08}
+ {1080327600 28800 1 +07}
{1096048800 25200 0 +07}
- {1111777200 28800 1 +08}
+ {1111777200 28800 1 +07}
{1127498400 25200 0 +07}
- {1143226800 28800 1 +08}
+ {1143226800 28800 1 +07}
{1159552800 25200 0 +07}
- {1427482800 28800 1 +08}
+ {1427482800 28800 1 +07}
{1443196800 25200 0 +07}
- {1458932400 28800 1 +08}
+ {1458932400 28800 1 +07}
{1474646400 25200 0 +07}
}
diff --git a/tcl8.6/library/tzdata/Asia/Kuching b/tcl8.6/library/tzdata/Asia/Kuching
index d6f5ad4..e5dc1b7 100644
--- a/tcl8.6/library/tzdata/Asia/Kuching
+++ b/tcl8.6/library/tzdata/Asia/Kuching
@@ -4,19 +4,19 @@ set TZData(:Asia/Kuching) {
{-9223372036854775808 26480 0 LMT}
{-1383463280 27000 0 +0730}
{-1167636600 28800 0 +08}
- {-1082448000 30000 1 +0820}
+ {-1082448000 30000 1 +08}
{-1074586800 28800 0 +08}
- {-1050825600 30000 1 +0820}
+ {-1050825600 30000 1 +08}
{-1042964400 28800 0 +08}
- {-1019289600 30000 1 +0820}
+ {-1019289600 30000 1 +08}
{-1011428400 28800 0 +08}
- {-987753600 30000 1 +0820}
+ {-987753600 30000 1 +08}
{-979892400 28800 0 +08}
- {-956217600 30000 1 +0820}
+ {-956217600 30000 1 +08}
{-948356400 28800 0 +08}
- {-924595200 30000 1 +0820}
+ {-924595200 30000 1 +08}
{-916734000 28800 0 +08}
- {-893059200 30000 1 +0820}
+ {-893059200 30000 1 +08}
{-885198000 28800 0 +08}
{-879667200 32400 0 +09}
{-767005200 28800 0 +08}
diff --git a/tcl8.6/library/tzdata/Asia/Macau b/tcl8.6/library/tzdata/Asia/Macau
index 8458a8a..cbafd0e 100644
--- a/tcl8.6/library/tzdata/Asia/Macau
+++ b/tcl8.6/library/tzdata/Asia/Macau
@@ -1,20 +1,56 @@
# created by tools/tclZIC.tcl - do not edit
set TZData(:Asia/Macau) {
- {-9223372036854775808 27260 0 LMT}
- {-1830411260 28800 0 CST}
+ {-9223372036854775808 27250 0 LMT}
+ {-2056692850 28800 0 CST}
+ {-884509200 32400 0 +09}
+ {-873280800 36000 1 +09}
+ {-855918000 32400 0 +09}
+ {-841744800 36000 1 +09}
+ {-828529200 32400 0 +10}
+ {-765363600 28800 0 CT}
+ {-747046800 32400 1 CDT}
+ {-733827600 28800 0 CST}
+ {-716461200 32400 1 CDT}
+ {-697021200 28800 0 CST}
+ {-683715600 32400 1 CDT}
+ {-667990800 28800 0 CST}
+ {-654771600 32400 1 CDT}
+ {-636627600 28800 0 CST}
+ {-623322000 32400 1 CDT}
+ {-605178000 28800 0 CST}
+ {-591872400 32400 1 CDT}
+ {-573642000 28800 0 CST}
+ {-559818000 32400 1 CDT}
+ {-541674000 28800 0 CST}
+ {-528368400 32400 1 CDT}
+ {-510224400 28800 0 CST}
+ {-498128400 32400 1 CDT}
+ {-478774800 28800 0 CST}
+ {-466678800 32400 1 CDT}
+ {-446720400 28800 0 CST}
+ {-435229200 32400 1 CDT}
+ {-415258200 28800 0 CST}
+ {-403158600 32400 1 CDT}
+ {-383808600 28800 0 CST}
+ {-371709000 32400 1 CDT}
+ {-352359000 28800 0 CST}
+ {-340259400 32400 1 CDT}
+ {-320909400 28800 0 CST}
+ {-308809800 32400 1 CDT}
+ {-288855000 28800 0 CST}
{-277360200 32400 1 CDT}
{-257405400 28800 0 CST}
{-245910600 32400 1 CDT}
{-225955800 28800 0 CST}
- {-214473600 32400 1 CDT}
+ {-213856200 32400 1 CDT}
{-194506200 28800 0 CST}
{-182406600 32400 1 CDT}
{-163056600 28800 0 CST}
- {-150969600 32400 1 CDT}
- {-131619600 28800 0 CST}
+ {-148537800 32400 1 CDT}
+ {-132820200 28800 0 CST}
{-117088200 32400 1 CDT}
- {-101367000 28800 0 CST}
+ {-101370600 28800 0 CST}
{-85638600 32400 1 CDT}
{-69312600 28800 0 CST}
{-53584200 32400 1 CDT}
@@ -25,22 +61,16 @@ set TZData(:Asia/Macau) {
{25036200 28800 0 CST}
{40764600 32400 1 CDT}
{56485800 28800 0 CST}
- {72201600 32400 1 CDT}
- {87922800 28800 0 CST}
- {103651200 32400 1 CDT}
- {119977200 28800 0 CST}
- {135705600 32400 1 CDT}
+ {72214200 32400 1 CDT}
+ {88540200 28800 0 CST}
+ {104268600 32400 1 CDT}
+ {119989800 28800 0 CST}
+ {126041400 32400 1 CDT}
{151439400 28800 0 CST}
{167167800 32400 1 CDT}
{182889000 28800 0 CST}
{198617400 32400 1 CDT}
{214338600 28800 0 CST}
- {230067000 32400 1 CDT}
- {245788200 28800 0 CST}
- {261504000 32400 1 CDT}
- {277225200 28800 0 CST}
- {292953600 32400 1 CDT}
- {309279600 28800 0 CST}
- {325008000 32400 1 CDT}
- {340729200 28800 0 CST}
+ {295385400 32400 1 CDT}
+ {309292200 28800 0 CST}
}
diff --git a/tcl8.6/library/tzdata/Asia/Manila b/tcl8.6/library/tzdata/Asia/Manila
index 987919a..6eb1db3 100644
--- a/tcl8.6/library/tzdata/Asia/Manila
+++ b/tcl8.6/library/tzdata/Asia/Manila
@@ -3,13 +3,13 @@
set TZData(:Asia/Manila) {
{-9223372036854775808 -57360 0 LMT}
{-3944621040 29040 0 LMT}
- {-2229321840 28800 0 +08}
- {-1046678400 32400 1 +09}
- {-1038733200 28800 0 +08}
- {-873273600 32400 0 +09}
- {-794221200 28800 0 +08}
- {-496224000 32400 1 +09}
- {-489315600 28800 0 +08}
- {259344000 32400 1 +09}
- {275151600 28800 0 +08}
+ {-2229321840 28800 0 PST}
+ {-1046678400 32400 1 PDT}
+ {-1038733200 28800 0 PST}
+ {-873273600 32400 0 JST}
+ {-794221200 28800 0 PST}
+ {-496224000 32400 1 PDT}
+ {-489315600 28800 0 PST}
+ {259344000 32400 1 PDT}
+ {275151600 28800 0 PST}
}
diff --git a/tcl8.6/library/tzdata/Asia/Oral b/tcl8.6/library/tzdata/Asia/Oral
index 624a59d..e781b60 100644
--- a/tcl8.6/library/tzdata/Asia/Oral
+++ b/tcl8.6/library/tzdata/Asia/Oral
@@ -7,52 +7,52 @@ set TZData(:Asia/Oral) {
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
{606862800 14400 0 +04}
- {606866400 18000 1 +05}
+ {606866400 18000 1 +04}
{622591200 14400 0 +04}
- {638316000 18000 1 +05}
+ {638316000 18000 1 +04}
{654645600 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{686095200 14400 0 +04}
{701816400 14400 0 +04}
- {701820000 18000 1 +05}
+ {701820000 18000 1 +04}
{717544800 14400 0 +04}
- {733269600 18000 1 +05}
+ {733269600 18000 1 +04}
{748994400 14400 0 +04}
- {764719200 18000 1 +05}
+ {764719200 18000 1 +04}
{780444000 14400 0 +04}
- {796168800 18000 1 +05}
+ {796168800 18000 1 +04}
{811893600 14400 0 +04}
- {828223200 18000 1 +05}
+ {828223200 18000 1 +04}
{846367200 14400 0 +04}
- {859672800 18000 1 +05}
+ {859672800 18000 1 +04}
{877816800 14400 0 +04}
- {891122400 18000 1 +05}
+ {891122400 18000 1 +04}
{909266400 14400 0 +04}
- {922572000 18000 1 +05}
+ {922572000 18000 1 +04}
{941320800 14400 0 +04}
- {954021600 18000 1 +05}
+ {954021600 18000 1 +04}
{972770400 14400 0 +04}
- {985471200 18000 1 +05}
+ {985471200 18000 1 +04}
{1004220000 14400 0 +04}
- {1017525600 18000 1 +05}
+ {1017525600 18000 1 +04}
{1035669600 14400 0 +04}
- {1048975200 18000 1 +05}
+ {1048975200 18000 1 +04}
{1067119200 14400 0 +04}
- {1080424800 18000 1 +05}
+ {1080424800 18000 1 +04}
{1099173600 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Pyongyang b/tcl8.6/library/tzdata/Asia/Pyongyang
index 72e7f23..5351736 100644
--- a/tcl8.6/library/tzdata/Asia/Pyongyang
+++ b/tcl8.6/library/tzdata/Asia/Pyongyang
@@ -6,4 +6,5 @@ set TZData(:Asia/Pyongyang) {
{-1830414600 32400 0 JST}
{-768646800 32400 0 KST}
{1439564400 30600 0 KST}
+ {1525446000 32400 0 KST}
}
diff --git a/tcl8.6/library/tzdata/Asia/Qyzylorda b/tcl8.6/library/tzdata/Asia/Qyzylorda
index b2e9472..7c6df32 100644
--- a/tcl8.6/library/tzdata/Asia/Qyzylorda
+++ b/tcl8.6/library/tzdata/Asia/Qyzylorda
@@ -7,51 +7,51 @@ set TZData(:Asia/Qyzylorda) {
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
{670366800 14400 0 +04}
- {670370400 18000 1 +05}
+ {670370400 18000 1 +04}
{701812800 18000 0 +05}
- {701816400 21600 1 +06}
+ {701816400 21600 1 +05}
{717541200 18000 0 +05}
- {733266000 21600 1 +06}
+ {733266000 21600 1 +05}
{748990800 18000 0 +05}
- {764715600 21600 1 +06}
+ {764715600 21600 1 +05}
{780440400 18000 0 +05}
- {796165200 21600 1 +06}
+ {796165200 21600 1 +05}
{811890000 18000 0 +05}
- {828219600 21600 1 +06}
+ {828219600 21600 1 +05}
{846363600 18000 0 +05}
- {859669200 21600 1 +06}
+ {859669200 21600 1 +05}
{877813200 18000 0 +05}
- {891118800 21600 1 +06}
+ {891118800 21600 1 +05}
{909262800 18000 0 +05}
- {922568400 21600 1 +06}
+ {922568400 21600 1 +05}
{941317200 18000 0 +05}
- {954018000 21600 1 +06}
+ {954018000 21600 1 +05}
{972766800 18000 0 +05}
- {985467600 21600 1 +06}
+ {985467600 21600 1 +05}
{1004216400 18000 0 +05}
- {1017522000 21600 1 +06}
+ {1017522000 21600 1 +05}
{1035666000 18000 0 +05}
- {1048971600 21600 1 +06}
+ {1048971600 21600 1 +05}
{1067115600 18000 0 +05}
- {1080421200 21600 1 +06}
+ {1080421200 21600 1 +05}
{1099170000 21600 0 +06}
}
diff --git a/tcl8.6/library/tzdata/Asia/Samarkand b/tcl8.6/library/tzdata/Asia/Samarkand
index 43ad774..805bab7 100644
--- a/tcl8.6/library/tzdata/Asia/Samarkand
+++ b/tcl8.6/library/tzdata/Asia/Samarkand
@@ -7,25 +7,25 @@ set TZData(:Asia/Samarkand) {
{354913200 21600 1 +06}
{370720800 21600 0 +06}
{386445600 18000 0 +05}
- {386449200 21600 1 +06}
+ {386449200 21600 1 +05}
{402256800 18000 0 +05}
- {417985200 21600 1 +06}
+ {417985200 21600 1 +05}
{433792800 18000 0 +05}
- {449607600 21600 1 +06}
+ {449607600 21600 1 +05}
{465339600 18000 0 +05}
- {481064400 21600 1 +06}
+ {481064400 21600 1 +05}
{496789200 18000 0 +05}
- {512514000 21600 1 +06}
+ {512514000 21600 1 +05}
{528238800 18000 0 +05}
- {543963600 21600 1 +06}
+ {543963600 21600 1 +05}
{559688400 18000 0 +05}
- {575413200 21600 1 +06}
+ {575413200 21600 1 +05}
{591138000 18000 0 +05}
- {606862800 21600 1 +06}
+ {606862800 21600 1 +05}
{622587600 18000 0 +05}
- {638312400 21600 1 +06}
+ {638312400 21600 1 +05}
{654642000 18000 0 +05}
- {670366800 21600 1 +06}
+ {670366800 21600 1 +05}
{686091600 18000 0 +05}
{694206000 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Shanghai b/tcl8.6/library/tzdata/Asia/Shanghai
index ff2d2b5..66bc433 100644
--- a/tcl8.6/library/tzdata/Asia/Shanghai
+++ b/tcl8.6/library/tzdata/Asia/Shanghai
@@ -3,21 +3,30 @@
set TZData(:Asia/Shanghai) {
{-9223372036854775808 29143 0 LMT}
{-2177481943 28800 0 CST}
- {-933494400 32400 1 CDT}
- {-923130000 28800 0 CST}
- {-908784000 32400 1 CDT}
- {-891594000 28800 0 CST}
- {-662716800 28800 0 CST}
- {515520000 32400 1 CDT}
- {527007600 28800 0 CST}
- {545155200 32400 1 CDT}
- {558457200 28800 0 CST}
- {576604800 32400 1 CDT}
- {589906800 28800 0 CST}
- {608659200 32400 1 CDT}
- {621961200 28800 0 CST}
- {640108800 32400 1 CDT}
- {653410800 28800 0 CST}
- {671558400 32400 1 CDT}
- {684860400 28800 0 CST}
+ {-933667200 32400 1 CDT}
+ {-922093200 28800 0 CST}
+ {-908870400 32400 1 CDT}
+ {-888829200 28800 0 CST}
+ {-881049600 32400 1 CDT}
+ {-767869200 28800 0 CST}
+ {-745833600 32400 1 CDT}
+ {-733827600 28800 0 CST}
+ {-716889600 32400 1 CDT}
+ {-699613200 28800 0 CST}
+ {-683884800 32400 1 CDT}
+ {-670669200 28800 0 CST}
+ {-652348800 32400 1 CDT}
+ {-650016000 28800 0 CST}
+ {515527200 32400 1 CDT}
+ {527014800 28800 0 CST}
+ {545162400 32400 1 CDT}
+ {558464400 28800 0 CST}
+ {577216800 32400 1 CDT}
+ {589914000 28800 0 CST}
+ {608666400 32400 1 CDT}
+ {621968400 28800 0 CST}
+ {640116000 32400 1 CDT}
+ {653418000 28800 0 CST}
+ {671565600 32400 1 CDT}
+ {684867600 28800 0 CST}
}
diff --git a/tcl8.6/library/tzdata/Asia/Tashkent b/tcl8.6/library/tzdata/Asia/Tashkent
index 7b6abe4..bd16c91 100644
--- a/tcl8.6/library/tzdata/Asia/Tashkent
+++ b/tcl8.6/library/tzdata/Asia/Tashkent
@@ -4,28 +4,28 @@ set TZData(:Asia/Tashkent) {
{-9223372036854775808 16631 0 LMT}
{-1441168631 18000 0 +05}
{-1247547600 21600 0 +06}
- {354909600 25200 1 +07}
+ {354909600 25200 1 +06}
{370717200 21600 0 +06}
- {386445600 25200 1 +07}
+ {386445600 25200 1 +06}
{402253200 21600 0 +06}
- {417981600 25200 1 +07}
+ {417981600 25200 1 +06}
{433789200 21600 0 +06}
- {449604000 25200 1 +07}
+ {449604000 25200 1 +06}
{465336000 21600 0 +06}
- {481060800 25200 1 +07}
+ {481060800 25200 1 +06}
{496785600 21600 0 +06}
- {512510400 25200 1 +07}
+ {512510400 25200 1 +06}
{528235200 21600 0 +06}
- {543960000 25200 1 +07}
+ {543960000 25200 1 +06}
{559684800 21600 0 +06}
- {575409600 25200 1 +07}
+ {575409600 25200 1 +06}
{591134400 21600 0 +06}
- {606859200 25200 1 +07}
+ {606859200 25200 1 +06}
{622584000 21600 0 +06}
- {638308800 25200 1 +07}
+ {638308800 25200 1 +06}
{654638400 21600 0 +06}
{670363200 18000 0 +05}
- {670366800 21600 1 +06}
+ {670366800 21600 1 +05}
{686091600 18000 0 +05}
{694206000 18000 0 +05}
}
diff --git a/tcl8.6/library/tzdata/Asia/Tbilisi b/tcl8.6/library/tzdata/Asia/Tbilisi
index 60d253c..71e7695 100644
--- a/tcl8.6/library/tzdata/Asia/Tbilisi
+++ b/tcl8.6/library/tzdata/Asia/Tbilisi
@@ -5,56 +5,56 @@ set TZData(:Asia/Tbilisi) {
{-2840151551 10751 0 TBMT}
{-1441162751 10800 0 +03}
{-405140400 14400 0 +04}
- {354916800 18000 1 +05}
+ {354916800 18000 1 +04}
{370724400 14400 0 +04}
- {386452800 18000 1 +05}
+ {386452800 18000 1 +04}
{402260400 14400 0 +04}
- {417988800 18000 1 +05}
+ {417988800 18000 1 +04}
{433796400 14400 0 +04}
- {449611200 18000 1 +05}
+ {449611200 18000 1 +04}
{465343200 14400 0 +04}
- {481068000 18000 1 +05}
+ {481068000 18000 1 +04}
{496792800 14400 0 +04}
- {512517600 18000 1 +05}
+ {512517600 18000 1 +04}
{528242400 14400 0 +04}
- {543967200 18000 1 +05}
+ {543967200 18000 1 +04}
{559692000 14400 0 +04}
- {575416800 18000 1 +05}
+ {575416800 18000 1 +04}
{591141600 14400 0 +04}
- {606866400 18000 1 +05}
+ {606866400 18000 1 +04}
{622591200 14400 0 +04}
- {638316000 18000 1 +05}
+ {638316000 18000 1 +04}
{654645600 14400 0 +04}
{670370400 10800 0 +03}
- {670374000 14400 1 +04}
+ {670374000 14400 1 +03}
{686098800 10800 0 +03}
{694213200 10800 0 +03}
- {701816400 14400 1 +04}
+ {701816400 14400 1 +03}
{717537600 10800 0 +03}
- {733266000 14400 1 +04}
+ {733266000 14400 1 +03}
{748987200 10800 0 +03}
- {764715600 14400 1 +04}
+ {764715600 14400 1 +03}
{780440400 14400 0 +04}
- {796161600 18000 1 +05}
+ {796161600 18000 1 +04}
{811882800 14400 0 +04}
- {828216000 18000 1 +05}
+ {828216000 18000 1 +04}
{846360000 18000 1 +05}
- {859662000 18000 0 +05}
+ {859662000 18000 0 +04}
{877806000 14400 0 +04}
- {891115200 18000 1 +05}
+ {891115200 18000 1 +04}
{909255600 14400 0 +04}
- {922564800 18000 1 +05}
+ {922564800 18000 1 +04}
{941310000 14400 0 +04}
- {954014400 18000 1 +05}
+ {954014400 18000 1 +04}
{972759600 14400 0 +04}
- {985464000 18000 1 +05}
+ {985464000 18000 1 +04}
{1004209200 14400 0 +04}
- {1017518400 18000 1 +05}
+ {1017518400 18000 1 +04}
{1035658800 14400 0 +04}
- {1048968000 18000 1 +05}
+ {1048968000 18000 1 +04}
{1067108400 14400 0 +04}
- {1080417600 18000 1 +05}
- {1088280000 14400 0 +04}
+ {1080417600 18000 1 +04}
+ {1088280000 14400 0 +03}
{1099177200 10800 0 +03}
{1111878000 14400 0 +04}
}
diff --git a/tcl8.6/library/tzdata/Asia/Tehran b/tcl8.6/library/tzdata/Asia/Tehran
index a8912ce..3d44e42 100644
--- a/tcl8.6/library/tzdata/Asia/Tehran
+++ b/tcl8.6/library/tzdata/Asia/Tehran
@@ -4,226 +4,226 @@ set TZData(:Asia/Tehran) {
{-9223372036854775808 12344 0 LMT}
{-1704165944 12344 0 TMT}
{-757394744 12600 0 +0330}
- {247177800 14400 0 +05}
- {259272000 18000 1 +05}
- {277758000 14400 0 +05}
- {283982400 12600 0 +0430}
- {290809800 16200 1 +0430}
- {306531000 12600 0 +0430}
- {322432200 16200 1 +0430}
- {338499000 12600 0 +0430}
- {673216200 16200 1 +0430}
- {685481400 12600 0 +0430}
- {701209800 16200 1 +0430}
- {717103800 12600 0 +0430}
- {732745800 16200 1 +0430}
- {748639800 12600 0 +0430}
- {764281800 16200 1 +0430}
- {780175800 12600 0 +0430}
- {795817800 16200 1 +0430}
- {811711800 12600 0 +0430}
- {827353800 16200 1 +0430}
- {843247800 12600 0 +0430}
- {858976200 16200 1 +0430}
- {874870200 12600 0 +0430}
- {890512200 16200 1 +0430}
- {906406200 12600 0 +0430}
- {922048200 16200 1 +0430}
- {937942200 12600 0 +0430}
- {953584200 16200 1 +0430}
- {969478200 12600 0 +0430}
- {985206600 16200 1 +0430}
- {1001100600 12600 0 +0430}
- {1016742600 16200 1 +0430}
- {1032636600 12600 0 +0430}
- {1048278600 16200 1 +0430}
- {1064172600 12600 0 +0430}
- {1079814600 16200 1 +0430}
- {1095708600 12600 0 +0430}
- {1111437000 16200 1 +0430}
- {1127331000 12600 0 +0430}
- {1206045000 16200 1 +0430}
- {1221939000 12600 0 +0430}
- {1237667400 16200 1 +0430}
- {1253561400 12600 0 +0430}
- {1269203400 16200 1 +0430}
- {1285097400 12600 0 +0430}
- {1300739400 16200 1 +0430}
- {1316633400 12600 0 +0430}
- {1332275400 16200 1 +0430}
- {1348169400 12600 0 +0430}
- {1363897800 16200 1 +0430}
- {1379791800 12600 0 +0430}
- {1395433800 16200 1 +0430}
- {1411327800 12600 0 +0430}
- {1426969800 16200 1 +0430}
- {1442863800 12600 0 +0430}
- {1458505800 16200 1 +0430}
- {1474399800 12600 0 +0430}
- {1490128200 16200 1 +0430}
- {1506022200 12600 0 +0430}
- {1521664200 16200 1 +0430}
- {1537558200 12600 0 +0430}
- {1553200200 16200 1 +0430}
- {1569094200 12600 0 +0430}
- {1584736200 16200 1 +0430}
- {1600630200 12600 0 +0430}
- {1616358600 16200 1 +0430}
- {1632252600 12600 0 +0430}
- {1647894600 16200 1 +0430}
- {1663788600 12600 0 +0430}
- {1679430600 16200 1 +0430}
- {1695324600 12600 0 +0430}
- {1710966600 16200 1 +0430}
- {1726860600 12600 0 +0430}
- {1742589000 16200 1 +0430}
- {1758483000 12600 0 +0430}
- {1774125000 16200 1 +0430}
- {1790019000 12600 0 +0430}
- {1805661000 16200 1 +0430}
- {1821555000 12600 0 +0430}
- {1837197000 16200 1 +0430}
- {1853091000 12600 0 +0430}
- {1868733000 16200 1 +0430}
- {1884627000 12600 0 +0430}
- {1900355400 16200 1 +0430}
- {1916249400 12600 0 +0430}
- {1931891400 16200 1 +0430}
- {1947785400 12600 0 +0430}
- {1963427400 16200 1 +0430}
- {1979321400 12600 0 +0430}
- {1994963400 16200 1 +0430}
- {2010857400 12600 0 +0430}
- {2026585800 16200 1 +0430}
- {2042479800 12600 0 +0430}
- {2058121800 16200 1 +0430}
- {2074015800 12600 0 +0430}
- {2089657800 16200 1 +0430}
- {2105551800 12600 0 +0430}
- {2121193800 16200 1 +0430}
- {2137087800 12600 0 +0430}
- {2152729800 16200 1 +0430}
- {2168623800 12600 0 +0430}
- {2184265800 16200 1 +0430}
- {2200159800 12600 0 +0430}
- {2215888200 16200 1 +0430}
- {2231782200 12600 0 +0430}
- {2247424200 16200 1 +0430}
- {2263318200 12600 0 +0430}
- {2278960200 16200 1 +0430}
- {2294854200 12600 0 +0430}
- {2310496200 16200 1 +0430}
- {2326390200 12600 0 +0430}
- {2342118600 16200 1 +0430}
- {2358012600 12600 0 +0430}
- {2373654600 16200 1 +0430}
- {2389548600 12600 0 +0430}
- {2405190600 16200 1 +0430}
- {2421084600 12600 0 +0430}
- {2436726600 16200 1 +0430}
- {2452620600 12600 0 +0430}
- {2468349000 16200 1 +0430}
- {2484243000 12600 0 +0430}
- {2499885000 16200 1 +0430}
- {2515779000 12600 0 +0430}
- {2531421000 16200 1 +0430}
- {2547315000 12600 0 +0430}
- {2562957000 16200 1 +0430}
- {2578851000 12600 0 +0430}
- {2594579400 16200 1 +0430}
- {2610473400 12600 0 +0430}
- {2626115400 16200 1 +0430}
- {2642009400 12600 0 +0430}
- {2657651400 16200 1 +0430}
- {2673545400 12600 0 +0430}
- {2689187400 16200 1 +0430}
- {2705081400 12600 0 +0430}
- {2720809800 16200 1 +0430}
- {2736703800 12600 0 +0430}
- {2752345800 16200 1 +0430}
- {2768239800 12600 0 +0430}
- {2783881800 16200 1 +0430}
- {2799775800 12600 0 +0430}
- {2815417800 16200 1 +0430}
- {2831311800 12600 0 +0430}
- {2847040200 16200 1 +0430}
- {2862934200 12600 0 +0430}
- {2878576200 16200 1 +0430}
- {2894470200 12600 0 +0430}
- {2910112200 16200 1 +0430}
- {2926006200 12600 0 +0430}
- {2941648200 16200 1 +0430}
- {2957542200 12600 0 +0430}
- {2973270600 16200 1 +0430}
- {2989164600 12600 0 +0430}
- {3004806600 16200 1 +0430}
- {3020700600 12600 0 +0430}
- {3036342600 16200 1 +0430}
- {3052236600 12600 0 +0430}
- {3067878600 16200 1 +0430}
- {3083772600 12600 0 +0430}
- {3099501000 16200 1 +0430}
- {3115395000 12600 0 +0430}
- {3131037000 16200 1 +0430}
- {3146931000 12600 0 +0430}
- {3162573000 16200 1 +0430}
- {3178467000 12600 0 +0430}
- {3194109000 16200 1 +0430}
- {3210003000 12600 0 +0430}
- {3225731400 16200 1 +0430}
- {3241625400 12600 0 +0430}
- {3257267400 16200 1 +0430}
- {3273161400 12600 0 +0430}
- {3288803400 16200 1 +0430}
- {3304697400 12600 0 +0430}
- {3320339400 16200 1 +0430}
- {3336233400 12600 0 +0430}
- {3351961800 16200 1 +0430}
- {3367855800 12600 0 +0430}
- {3383497800 16200 1 +0430}
- {3399391800 12600 0 +0430}
- {3415033800 16200 1 +0430}
- {3430927800 12600 0 +0430}
- {3446569800 16200 1 +0430}
- {3462463800 12600 0 +0430}
- {3478192200 16200 1 +0430}
- {3494086200 12600 0 +0430}
- {3509728200 16200 1 +0430}
- {3525622200 12600 0 +0430}
- {3541264200 16200 1 +0430}
- {3557158200 12600 0 +0430}
- {3572800200 16200 1 +0430}
- {3588694200 12600 0 +0430}
- {3604422600 16200 1 +0430}
- {3620316600 12600 0 +0430}
- {3635958600 16200 1 +0430}
- {3651852600 12600 0 +0430}
- {3667494600 16200 1 +0430}
- {3683388600 12600 0 +0430}
- {3699030600 16200 1 +0430}
- {3714924600 12600 0 +0430}
- {3730653000 16200 1 +0430}
- {3746547000 12600 0 +0430}
- {3762189000 16200 1 +0430}
- {3778083000 12600 0 +0430}
- {3793725000 16200 1 +0430}
- {3809619000 12600 0 +0430}
- {3825261000 16200 1 +0430}
- {3841155000 12600 0 +0430}
- {3856883400 16200 1 +0430}
- {3872777400 12600 0 +0430}
- {3888419400 16200 1 +0430}
- {3904313400 12600 0 +0430}
- {3919955400 16200 1 +0430}
- {3935849400 12600 0 +0430}
- {3951491400 16200 1 +0430}
- {3967385400 12600 0 +0430}
- {3983113800 16200 1 +0430}
- {3999007800 12600 0 +0430}
- {4014649800 16200 1 +0430}
- {4030543800 12600 0 +0430}
- {4046185800 16200 1 +0430}
- {4062079800 12600 0 +0430}
- {4077721800 16200 1 +0430}
- {4093615800 12600 0 +0430}
+ {247177800 14400 0 +04}
+ {259272000 18000 1 +04}
+ {277758000 14400 0 +04}
+ {283982400 12600 0 +0330}
+ {290809800 16200 1 +0330}
+ {306531000 12600 0 +0330}
+ {322432200 16200 1 +0330}
+ {338499000 12600 0 +0330}
+ {673216200 16200 1 +0330}
+ {685481400 12600 0 +0330}
+ {701209800 16200 1 +0330}
+ {717103800 12600 0 +0330}
+ {732745800 16200 1 +0330}
+ {748639800 12600 0 +0330}
+ {764281800 16200 1 +0330}
+ {780175800 12600 0 +0330}
+ {795817800 16200 1 +0330}
+ {811711800 12600 0 +0330}
+ {827353800 16200 1 +0330}
+ {843247800 12600 0 +0330}
+ {858976200 16200 1 +0330}
+ {874870200 12600 0 +0330}
+ {890512200 16200 1 +0330}
+ {906406200 12600 0 +0330}
+ {922048200 16200 1 +0330}
+ {937942200 12600 0 +0330}
+ {953584200 16200 1 +0330}
+ {969478200 12600 0 +0330}
+ {985206600 16200 1 +0330}
+ {1001100600 12600 0 +0330}
+ {1016742600 16200 1 +0330}
+ {1032636600 12600 0 +0330}
+ {1048278600 16200 1 +0330}
+ {1064172600 12600 0 +0330}
+ {1079814600 16200 1 +0330}
+ {1095708600 12600 0 +0330}
+ {1111437000 16200 1 +0330}
+ {1127331000 12600 0 +0330}
+ {1206045000 16200 1 +0330}
+ {1221939000 12600 0 +0330}
+ {1237667400 16200 1 +0330}
+ {1253561400 12600 0 +0330}
+ {1269203400 16200 1 +0330}
+ {1285097400 12600 0 +0330}
+ {1300739400 16200 1 +0330}
+ {1316633400 12600 0 +0330}
+ {1332275400 16200 1 +0330}
+ {1348169400 12600 0 +0330}
+ {1363897800 16200 1 +0330}
+ {1379791800 12600 0 +0330}
+ {1395433800 16200 1 +0330}
+ {1411327800 12600 0 +0330}
+ {1426969800 16200 1 +0330}
+ {1442863800 12600 0 +0330}
+ {1458505800 16200 1 +0330}
+ {1474399800 12600 0 +0330}
+ {1490128200 16200 1 +0330}
+ {1506022200 12600 0 +0330}
+ {1521664200 16200 1 +0330}
+ {1537558200 12600 0 +0330}
+ {1553200200 16200 1 +0330}
+ {1569094200 12600 0 +0330}
+ {1584736200 16200 1 +0330}
+ {1600630200 12600 0 +0330}
+ {1616358600 16200 1 +0330}
+ {1632252600 12600 0 +0330}
+ {1647894600 16200 1 +0330}
+ {1663788600 12600 0 +0330}
+ {1679430600 16200 1 +0330}
+ {1695324600 12600 0 +0330}
+ {1710966600 16200 1 +0330}
+ {1726860600 12600 0 +0330}
+ {1742589000 16200 1 +0330}
+ {1758483000 12600 0 +0330}
+ {1774125000 16200 1 +0330}
+ {1790019000 12600 0 +0330}
+ {1805661000 16200 1 +0330}
+ {1821555000 12600 0 +0330}
+ {1837197000 16200 1 +0330}
+ {1853091000 12600 0 +0330}
+ {1868733000 16200 1 +0330}
+ {1884627000 12600 0 +0330}
+ {1900355400 16200 1 +0330}
+ {1916249400 12600 0 +0330}
+ {1931891400 16200 1 +0330}
+ {1947785400 12600 0 +0330}
+ {1963427400 16200 1 +0330}
+ {1979321400 12600 0 +0330}
+ {1994963400 16200 1 +0330}
+ {2010857400 12600 0 +0330}
+ {2026585800 16200 1 +0330}
+ {2042479800 12600 0 +0330}
+ {2058121800 16200 1 +0330}
+ {2074015800 12600 0 +0330}
+ {2089657800 16200 1 +0330}
+ {2105551800 12600 0 +0330}
+ {2121193800 16200 1 +0330}
+ {2137087800 12600 0 +0330}
+ {2152729800 16200 1 +0330}
+ {2168623800 12600 0 +0330}
+ {2184265800 16200 1 +0330}
+ {2200159800 12600 0 +0330}
+ {2215888200 16200 1 +0330}
+ {2231782200 12600 0 +0330}
+ {2247424200 16200 1 +0330}
+ {2263318200 12600 0 +0330}
+ {2278960200 16200 1 +0330}
+ {2294854200 12600 0 +0330}
+ {2310496200 16200 1 +0330}
+ {2326390200 12600 0 +0330}
+ {2342118600 16200 1 +0330}
+ {2358012600 12600 0 +0330}
+ {2373654600 16200 1 +0330}
+ {2389548600 12600 0 +0330}
+ {2405190600 16200 1 +0330}
+ {2421084600 12600 0 +0330}
+ {2436726600 16200 1 +0330}
+ {2452620600 12600 0 +0330}
+ {2468349000 16200 1 +0330}
+ {2484243000 12600 0 +0330}
+ {2499885000 16200 1 +0330}
+ {2515779000 12600 0 +0330}
+ {2531421000 16200 1 +0330}
+ {2547315000 12600 0 +0330}
+ {2562957000 16200 1 +0330}
+ {2578851000 12600 0 +0330}
+ {2594579400 16200 1 +0330}
+ {2610473400 12600 0 +0330}
+ {2626115400 16200 1 +0330}
+ {2642009400 12600 0 +0330}
+ {2657651400 16200 1 +0330}
+ {2673545400 12600 0 +0330}
+ {2689187400 16200 1 +0330}
+ {2705081400 12600 0 +0330}
+ {2720809800 16200 1 +0330}
+ {2736703800 12600 0 +0330}
+ {2752345800 16200 1 +0330}
+ {2768239800 12600 0 +0330}
+ {2783881800 16200 1 +0330}
+ {2799775800 12600 0 +0330}
+ {2815417800 16200 1 +0330}
+ {2831311800 12600 0 +0330}
+ {2847040200 16200 1 +0330}
+ {2862934200 12600 0 +0330}
+ {2878576200 16200 1 +0330}
+ {2894470200 12600 0 +0330}
+ {2910112200 16200 1 +0330}
+ {2926006200 12600 0 +0330}
+ {2941648200 16200 1 +0330}
+ {2957542200 12600 0 +0330}
+ {2973270600 16200 1 +0330}
+ {2989164600 12600 0 +0330}
+ {3004806600 16200 1 +0330}
+ {3020700600 12600 0 +0330}
+ {3036342600 16200 1 +0330}
+ {3052236600 12600 0 +0330}
+ {3067878600 16200 1 +0330}
+ {3083772600 12600 0 +0330}
+ {3099501000 16200 1 +0330}
+ {3115395000 12600 0 +0330}
+ {3131037000 16200 1 +0330}
+ {3146931000 12600 0 +0330}
+ {3162573000 16200 1 +0330}
+ {3178467000 12600 0 +0330}
+ {3194109000 16200 1 +0330}
+ {3210003000 12600 0 +0330}
+ {3225731400 16200 1 +0330}
+ {3241625400 12600 0 +0330}
+ {3257267400 16200 1 +0330}
+ {3273161400 12600 0 +0330}
+ {3288803400 16200 1 +0330}
+ {3304697400 12600 0 +0330}
+ {3320339400 16200 1 +0330}
+ {3336233400 12600 0 +0330}
+ {3351961800 16200 1 +0330}
+ {3367855800 12600 0 +0330}
+ {3383497800 16200 1 +0330}
+ {3399391800 12600 0 +0330}
+ {3415033800 16200 1 +0330}
+ {3430927800 12600 0 +0330}
+ {3446569800 16200 1 +0330}
+ {3462463800 12600 0 +0330}
+ {3478192200 16200 1 +0330}
+ {3494086200 12600 0 +0330}
+ {3509728200 16200 1 +0330}
+ {3525622200 12600 0 +0330}
+ {3541264200 16200 1 +0330}
+ {3557158200 12600 0 +0330}
+ {3572800200 16200 1 +0330}
+ {3588694200 12600 0 +0330}
+ {3604422600 16200 1 +0330}
+ {3620316600 12600 0 +0330}
+ {3635958600 16200 1 +0330}
+ {3651852600 12600 0 +0330}
+ {3667494600 16200 1 +0330}
+ {3683388600 12600 0 +0330}
+ {3699030600 16200 1 +0330}
+ {3714924600 12600 0 +0330}
+ {3730653000 16200 1 +0330}
+ {3746547000 12600 0 +0330}
+ {3762189000 16200 1 +0330}
+ {3778083000 12600 0 +0330}
+ {3793725000 16200 1 +0330}
+ {3809619000 12600 0 +0330}
+ {3825261000 16200 1 +0330}
+ {3841155000 12600 0 +0330}
+ {3856883400 16200 1 +0330}
+ {3872777400 12600 0 +0330}
+ {3888419400 16200 1 +0330}
+ {3904313400 12600 0 +0330}
+ {3919955400 16200 1 +0330}
+ {3935849400 12600 0 +0330}
+ {3951491400 16200 1 +0330}
+ {3967385400 12600 0 +0330}
+ {3983113800 16200 1 +0330}
+ {3999007800 12600 0 +0330}
+ {4014649800 16200 1 +0330}
+ {4030543800 12600 0 +0330}
+ {4046185800 16200 1 +0330}
+ {4062079800 12600 0 +0330}
+ {4077721800 16200 1 +0330}
+ {4093615800 12600 0 +0330}
}
diff --git a/tcl8.6/library/tzdata/Asia/Tokyo b/tcl8.6/library/tzdata/Asia/Tokyo
index 10add1c..cc7a857 100644
--- a/tcl8.6/library/tzdata/Asia/Tokyo
+++ b/tcl8.6/library/tzdata/Asia/Tokyo
@@ -3,12 +3,12 @@
set TZData(:Asia/Tokyo) {
{-9223372036854775808 33539 0 LMT}
{-2587712400 32400 0 JST}
- {-683794800 36000 1 JDT}
- {-672393600 32400 0 JST}
- {-654764400 36000 1 JDT}
- {-640944000 32400 0 JST}
- {-620290800 36000 1 JDT}
- {-609494400 32400 0 JST}
- {-588841200 36000 1 JDT}
- {-578044800 32400 0 JST}
+ {-683802000 36000 1 JDT}
+ {-672310800 32400 0 JST}
+ {-654771600 36000 1 JDT}
+ {-640861200 32400 0 JST}
+ {-620298000 36000 1 JDT}
+ {-609411600 32400 0 JST}
+ {-588848400 36000 1 JDT}
+ {-577962000 32400 0 JST}
}
diff --git a/tcl8.6/library/tzdata/Asia/Ulaanbaatar b/tcl8.6/library/tzdata/Asia/Ulaanbaatar
index e0ba7ab..3a33ef9 100644
--- a/tcl8.6/library/tzdata/Asia/Ulaanbaatar
+++ b/tcl8.6/library/tzdata/Asia/Ulaanbaatar
@@ -4,52 +4,52 @@ set TZData(:Asia/Ulaanbaatar) {
{-9223372036854775808 25652 0 LMT}
{-2032931252 25200 0 +07}
{252435600 28800 0 +08}
- {417974400 32400 1 +09}
+ {417974400 32400 1 +08}
{433782000 28800 0 +08}
- {449596800 32400 1 +09}
+ {449596800 32400 1 +08}
{465318000 28800 0 +08}
- {481046400 32400 1 +09}
+ {481046400 32400 1 +08}
{496767600 28800 0 +08}
- {512496000 32400 1 +09}
+ {512496000 32400 1 +08}
{528217200 28800 0 +08}
- {543945600 32400 1 +09}
+ {543945600 32400 1 +08}
{559666800 28800 0 +08}
- {575395200 32400 1 +09}
+ {575395200 32400 1 +08}
{591116400 28800 0 +08}
- {606844800 32400 1 +09}
+ {606844800 32400 1 +08}
{622566000 28800 0 +08}
- {638294400 32400 1 +09}
+ {638294400 32400 1 +08}
{654620400 28800 0 +08}
- {670348800 32400 1 +09}
+ {670348800 32400 1 +08}
{686070000 28800 0 +08}
- {701798400 32400 1 +09}
+ {701798400 32400 1 +08}
{717519600 28800 0 +08}
- {733248000 32400 1 +09}
+ {733248000 32400 1 +08}
{748969200 28800 0 +08}
- {764697600 32400 1 +09}
+ {764697600 32400 1 +08}
{780418800 28800 0 +08}
- {796147200 32400 1 +09}
+ {796147200 32400 1 +08}
{811868400 28800 0 +08}
- {828201600 32400 1 +09}
+ {828201600 32400 1 +08}
{843922800 28800 0 +08}
- {859651200 32400 1 +09}
+ {859651200 32400 1 +08}
{875372400 28800 0 +08}
- {891100800 32400 1 +09}
+ {891100800 32400 1 +08}
{906822000 28800 0 +08}
- {988394400 32400 1 +09}
+ {988394400 32400 1 +08}
{1001696400 28800 0 +08}
- {1017424800 32400 1 +09}
+ {1017424800 32400 1 +08}
{1033146000 28800 0 +08}
- {1048874400 32400 1 +09}
+ {1048874400 32400 1 +08}
{1064595600 28800 0 +08}
- {1080324000 32400 1 +09}
+ {1080324000 32400 1 +08}
{1096045200 28800 0 +08}
- {1111773600 32400 1 +09}
+ {1111773600 32400 1 +08}
{1127494800 28800 0 +08}
- {1143223200 32400 1 +09}
+ {1143223200 32400 1 +08}
{1159549200 28800 0 +08}
- {1427479200 32400 1 +09}
+ {1427479200 32400 1 +08}
{1443193200 28800 0 +08}
- {1458928800 32400 1 +09}
+ {1458928800 32400 1 +08}
{1474642800 28800 0 +08}
}
diff --git a/tcl8.6/library/tzdata/Asia/Yerevan b/tcl8.6/library/tzdata/Asia/Yerevan
index 25a349a..463bed0 100644
--- a/tcl8.6/library/tzdata/Asia/Yerevan
+++ b/tcl8.6/library/tzdata/Asia/Yerevan
@@ -4,67 +4,67 @@ set TZData(:Asia/Yerevan) {
{-9223372036854775808 10680 0 LMT}
{-1441162680 10800 0 +03}
{-405140400 14400 0 +04}
- {354916800 18000 1 +05}
+ {354916800 18000 1 +04}
{370724400 14400 0 +04}
- {386452800 18000 1 +05}
+ {386452800 18000 1 +04}
{402260400 14400 0 +04}
- {417988800 18000 1 +05}
+ {417988800 18000 1 +04}
{433796400 14400 0 +04}
- {449611200 18000 1 +05}
+ {449611200 18000 1 +04}
{465343200 14400 0 +04}
- {481068000 18000 1 +05}
+ {481068000 18000 1 +04}
{496792800 14400 0 +04}
- {512517600 18000 1 +05}
+ {512517600 18000 1 +04}
{528242400 14400 0 +04}
- {543967200 18000 1 +05}
+ {543967200 18000 1 +04}
{559692000 14400 0 +04}
- {575416800 18000 1 +05}
+ {575416800 18000 1 +04}
{591141600 14400 0 +04}
- {606866400 18000 1 +05}
+ {606866400 18000 1 +04}
{622591200 14400 0 +04}
- {638316000 18000 1 +05}
+ {638316000 18000 1 +04}
{654645600 14400 0 +04}
{670370400 10800 0 +03}
- {670374000 14400 1 +04}
+ {670374000 14400 1 +03}
{686098800 10800 0 +03}
- {701823600 14400 1 +04}
+ {701823600 14400 1 +03}
{717548400 10800 0 +03}
- {733273200 14400 1 +04}
+ {733273200 14400 1 +03}
{748998000 10800 0 +03}
- {764722800 14400 1 +04}
+ {764722800 14400 1 +03}
{780447600 10800 0 +03}
- {796172400 14400 1 +04}
+ {796172400 14400 1 +03}
{811897200 14400 0 +04}
{852062400 14400 0 +04}
- {859672800 18000 1 +05}
+ {859672800 18000 1 +04}
{877816800 14400 0 +04}
- {891122400 18000 1 +05}
+ {891122400 18000 1 +04}
{909266400 14400 0 +04}
- {922572000 18000 1 +05}
+ {922572000 18000 1 +04}
{941320800 14400 0 +04}
- {954021600 18000 1 +05}
+ {954021600 18000 1 +04}
{972770400 14400 0 +04}
- {985471200 18000 1 +05}
+ {985471200 18000 1 +04}
{1004220000 14400 0 +04}
- {1017525600 18000 1 +05}
+ {1017525600 18000 1 +04}
{1035669600 14400 0 +04}
- {1048975200 18000 1 +05}
+ {1048975200 18000 1 +04}
{1067119200 14400 0 +04}
- {1080424800 18000 1 +05}
+ {1080424800 18000 1 +04}
{1099173600 14400 0 +04}
- {1111874400 18000 1 +05}
+ {1111874400 18000 1 +04}
{1130623200 14400 0 +04}
- {1143324000 18000 1 +05}
+ {1143324000 18000 1 +04}
{1162072800 14400 0 +04}
- {1174773600 18000 1 +05}
+ {1174773600 18000 1 +04}
{1193522400 14400 0 +04}
- {1206828000 18000 1 +05}
+ {1206828000 18000 1 +04}
{1224972000 14400 0 +04}
- {1238277600 18000 1 +05}
+ {1238277600 18000 1 +04}
{1256421600 14400 0 +04}
- {1269727200 18000 1 +05}
+ {1269727200 18000 1 +04}
{1288476000 14400 0 +04}
{1293825600 14400 0 +04}
- {1301176800 18000 1 +05}
+ {1301176800 18000 1 +04}
{1319925600 14400 0 +04}
}
diff --git a/tcl8.6/library/tzdata/Atlantic/Azores b/tcl8.6/library/tzdata/Atlantic/Azores
index a9bec94..088dd9a 100644
--- a/tcl8.6/library/tzdata/Atlantic/Azores
+++ b/tcl8.6/library/tzdata/Atlantic/Azores
@@ -3,7 +3,7 @@
set TZData(:Atlantic/Azores) {
{-9223372036854775808 -6160 0 LMT}
{-2713904240 -6872 0 HMT}
- {-1830377128 -7200 0 -02}
+ {-1830376800 -7200 0 -02}
{-1689548400 -3600 1 -01}
{-1677794400 -7200 0 -02}
{-1667430000 -3600 1 -01}
diff --git a/tcl8.6/library/tzdata/Atlantic/Cape_Verde b/tcl8.6/library/tzdata/Atlantic/Cape_Verde
index 6fc94eb..595db0b 100644
--- a/tcl8.6/library/tzdata/Atlantic/Cape_Verde
+++ b/tcl8.6/library/tzdata/Atlantic/Cape_Verde
@@ -2,7 +2,7 @@
set TZData(:Atlantic/Cape_Verde) {
{-9223372036854775808 -5644 0 LMT}
- {-1988144756 -7200 0 -02}
+ {-1830376800 -7200 0 -02}
{-862610400 -3600 1 -01}
{-764118000 -7200 0 -02}
{186120000 -3600 0 -01}
diff --git a/tcl8.6/library/tzdata/Atlantic/Madeira b/tcl8.6/library/tzdata/Atlantic/Madeira
index cc5e5f8..fed9c19 100644
--- a/tcl8.6/library/tzdata/Atlantic/Madeira
+++ b/tcl8.6/library/tzdata/Atlantic/Madeira
@@ -3,7 +3,7 @@
set TZData(:Atlantic/Madeira) {
{-9223372036854775808 -4056 0 LMT}
{-2713906344 -4056 0 FMT}
- {-1830379944 -3600 0 -01}
+ {-1830380400 -3600 0 -01}
{-1689552000 0 1 +00}
{-1677798000 -3600 0 -01}
{-1667433600 0 1 +00}
diff --git a/tcl8.6/library/tzdata/Atlantic/Reykjavik b/tcl8.6/library/tzdata/Atlantic/Reykjavik
index 5555460..6270572 100644
--- a/tcl8.6/library/tzdata/Atlantic/Reykjavik
+++ b/tcl8.6/library/tzdata/Atlantic/Reykjavik
@@ -3,71 +3,71 @@
set TZData(:Atlantic/Reykjavik) {
{-9223372036854775808 -5280 0 LMT}
{-1956609120 -3600 0 -01}
- {-1668211200 0 1 +00}
+ {-1668211200 0 1 -01}
{-1647212400 -3600 0 -01}
- {-1636675200 0 1 +00}
+ {-1636675200 0 1 -01}
{-1613430000 -3600 0 -01}
- {-1605139200 0 1 +00}
+ {-1605139200 0 1 -01}
{-1581894000 -3600 0 -01}
- {-1539561600 0 1 +00}
+ {-1539561600 0 1 -01}
{-1531350000 -3600 0 -01}
- {-968025600 0 1 +00}
+ {-968025600 0 1 -01}
{-952293600 -3600 0 -01}
- {-942008400 0 1 +00}
+ {-942008400 0 1 -01}
{-920239200 -3600 0 -01}
- {-909957600 0 1 +00}
+ {-909957600 0 1 -01}
{-888789600 -3600 0 -01}
- {-877903200 0 1 +00}
+ {-877903200 0 1 -01}
{-857944800 -3600 0 -01}
- {-846453600 0 1 +00}
+ {-846453600 0 1 -01}
{-826495200 -3600 0 -01}
- {-815004000 0 1 +00}
+ {-815004000 0 1 -01}
{-795045600 -3600 0 -01}
- {-783554400 0 1 +00}
+ {-783554400 0 1 -01}
{-762991200 -3600 0 -01}
- {-752104800 0 1 +00}
+ {-752104800 0 1 -01}
{-731541600 -3600 0 -01}
- {-717631200 0 1 +00}
+ {-717631200 0 1 -01}
{-700092000 -3600 0 -01}
- {-686181600 0 1 +00}
+ {-686181600 0 1 -01}
{-668642400 -3600 0 -01}
- {-654732000 0 1 +00}
+ {-654732000 0 1 -01}
{-636588000 -3600 0 -01}
- {-623282400 0 1 +00}
+ {-623282400 0 1 -01}
{-605743200 -3600 0 -01}
- {-591832800 0 1 +00}
+ {-591832800 0 1 -01}
{-573688800 -3600 0 -01}
- {-559778400 0 1 +00}
+ {-559778400 0 1 -01}
{-542239200 -3600 0 -01}
- {-528328800 0 1 +00}
+ {-528328800 0 1 -01}
{-510789600 -3600 0 -01}
- {-496879200 0 1 +00}
+ {-496879200 0 1 -01}
{-479340000 -3600 0 -01}
- {-465429600 0 1 +00}
+ {-465429600 0 1 -01}
{-447890400 -3600 0 -01}
- {-433980000 0 1 +00}
+ {-433980000 0 1 -01}
{-415836000 -3600 0 -01}
- {-401925600 0 1 +00}
+ {-401925600 0 1 -01}
{-384386400 -3600 0 -01}
- {-370476000 0 1 +00}
+ {-370476000 0 1 -01}
{-352936800 -3600 0 -01}
- {-339026400 0 1 +00}
+ {-339026400 0 1 -01}
{-321487200 -3600 0 -01}
- {-307576800 0 1 +00}
+ {-307576800 0 1 -01}
{-290037600 -3600 0 -01}
- {-276127200 0 1 +00}
+ {-276127200 0 1 -01}
{-258588000 -3600 0 -01}
- {-244677600 0 1 +00}
+ {-244677600 0 1 -01}
{-226533600 -3600 0 -01}
- {-212623200 0 1 +00}
+ {-212623200 0 1 -01}
{-195084000 -3600 0 -01}
- {-181173600 0 1 +00}
+ {-181173600 0 1 -01}
{-163634400 -3600 0 -01}
- {-149724000 0 1 +00}
+ {-149724000 0 1 -01}
{-132184800 -3600 0 -01}
- {-118274400 0 1 +00}
+ {-118274400 0 1 -01}
{-100735200 -3600 0 -01}
- {-86824800 0 1 +00}
+ {-86824800 0 1 -01}
{-68680800 -3600 0 -01}
{-54770400 0 0 GMT}
}
diff --git a/tcl8.6/library/tzdata/Atlantic/Stanley b/tcl8.6/library/tzdata/Atlantic/Stanley
index 5210832..48473ca 100644
--- a/tcl8.6/library/tzdata/Atlantic/Stanley
+++ b/tcl8.6/library/tzdata/Atlantic/Stanley
@@ -4,72 +4,72 @@ set TZData(:Atlantic/Stanley) {
{-9223372036854775808 -13884 0 LMT}
{-2524507716 -13884 0 SMT}
{-1824235716 -14400 0 -04}
- {-1018209600 -10800 1 -03}
+ {-1018209600 -10800 1 -04}
{-1003093200 -14400 0 -04}
- {-986760000 -10800 1 -03}
+ {-986760000 -10800 1 -04}
{-971643600 -14400 0 -04}
- {-954705600 -10800 1 -03}
+ {-954705600 -10800 1 -04}
{-939589200 -14400 0 -04}
- {-923256000 -10800 1 -03}
+ {-923256000 -10800 1 -04}
{-908139600 -14400 0 -04}
- {-891806400 -10800 1 -03}
+ {-891806400 -10800 1 -04}
{-876690000 -14400 0 -04}
- {-860356800 -10800 1 -03}
+ {-860356800 -10800 1 -04}
{420606000 -7200 0 -03}
- {433303200 -7200 1 -02}
+ {433303200 -7200 1 -03}
{452052000 -10800 0 -03}
- {464151600 -7200 1 -02}
+ {464151600 -7200 1 -03}
{483501600 -10800 0 -03}
{495597600 -14400 0 -04}
- {495604800 -10800 1 -03}
+ {495604800 -10800 1 -04}
{514350000 -14400 0 -04}
- {527054400 -10800 1 -03}
+ {527054400 -10800 1 -04}
{545799600 -14400 0 -04}
- {558504000 -10800 1 -03}
+ {558504000 -10800 1 -04}
{577249200 -14400 0 -04}
- {589953600 -10800 1 -03}
+ {589953600 -10800 1 -04}
{608698800 -14400 0 -04}
- {621403200 -10800 1 -03}
+ {621403200 -10800 1 -04}
{640753200 -14400 0 -04}
- {652852800 -10800 1 -03}
+ {652852800 -10800 1 -04}
{672202800 -14400 0 -04}
- {684907200 -10800 1 -03}
+ {684907200 -10800 1 -04}
{703652400 -14400 0 -04}
- {716356800 -10800 1 -03}
+ {716356800 -10800 1 -04}
{735102000 -14400 0 -04}
- {747806400 -10800 1 -03}
+ {747806400 -10800 1 -04}
{766551600 -14400 0 -04}
- {779256000 -10800 1 -03}
+ {779256000 -10800 1 -04}
{798001200 -14400 0 -04}
- {810705600 -10800 1 -03}
+ {810705600 -10800 1 -04}
{830055600 -14400 0 -04}
- {842760000 -10800 1 -03}
+ {842760000 -10800 1 -04}
{861505200 -14400 0 -04}
- {874209600 -10800 1 -03}
+ {874209600 -10800 1 -04}
{892954800 -14400 0 -04}
- {905659200 -10800 1 -03}
+ {905659200 -10800 1 -04}
{924404400 -14400 0 -04}
- {937108800 -10800 1 -03}
+ {937108800 -10800 1 -04}
{955854000 -14400 0 -04}
- {968558400 -10800 1 -03}
+ {968558400 -10800 1 -04}
{987310800 -14400 0 -04}
- {999410400 -10800 1 -03}
+ {999410400 -10800 1 -04}
{1019365200 -14400 0 -04}
- {1030860000 -10800 1 -03}
+ {1030860000 -10800 1 -04}
{1050814800 -14400 0 -04}
- {1062914400 -10800 1 -03}
+ {1062914400 -10800 1 -04}
{1082264400 -14400 0 -04}
- {1094364000 -10800 1 -03}
+ {1094364000 -10800 1 -04}
{1113714000 -14400 0 -04}
- {1125813600 -10800 1 -03}
+ {1125813600 -10800 1 -04}
{1145163600 -14400 0 -04}
- {1157263200 -10800 1 -03}
+ {1157263200 -10800 1 -04}
{1176613200 -14400 0 -04}
- {1188712800 -10800 1 -03}
+ {1188712800 -10800 1 -04}
{1208667600 -14400 0 -04}
- {1220767200 -10800 1 -03}
+ {1220767200 -10800 1 -04}
{1240117200 -14400 0 -04}
- {1252216800 -10800 1 -03}
+ {1252216800 -10800 1 -04}
{1271566800 -14400 0 -04}
{1283662800 -10800 0 -03}
}
diff --git a/tcl8.6/library/tzdata/Australia/Lord_Howe b/tcl8.6/library/tzdata/Australia/Lord_Howe
index 0e2405e..c595967 100644
--- a/tcl8.6/library/tzdata/Australia/Lord_Howe
+++ b/tcl8.6/library/tzdata/Australia/Lord_Howe
@@ -3,243 +3,243 @@
set TZData(:Australia/Lord_Howe) {
{-9223372036854775808 38180 0 LMT}
{-2364114980 36000 0 AEST}
- {352216800 37800 0 +1130}
- {372785400 41400 1 +1130}
- {384273000 37800 0 +1130}
- {404839800 41400 1 +1130}
- {415722600 37800 0 +1130}
- {436289400 41400 1 +1130}
- {447172200 37800 0 +1130}
- {467739000 41400 1 +1130}
- {478621800 37800 0 +1130}
- {488984400 37800 0 +11}
- {499188600 39600 1 +11}
- {511282800 37800 0 +11}
- {530033400 39600 1 +11}
- {542732400 37800 0 +11}
- {562087800 39600 1 +11}
- {574786800 37800 0 +11}
- {594142200 39600 1 +11}
- {606236400 37800 0 +11}
- {625591800 39600 1 +11}
- {636476400 37800 0 +11}
- {657041400 39600 1 +11}
- {667926000 37800 0 +11}
- {688491000 39600 1 +11}
- {699375600 37800 0 +11}
- {719940600 39600 1 +11}
- {731430000 37800 0 +11}
- {751995000 39600 1 +11}
- {762879600 37800 0 +11}
- {783444600 39600 1 +11}
- {794329200 37800 0 +11}
- {814894200 39600 1 +11}
- {828198000 37800 0 +11}
- {846343800 39600 1 +11}
- {859647600 37800 0 +11}
- {877793400 39600 1 +11}
- {891097200 37800 0 +11}
- {909243000 39600 1 +11}
- {922546800 37800 0 +11}
- {941297400 39600 1 +11}
- {953996400 37800 0 +11}
- {967303800 39600 1 +11}
- {985446000 37800 0 +11}
- {1004196600 39600 1 +11}
- {1017500400 37800 0 +11}
- {1035646200 39600 1 +11}
- {1048950000 37800 0 +11}
- {1067095800 39600 1 +11}
- {1080399600 37800 0 +11}
- {1099150200 39600 1 +11}
- {1111849200 37800 0 +11}
- {1130599800 39600 1 +11}
- {1143903600 37800 0 +11}
- {1162049400 39600 1 +11}
- {1174748400 37800 0 +11}
- {1193499000 39600 1 +11}
- {1207407600 37800 0 +11}
- {1223134200 39600 1 +11}
- {1238857200 37800 0 +11}
- {1254583800 39600 1 +11}
- {1270306800 37800 0 +11}
- {1286033400 39600 1 +11}
- {1301756400 37800 0 +11}
- {1317483000 39600 1 +11}
- {1333206000 37800 0 +11}
- {1349537400 39600 1 +11}
- {1365260400 37800 0 +11}
- {1380987000 39600 1 +11}
- {1396710000 37800 0 +11}
- {1412436600 39600 1 +11}
- {1428159600 37800 0 +11}
- {1443886200 39600 1 +11}
- {1459609200 37800 0 +11}
- {1475335800 39600 1 +11}
- {1491058800 37800 0 +11}
- {1506785400 39600 1 +11}
- {1522508400 37800 0 +11}
- {1538839800 39600 1 +11}
- {1554562800 37800 0 +11}
- {1570289400 39600 1 +11}
- {1586012400 37800 0 +11}
- {1601739000 39600 1 +11}
- {1617462000 37800 0 +11}
- {1633188600 39600 1 +11}
- {1648911600 37800 0 +11}
- {1664638200 39600 1 +11}
- {1680361200 37800 0 +11}
- {1696087800 39600 1 +11}
- {1712415600 37800 0 +11}
- {1728142200 39600 1 +11}
- {1743865200 37800 0 +11}
- {1759591800 39600 1 +11}
- {1775314800 37800 0 +11}
- {1791041400 39600 1 +11}
- {1806764400 37800 0 +11}
- {1822491000 39600 1 +11}
- {1838214000 37800 0 +11}
- {1853940600 39600 1 +11}
- {1869663600 37800 0 +11}
- {1885995000 39600 1 +11}
- {1901718000 37800 0 +11}
- {1917444600 39600 1 +11}
- {1933167600 37800 0 +11}
- {1948894200 39600 1 +11}
- {1964617200 37800 0 +11}
- {1980343800 39600 1 +11}
- {1996066800 37800 0 +11}
- {2011793400 39600 1 +11}
- {2027516400 37800 0 +11}
- {2043243000 39600 1 +11}
- {2058966000 37800 0 +11}
- {2075297400 39600 1 +11}
- {2091020400 37800 0 +11}
- {2106747000 39600 1 +11}
- {2122470000 37800 0 +11}
- {2138196600 39600 1 +11}
- {2153919600 37800 0 +11}
- {2169646200 39600 1 +11}
- {2185369200 37800 0 +11}
- {2201095800 39600 1 +11}
- {2216818800 37800 0 +11}
- {2233150200 39600 1 +11}
- {2248873200 37800 0 +11}
- {2264599800 39600 1 +11}
- {2280322800 37800 0 +11}
- {2296049400 39600 1 +11}
- {2311772400 37800 0 +11}
- {2327499000 39600 1 +11}
- {2343222000 37800 0 +11}
- {2358948600 39600 1 +11}
- {2374671600 37800 0 +11}
- {2390398200 39600 1 +11}
- {2406121200 37800 0 +11}
- {2422452600 39600 1 +11}
- {2438175600 37800 0 +11}
- {2453902200 39600 1 +11}
- {2469625200 37800 0 +11}
- {2485351800 39600 1 +11}
- {2501074800 37800 0 +11}
- {2516801400 39600 1 +11}
- {2532524400 37800 0 +11}
- {2548251000 39600 1 +11}
- {2563974000 37800 0 +11}
- {2579700600 39600 1 +11}
- {2596028400 37800 0 +11}
- {2611755000 39600 1 +11}
- {2627478000 37800 0 +11}
- {2643204600 39600 1 +11}
- {2658927600 37800 0 +11}
- {2674654200 39600 1 +11}
- {2690377200 37800 0 +11}
- {2706103800 39600 1 +11}
- {2721826800 37800 0 +11}
- {2737553400 39600 1 +11}
- {2753276400 37800 0 +11}
- {2769607800 39600 1 +11}
- {2785330800 37800 0 +11}
- {2801057400 39600 1 +11}
- {2816780400 37800 0 +11}
- {2832507000 39600 1 +11}
- {2848230000 37800 0 +11}
- {2863956600 39600 1 +11}
- {2879679600 37800 0 +11}
- {2895406200 39600 1 +11}
- {2911129200 37800 0 +11}
- {2926855800 39600 1 +11}
- {2942578800 37800 0 +11}
- {2958910200 39600 1 +11}
- {2974633200 37800 0 +11}
- {2990359800 39600 1 +11}
- {3006082800 37800 0 +11}
- {3021809400 39600 1 +11}
- {3037532400 37800 0 +11}
- {3053259000 39600 1 +11}
- {3068982000 37800 0 +11}
- {3084708600 39600 1 +11}
- {3100431600 37800 0 +11}
- {3116763000 39600 1 +11}
- {3132486000 37800 0 +11}
- {3148212600 39600 1 +11}
- {3163935600 37800 0 +11}
- {3179662200 39600 1 +11}
- {3195385200 37800 0 +11}
- {3211111800 39600 1 +11}
- {3226834800 37800 0 +11}
- {3242561400 39600 1 +11}
- {3258284400 37800 0 +11}
- {3274011000 39600 1 +11}
- {3289734000 37800 0 +11}
- {3306065400 39600 1 +11}
- {3321788400 37800 0 +11}
- {3337515000 39600 1 +11}
- {3353238000 37800 0 +11}
- {3368964600 39600 1 +11}
- {3384687600 37800 0 +11}
- {3400414200 39600 1 +11}
- {3416137200 37800 0 +11}
- {3431863800 39600 1 +11}
- {3447586800 37800 0 +11}
- {3463313400 39600 1 +11}
- {3479641200 37800 0 +11}
- {3495367800 39600 1 +11}
- {3511090800 37800 0 +11}
- {3526817400 39600 1 +11}
- {3542540400 37800 0 +11}
- {3558267000 39600 1 +11}
- {3573990000 37800 0 +11}
- {3589716600 39600 1 +11}
- {3605439600 37800 0 +11}
- {3621166200 39600 1 +11}
- {3636889200 37800 0 +11}
- {3653220600 39600 1 +11}
- {3668943600 37800 0 +11}
- {3684670200 39600 1 +11}
- {3700393200 37800 0 +11}
- {3716119800 39600 1 +11}
- {3731842800 37800 0 +11}
- {3747569400 39600 1 +11}
- {3763292400 37800 0 +11}
- {3779019000 39600 1 +11}
- {3794742000 37800 0 +11}
- {3810468600 39600 1 +11}
- {3826191600 37800 0 +11}
- {3842523000 39600 1 +11}
- {3858246000 37800 0 +11}
- {3873972600 39600 1 +11}
- {3889695600 37800 0 +11}
- {3905422200 39600 1 +11}
- {3921145200 37800 0 +11}
- {3936871800 39600 1 +11}
- {3952594800 37800 0 +11}
- {3968321400 39600 1 +11}
- {3984044400 37800 0 +11}
- {4000375800 39600 1 +11}
- {4016098800 37800 0 +11}
- {4031825400 39600 1 +11}
- {4047548400 37800 0 +11}
- {4063275000 39600 1 +11}
- {4078998000 37800 0 +11}
- {4094724600 39600 1 +11}
+ {352216800 37800 0 +1030}
+ {372785400 41400 1 +1030}
+ {384273000 37800 0 +1030}
+ {404839800 41400 1 +1030}
+ {415722600 37800 0 +1030}
+ {436289400 41400 1 +1030}
+ {447172200 37800 0 +1030}
+ {467739000 41400 1 +1030}
+ {478621800 37800 0 +1030}
+ {488984400 37800 0 +1030}
+ {499188600 39600 1 +1030}
+ {511282800 37800 0 +1030}
+ {530033400 39600 1 +1030}
+ {542732400 37800 0 +1030}
+ {562087800 39600 1 +1030}
+ {574786800 37800 0 +1030}
+ {594142200 39600 1 +1030}
+ {606236400 37800 0 +1030}
+ {625591800 39600 1 +1030}
+ {636476400 37800 0 +1030}
+ {657041400 39600 1 +1030}
+ {667926000 37800 0 +1030}
+ {688491000 39600 1 +1030}
+ {699375600 37800 0 +1030}
+ {719940600 39600 1 +1030}
+ {731430000 37800 0 +1030}
+ {751995000 39600 1 +1030}
+ {762879600 37800 0 +1030}
+ {783444600 39600 1 +1030}
+ {794329200 37800 0 +1030}
+ {814894200 39600 1 +1030}
+ {828198000 37800 0 +1030}
+ {846343800 39600 1 +1030}
+ {859647600 37800 0 +1030}
+ {877793400 39600 1 +1030}
+ {891097200 37800 0 +1030}
+ {909243000 39600 1 +1030}
+ {922546800 37800 0 +1030}
+ {941297400 39600 1 +1030}
+ {953996400 37800 0 +1030}
+ {967303800 39600 1 +1030}
+ {985446000 37800 0 +1030}
+ {1004196600 39600 1 +1030}
+ {1017500400 37800 0 +1030}
+ {1035646200 39600 1 +1030}
+ {1048950000 37800 0 +1030}
+ {1067095800 39600 1 +1030}
+ {1080399600 37800 0 +1030}
+ {1099150200 39600 1 +1030}
+ {1111849200 37800 0 +1030}
+ {1130599800 39600 1 +1030}
+ {1143903600 37800 0 +1030}
+ {1162049400 39600 1 +1030}
+ {1174748400 37800 0 +1030}
+ {1193499000 39600 1 +1030}
+ {1207407600 37800 0 +1030}
+ {1223134200 39600 1 +1030}
+ {1238857200 37800 0 +1030}
+ {1254583800 39600 1 +1030}
+ {1270306800 37800 0 +1030}
+ {1286033400 39600 1 +1030}
+ {1301756400 37800 0 +1030}
+ {1317483000 39600 1 +1030}
+ {1333206000 37800 0 +1030}
+ {1349537400 39600 1 +1030}
+ {1365260400 37800 0 +1030}
+ {1380987000 39600 1 +1030}
+ {1396710000 37800 0 +1030}
+ {1412436600 39600 1 +1030}
+ {1428159600 37800 0 +1030}
+ {1443886200 39600 1 +1030}
+ {1459609200 37800 0 +1030}
+ {1475335800 39600 1 +1030}
+ {1491058800 37800 0 +1030}
+ {1506785400 39600 1 +1030}
+ {1522508400 37800 0 +1030}
+ {1538839800 39600 1 +1030}
+ {1554562800 37800 0 +1030}
+ {1570289400 39600 1 +1030}
+ {1586012400 37800 0 +1030}
+ {1601739000 39600 1 +1030}
+ {1617462000 37800 0 +1030}
+ {1633188600 39600 1 +1030}
+ {1648911600 37800 0 +1030}
+ {1664638200 39600 1 +1030}
+ {1680361200 37800 0 +1030}
+ {1696087800 39600 1 +1030}
+ {1712415600 37800 0 +1030}
+ {1728142200 39600 1 +1030}
+ {1743865200 37800 0 +1030}
+ {1759591800 39600 1 +1030}
+ {1775314800 37800 0 +1030}
+ {1791041400 39600 1 +1030}
+ {1806764400 37800 0 +1030}
+ {1822491000 39600 1 +1030}
+ {1838214000 37800 0 +1030}
+ {1853940600 39600 1 +1030}
+ {1869663600 37800 0 +1030}
+ {1885995000 39600 1 +1030}
+ {1901718000 37800 0 +1030}
+ {1917444600 39600 1 +1030}
+ {1933167600 37800 0 +1030}
+ {1948894200 39600 1 +1030}
+ {1964617200 37800 0 +1030}
+ {1980343800 39600 1 +1030}
+ {1996066800 37800 0 +1030}
+ {2011793400 39600 1 +1030}
+ {2027516400 37800 0 +1030}
+ {2043243000 39600 1 +1030}
+ {2058966000 37800 0 +1030}
+ {2075297400 39600 1 +1030}
+ {2091020400 37800 0 +1030}
+ {2106747000 39600 1 +1030}
+ {2122470000 37800 0 +1030}
+ {2138196600 39600 1 +1030}
+ {2153919600 37800 0 +1030}
+ {2169646200 39600 1 +1030}
+ {2185369200 37800 0 +1030}
+ {2201095800 39600 1 +1030}
+ {2216818800 37800 0 +1030}
+ {2233150200 39600 1 +1030}
+ {2248873200 37800 0 +1030}
+ {2264599800 39600 1 +1030}
+ {2280322800 37800 0 +1030}
+ {2296049400 39600 1 +1030}
+ {2311772400 37800 0 +1030}
+ {2327499000 39600 1 +1030}
+ {2343222000 37800 0 +1030}
+ {2358948600 39600 1 +1030}
+ {2374671600 37800 0 +1030}
+ {2390398200 39600 1 +1030}
+ {2406121200 37800 0 +1030}
+ {2422452600 39600 1 +1030}
+ {2438175600 37800 0 +1030}
+ {2453902200 39600 1 +1030}
+ {2469625200 37800 0 +1030}
+ {2485351800 39600 1 +1030}
+ {2501074800 37800 0 +1030}
+ {2516801400 39600 1 +1030}
+ {2532524400 37800 0 +1030}
+ {2548251000 39600 1 +1030}
+ {2563974000 37800 0 +1030}
+ {2579700600 39600 1 +1030}
+ {2596028400 37800 0 +1030}
+ {2611755000 39600 1 +1030}
+ {2627478000 37800 0 +1030}
+ {2643204600 39600 1 +1030}
+ {2658927600 37800 0 +1030}
+ {2674654200 39600 1 +1030}
+ {2690377200 37800 0 +1030}
+ {2706103800 39600 1 +1030}
+ {2721826800 37800 0 +1030}
+ {2737553400 39600 1 +1030}
+ {2753276400 37800 0 +1030}
+ {2769607800 39600 1 +1030}
+ {2785330800 37800 0 +1030}
+ {2801057400 39600 1 +1030}
+ {2816780400 37800 0 +1030}
+ {2832507000 39600 1 +1030}
+ {2848230000 37800 0 +1030}
+ {2863956600 39600 1 +1030}
+ {2879679600 37800 0 +1030}
+ {2895406200 39600 1 +1030}
+ {2911129200 37800 0 +1030}
+ {2926855800 39600 1 +1030}
+ {2942578800 37800 0 +1030}
+ {2958910200 39600 1 +1030}
+ {2974633200 37800 0 +1030}
+ {2990359800 39600 1 +1030}
+ {3006082800 37800 0 +1030}
+ {3021809400 39600 1 +1030}
+ {3037532400 37800 0 +1030}
+ {3053259000 39600 1 +1030}
+ {3068982000 37800 0 +1030}
+ {3084708600 39600 1 +1030}
+ {3100431600 37800 0 +1030}
+ {3116763000 39600 1 +1030}
+ {3132486000 37800 0 +1030}
+ {3148212600 39600 1 +1030}
+ {3163935600 37800 0 +1030}
+ {3179662200 39600 1 +1030}
+ {3195385200 37800 0 +1030}
+ {3211111800 39600 1 +1030}
+ {3226834800 37800 0 +1030}
+ {3242561400 39600 1 +1030}
+ {3258284400 37800 0 +1030}
+ {3274011000 39600 1 +1030}
+ {3289734000 37800 0 +1030}
+ {3306065400 39600 1 +1030}
+ {3321788400 37800 0 +1030}
+ {3337515000 39600 1 +1030}
+ {3353238000 37800 0 +1030}
+ {3368964600 39600 1 +1030}
+ {3384687600 37800 0 +1030}
+ {3400414200 39600 1 +1030}
+ {3416137200 37800 0 +1030}
+ {3431863800 39600 1 +1030}
+ {3447586800 37800 0 +1030}
+ {3463313400 39600 1 +1030}
+ {3479641200 37800 0 +1030}
+ {3495367800 39600 1 +1030}
+ {3511090800 37800 0 +1030}
+ {3526817400 39600 1 +1030}
+ {3542540400 37800 0 +1030}
+ {3558267000 39600 1 +1030}
+ {3573990000 37800 0 +1030}
+ {3589716600 39600 1 +1030}
+ {3605439600 37800 0 +1030}
+ {3621166200 39600 1 +1030}
+ {3636889200 37800 0 +1030}
+ {3653220600 39600 1 +1030}
+ {3668943600 37800 0 +1030}
+ {3684670200 39600 1 +1030}
+ {3700393200 37800 0 +1030}
+ {3716119800 39600 1 +1030}
+ {3731842800 37800 0 +1030}
+ {3747569400 39600 1 +1030}
+ {3763292400 37800 0 +1030}
+ {3779019000 39600 1 +1030}
+ {3794742000 37800 0 +1030}
+ {3810468600 39600 1 +1030}
+ {3826191600 37800 0 +1030}
+ {3842523000 39600 1 +1030}
+ {3858246000 37800 0 +1030}
+ {3873972600 39600 1 +1030}
+ {3889695600 37800 0 +1030}
+ {3905422200 39600 1 +1030}
+ {3921145200 37800 0 +1030}
+ {3936871800 39600 1 +1030}
+ {3952594800 37800 0 +1030}
+ {3968321400 39600 1 +1030}
+ {3984044400 37800 0 +1030}
+ {4000375800 39600 1 +1030}
+ {4016098800 37800 0 +1030}
+ {4031825400 39600 1 +1030}
+ {4047548400 37800 0 +1030}
+ {4063275000 39600 1 +1030}
+ {4078998000 37800 0 +1030}
+ {4094724600 39600 1 +1030}
}
diff --git a/tcl8.6/library/tzdata/Europe/Dublin b/tcl8.6/library/tzdata/Europe/Dublin
index c3a5c0e..56afc93 100644
--- a/tcl8.6/library/tzdata/Europe/Dublin
+++ b/tcl8.6/library/tzdata/Europe/Dublin
@@ -98,262 +98,261 @@ set TZData(:Europe/Dublin) {
{-68680800 0 0 IST}
{-59004000 3600 1 IST}
{-37238400 3600 0 IST}
- {57722400 0 0 IST}
- {69818400 3600 1 IST}
- {89172000 0 0 IST}
- {101268000 3600 1 IST}
- {120621600 0 0 IST}
- {132717600 3600 1 IST}
- {152071200 0 0 IST}
- {164167200 3600 1 IST}
- {183520800 0 0 IST}
- {196221600 3600 1 IST}
- {214970400 0 0 IST}
- {227671200 3600 1 IST}
- {246420000 0 0 IST}
- {259120800 3600 1 IST}
- {278474400 0 0 IST}
- {290570400 3600 1 IST}
- {309924000 0 0 IST}
- {322020000 3600 1 IST}
- {341373600 0 0 IST}
- {354675600 3600 1 IST}
- {372819600 0 0 IST}
- {386125200 3600 1 IST}
- {404269200 0 0 IST}
- {417574800 3600 1 IST}
- {435718800 0 0 IST}
- {449024400 3600 1 IST}
- {467773200 0 0 IST}
- {481078800 3600 1 IST}
- {499222800 0 0 IST}
- {512528400 3600 1 IST}
- {530672400 0 0 IST}
- {543978000 3600 1 IST}
- {562122000 0 0 IST}
- {575427600 3600 1 IST}
- {593571600 0 0 IST}
- {606877200 3600 1 IST}
- {625626000 0 0 IST}
- {638326800 3600 1 IST}
- {657075600 0 0 IST}
- {670381200 3600 1 IST}
- {688525200 0 0 IST}
- {701830800 3600 1 IST}
- {719974800 0 0 IST}
- {733280400 3600 1 IST}
- {751424400 0 0 IST}
- {764730000 3600 1 IST}
- {782874000 0 0 IST}
- {796179600 3600 1 IST}
- {814323600 0 0 IST}
- {820454400 0 0 GMT}
- {828234000 3600 1 IST}
- {846378000 0 0 GMT}
- {859683600 3600 1 IST}
- {877827600 0 0 GMT}
- {891133200 3600 1 IST}
- {909277200 0 0 GMT}
- {922582800 3600 1 IST}
- {941331600 0 0 GMT}
- {954032400 3600 1 IST}
- {972781200 0 0 GMT}
- {985482000 3600 1 IST}
- {1004230800 0 0 GMT}
- {1017536400 3600 1 IST}
- {1035680400 0 0 GMT}
- {1048986000 3600 1 IST}
- {1067130000 0 0 GMT}
- {1080435600 3600 1 IST}
- {1099184400 0 0 GMT}
- {1111885200 3600 1 IST}
- {1130634000 0 0 GMT}
- {1143334800 3600 1 IST}
- {1162083600 0 0 GMT}
- {1174784400 3600 1 IST}
- {1193533200 0 0 GMT}
- {1206838800 3600 1 IST}
- {1224982800 0 0 GMT}
- {1238288400 3600 1 IST}
- {1256432400 0 0 GMT}
- {1269738000 3600 1 IST}
- {1288486800 0 0 GMT}
- {1301187600 3600 1 IST}
- {1319936400 0 0 GMT}
- {1332637200 3600 1 IST}
- {1351386000 0 0 GMT}
- {1364691600 3600 1 IST}
- {1382835600 0 0 GMT}
- {1396141200 3600 1 IST}
- {1414285200 0 0 GMT}
- {1427590800 3600 1 IST}
- {1445734800 0 0 GMT}
- {1459040400 3600 1 IST}
- {1477789200 0 0 GMT}
- {1490490000 3600 1 IST}
- {1509238800 0 0 GMT}
- {1521939600 3600 1 IST}
- {1540688400 0 0 GMT}
- {1553994000 3600 1 IST}
- {1572138000 0 0 GMT}
- {1585443600 3600 1 IST}
- {1603587600 0 0 GMT}
- {1616893200 3600 1 IST}
- {1635642000 0 0 GMT}
- {1648342800 3600 1 IST}
- {1667091600 0 0 GMT}
- {1679792400 3600 1 IST}
- {1698541200 0 0 GMT}
- {1711846800 3600 1 IST}
- {1729990800 0 0 GMT}
- {1743296400 3600 1 IST}
- {1761440400 0 0 GMT}
- {1774746000 3600 1 IST}
- {1792890000 0 0 GMT}
- {1806195600 3600 1 IST}
- {1824944400 0 0 GMT}
- {1837645200 3600 1 IST}
- {1856394000 0 0 GMT}
- {1869094800 3600 1 IST}
- {1887843600 0 0 GMT}
- {1901149200 3600 1 IST}
- {1919293200 0 0 GMT}
- {1932598800 3600 1 IST}
- {1950742800 0 0 GMT}
- {1964048400 3600 1 IST}
- {1982797200 0 0 GMT}
- {1995498000 3600 1 IST}
- {2014246800 0 0 GMT}
- {2026947600 3600 1 IST}
- {2045696400 0 0 GMT}
- {2058397200 3600 1 IST}
- {2077146000 0 0 GMT}
- {2090451600 3600 1 IST}
- {2108595600 0 0 GMT}
- {2121901200 3600 1 IST}
- {2140045200 0 0 GMT}
- {2153350800 3600 1 IST}
- {2172099600 0 0 GMT}
- {2184800400 3600 1 IST}
- {2203549200 0 0 GMT}
- {2216250000 3600 1 IST}
- {2234998800 0 0 GMT}
- {2248304400 3600 1 IST}
- {2266448400 0 0 GMT}
- {2279754000 3600 1 IST}
- {2297898000 0 0 GMT}
- {2311203600 3600 1 IST}
- {2329347600 0 0 GMT}
- {2342653200 3600 1 IST}
- {2361402000 0 0 GMT}
- {2374102800 3600 1 IST}
- {2392851600 0 0 GMT}
- {2405552400 3600 1 IST}
- {2424301200 0 0 GMT}
- {2437606800 3600 1 IST}
- {2455750800 0 0 GMT}
- {2469056400 3600 1 IST}
- {2487200400 0 0 GMT}
- {2500506000 3600 1 IST}
- {2519254800 0 0 GMT}
- {2531955600 3600 1 IST}
- {2550704400 0 0 GMT}
- {2563405200 3600 1 IST}
- {2582154000 0 0 GMT}
- {2595459600 3600 1 IST}
- {2613603600 0 0 GMT}
- {2626909200 3600 1 IST}
- {2645053200 0 0 GMT}
- {2658358800 3600 1 IST}
- {2676502800 0 0 GMT}
- {2689808400 3600 1 IST}
- {2708557200 0 0 GMT}
- {2721258000 3600 1 IST}
- {2740006800 0 0 GMT}
- {2752707600 3600 1 IST}
- {2771456400 0 0 GMT}
- {2784762000 3600 1 IST}
- {2802906000 0 0 GMT}
- {2816211600 3600 1 IST}
- {2834355600 0 0 GMT}
- {2847661200 3600 1 IST}
- {2866410000 0 0 GMT}
- {2879110800 3600 1 IST}
- {2897859600 0 0 GMT}
- {2910560400 3600 1 IST}
- {2929309200 0 0 GMT}
- {2942010000 3600 1 IST}
- {2960758800 0 0 GMT}
- {2974064400 3600 1 IST}
- {2992208400 0 0 GMT}
- {3005514000 3600 1 IST}
- {3023658000 0 0 GMT}
- {3036963600 3600 1 IST}
- {3055712400 0 0 GMT}
- {3068413200 3600 1 IST}
- {3087162000 0 0 GMT}
- {3099862800 3600 1 IST}
- {3118611600 0 0 GMT}
- {3131917200 3600 1 IST}
- {3150061200 0 0 GMT}
- {3163366800 3600 1 IST}
- {3181510800 0 0 GMT}
- {3194816400 3600 1 IST}
- {3212960400 0 0 GMT}
- {3226266000 3600 1 IST}
- {3245014800 0 0 GMT}
- {3257715600 3600 1 IST}
- {3276464400 0 0 GMT}
- {3289165200 3600 1 IST}
- {3307914000 0 0 GMT}
- {3321219600 3600 1 IST}
- {3339363600 0 0 GMT}
- {3352669200 3600 1 IST}
- {3370813200 0 0 GMT}
- {3384118800 3600 1 IST}
- {3402867600 0 0 GMT}
- {3415568400 3600 1 IST}
- {3434317200 0 0 GMT}
- {3447018000 3600 1 IST}
- {3465766800 0 0 GMT}
- {3479072400 3600 1 IST}
- {3497216400 0 0 GMT}
- {3510522000 3600 1 IST}
- {3528666000 0 0 GMT}
- {3541971600 3600 1 IST}
- {3560115600 0 0 GMT}
- {3573421200 3600 1 IST}
- {3592170000 0 0 GMT}
- {3604870800 3600 1 IST}
- {3623619600 0 0 GMT}
- {3636320400 3600 1 IST}
- {3655069200 0 0 GMT}
- {3668374800 3600 1 IST}
- {3686518800 0 0 GMT}
- {3699824400 3600 1 IST}
- {3717968400 0 0 GMT}
- {3731274000 3600 1 IST}
- {3750022800 0 0 GMT}
- {3762723600 3600 1 IST}
- {3781472400 0 0 GMT}
- {3794173200 3600 1 IST}
- {3812922000 0 0 GMT}
- {3825622800 3600 1 IST}
- {3844371600 0 0 GMT}
- {3857677200 3600 1 IST}
- {3875821200 0 0 GMT}
- {3889126800 3600 1 IST}
- {3907270800 0 0 GMT}
- {3920576400 3600 1 IST}
- {3939325200 0 0 GMT}
- {3952026000 3600 1 IST}
- {3970774800 0 0 GMT}
- {3983475600 3600 1 IST}
- {4002224400 0 0 GMT}
- {4015530000 3600 1 IST}
- {4033674000 0 0 GMT}
- {4046979600 3600 1 IST}
- {4065123600 0 0 GMT}
- {4078429200 3600 1 IST}
- {4096573200 0 0 GMT}
+ {57722400 0 1 IST}
+ {69818400 3600 0 IST}
+ {89172000 0 1 IST}
+ {101268000 3600 0 IST}
+ {120621600 0 1 IST}
+ {132717600 3600 0 IST}
+ {152071200 0 1 IST}
+ {164167200 3600 0 IST}
+ {183520800 0 1 IST}
+ {196221600 3600 0 IST}
+ {214970400 0 1 IST}
+ {227671200 3600 0 IST}
+ {246420000 0 1 IST}
+ {259120800 3600 0 IST}
+ {278474400 0 1 IST}
+ {290570400 3600 0 IST}
+ {309924000 0 1 IST}
+ {322020000 3600 0 IST}
+ {341373600 0 1 IST}
+ {354675600 3600 0 IST}
+ {372819600 0 1 IST}
+ {386125200 3600 0 IST}
+ {404269200 0 1 IST}
+ {417574800 3600 0 IST}
+ {435718800 0 1 IST}
+ {449024400 3600 0 IST}
+ {467773200 0 1 IST}
+ {481078800 3600 0 IST}
+ {499222800 0 1 IST}
+ {512528400 3600 0 IST}
+ {530672400 0 1 IST}
+ {543978000 3600 0 IST}
+ {562122000 0 1 IST}
+ {575427600 3600 0 IST}
+ {593571600 0 1 IST}
+ {606877200 3600 0 IST}
+ {625626000 0 1 IST}
+ {638326800 3600 0 IST}
+ {657075600 0 1 IST}
+ {670381200 3600 0 IST}
+ {688525200 0 1 IST}
+ {701830800 3600 0 IST}
+ {719974800 0 1 IST}
+ {733280400 3600 0 IST}
+ {751424400 0 1 IST}
+ {764730000 3600 0 IST}
+ {782874000 0 1 IST}
+ {796179600 3600 0 IST}
+ {814323600 0 1 IST}
+ {828234000 3600 0 IST}
+ {846378000 0 1 IST}
+ {859683600 3600 0 IST}
+ {877827600 0 1 IST}
+ {891133200 3600 0 IST}
+ {909277200 0 1 IST}
+ {922582800 3600 0 IST}
+ {941331600 0 1 IST}
+ {954032400 3600 0 IST}
+ {972781200 0 1 IST}
+ {985482000 3600 0 IST}
+ {1004230800 0 1 IST}
+ {1017536400 3600 0 IST}
+ {1035680400 0 1 IST}
+ {1048986000 3600 0 IST}
+ {1067130000 0 1 IST}
+ {1080435600 3600 0 IST}
+ {1099184400 0 1 IST}
+ {1111885200 3600 0 IST}
+ {1130634000 0 1 IST}
+ {1143334800 3600 0 IST}
+ {1162083600 0 1 IST}
+ {1174784400 3600 0 IST}
+ {1193533200 0 1 IST}
+ {1206838800 3600 0 IST}
+ {1224982800 0 1 IST}
+ {1238288400 3600 0 IST}
+ {1256432400 0 1 IST}
+ {1269738000 3600 0 IST}
+ {1288486800 0 1 IST}
+ {1301187600 3600 0 IST}
+ {1319936400 0 1 IST}
+ {1332637200 3600 0 IST}
+ {1351386000 0 1 IST}
+ {1364691600 3600 0 IST}
+ {1382835600 0 1 IST}
+ {1396141200 3600 0 IST}
+ {1414285200 0 1 IST}
+ {1427590800 3600 0 IST}
+ {1445734800 0 1 IST}
+ {1459040400 3600 0 IST}
+ {1477789200 0 1 IST}
+ {1490490000 3600 0 IST}
+ {1509238800 0 1 IST}
+ {1521939600 3600 0 IST}
+ {1540688400 0 1 IST}
+ {1553994000 3600 0 IST}
+ {1572138000 0 1 IST}
+ {1585443600 3600 0 IST}
+ {1603587600 0 1 IST}
+ {1616893200 3600 0 IST}
+ {1635642000 0 1 IST}
+ {1648342800 3600 0 IST}
+ {1667091600 0 1 IST}
+ {1679792400 3600 0 IST}
+ {1698541200 0 1 IST}
+ {1711846800 3600 0 IST}
+ {1729990800 0 1 IST}
+ {1743296400 3600 0 IST}
+ {1761440400 0 1 IST}
+ {1774746000 3600 0 IST}
+ {1792890000 0 1 IST}
+ {1806195600 3600 0 IST}
+ {1824944400 0 1 IST}
+ {1837645200 3600 0 IST}
+ {1856394000 0 1 IST}
+ {1869094800 3600 0 IST}
+ {1887843600 0 1 IST}
+ {1901149200 3600 0 IST}
+ {1919293200 0 1 IST}
+ {1932598800 3600 0 IST}
+ {1950742800 0 1 IST}
+ {1964048400 3600 0 IST}
+ {1982797200 0 1 IST}
+ {1995498000 3600 0 IST}
+ {2014246800 0 1 IST}
+ {2026947600 3600 0 IST}
+ {2045696400 0 1 IST}
+ {2058397200 3600 0 IST}
+ {2077146000 0 1 IST}
+ {2090451600 3600 0 IST}
+ {2108595600 0 1 IST}
+ {2121901200 3600 0 IST}
+ {2140045200 0 1 IST}
+ {2153350800 3600 0 IST}
+ {2172099600 0 1 IST}
+ {2184800400 3600 0 IST}
+ {2203549200 0 1 IST}
+ {2216250000 3600 0 IST}
+ {2234998800 0 1 IST}
+ {2248304400 3600 0 IST}
+ {2266448400 0 1 IST}
+ {2279754000 3600 0 IST}
+ {2297898000 0 1 IST}
+ {2311203600 3600 0 IST}
+ {2329347600 0 1 IST}
+ {2342653200 3600 0 IST}
+ {2361402000 0 1 IST}
+ {2374102800 3600 0 IST}
+ {2392851600 0 1 IST}
+ {2405552400 3600 0 IST}
+ {2424301200 0 1 IST}
+ {2437606800 3600 0 IST}
+ {2455750800 0 1 IST}
+ {2469056400 3600 0 IST}
+ {2487200400 0 1 IST}
+ {2500506000 3600 0 IST}
+ {2519254800 0 1 IST}
+ {2531955600 3600 0 IST}
+ {2550704400 0 1 IST}
+ {2563405200 3600 0 IST}
+ {2582154000 0 1 IST}
+ {2595459600 3600 0 IST}
+ {2613603600 0 1 IST}
+ {2626909200 3600 0 IST}
+ {2645053200 0 1 IST}
+ {2658358800 3600 0 IST}
+ {2676502800 0 1 IST}
+ {2689808400 3600 0 IST}
+ {2708557200 0 1 IST}
+ {2721258000 3600 0 IST}
+ {2740006800 0 1 IST}
+ {2752707600 3600 0 IST}
+ {2771456400 0 1 IST}
+ {2784762000 3600 0 IST}
+ {2802906000 0 1 IST}
+ {2816211600 3600 0 IST}
+ {2834355600 0 1 IST}
+ {2847661200 3600 0 IST}
+ {2866410000 0 1 IST}
+ {2879110800 3600 0 IST}
+ {2897859600 0 1 IST}
+ {2910560400 3600 0 IST}
+ {2929309200 0 1 IST}
+ {2942010000 3600 0 IST}
+ {2960758800 0 1 IST}
+ {2974064400 3600 0 IST}
+ {2992208400 0 1 IST}
+ {3005514000 3600 0 IST}
+ {3023658000 0 1 IST}
+ {3036963600 3600 0 IST}
+ {3055712400 0 1 IST}
+ {3068413200 3600 0 IST}
+ {3087162000 0 1 IST}
+ {3099862800 3600 0 IST}
+ {3118611600 0 1 IST}
+ {3131917200 3600 0 IST}
+ {3150061200 0 1 IST}
+ {3163366800 3600 0 IST}
+ {3181510800 0 1 IST}
+ {3194816400 3600 0 IST}
+ {3212960400 0 1 IST}
+ {3226266000 3600 0 IST}
+ {3245014800 0 1 IST}
+ {3257715600 3600 0 IST}
+ {3276464400 0 1 IST}
+ {3289165200 3600 0 IST}
+ {3307914000 0 1 IST}
+ {3321219600 3600 0 IST}
+ {3339363600 0 1 IST}
+ {3352669200 3600 0 IST}
+ {3370813200 0 1 IST}
+ {3384118800 3600 0 IST}
+ {3402867600 0 1 IST}
+ {3415568400 3600 0 IST}
+ {3434317200 0 1 IST}
+ {3447018000 3600 0 IST}
+ {3465766800 0 1 IST}
+ {3479072400 3600 0 IST}
+ {3497216400 0 1 IST}
+ {3510522000 3600 0 IST}
+ {3528666000 0 1 IST}
+ {3541971600 3600 0 IST}
+ {3560115600 0 1 IST}
+ {3573421200 3600 0 IST}
+ {3592170000 0 1 IST}
+ {3604870800 3600 0 IST}
+ {3623619600 0 1 IST}
+ {3636320400 3600 0 IST}
+ {3655069200 0 1 IST}
+ {3668374800 3600 0 IST}
+ {3686518800 0 1 IST}
+ {3699824400 3600 0 IST}
+ {3717968400 0 1 IST}
+ {3731274000 3600 0 IST}
+ {3750022800 0 1 IST}
+ {3762723600 3600 0 IST}
+ {3781472400 0 1 IST}
+ {3794173200 3600 0 IST}
+ {3812922000 0 1 IST}
+ {3825622800 3600 0 IST}
+ {3844371600 0 1 IST}
+ {3857677200 3600 0 IST}
+ {3875821200 0 1 IST}
+ {3889126800 3600 0 IST}
+ {3907270800 0 1 IST}
+ {3920576400 3600 0 IST}
+ {3939325200 0 1 IST}
+ {3952026000 3600 0 IST}
+ {3970774800 0 1 IST}
+ {3983475600 3600 0 IST}
+ {4002224400 0 1 IST}
+ {4015530000 3600 0 IST}
+ {4033674000 0 1 IST}
+ {4046979600 3600 0 IST}
+ {4065123600 0 1 IST}
+ {4078429200 3600 0 IST}
+ {4096573200 0 1 IST}
}
diff --git a/tcl8.6/library/tzdata/Europe/Lisbon b/tcl8.6/library/tzdata/Europe/Lisbon
index 7168f96..b566b51 100644
--- a/tcl8.6/library/tzdata/Europe/Lisbon
+++ b/tcl8.6/library/tzdata/Europe/Lisbon
@@ -3,7 +3,7 @@
set TZData(:Europe/Lisbon) {
{-9223372036854775808 -2205 0 LMT}
{-2713908195 -2205 0 LMT}
- {-1830381795 0 0 WET}
+ {-1830384000 0 0 WET}
{-1689555600 3600 1 WEST}
{-1677801600 0 0 WET}
{-1667437200 3600 1 WEST}
diff --git a/tcl8.6/library/tzdata/Europe/Prague b/tcl8.6/library/tzdata/Europe/Prague
index 222b1ae..34df8ed 100644
--- a/tcl8.6/library/tzdata/Europe/Prague
+++ b/tcl8.6/library/tzdata/Europe/Prague
@@ -15,11 +15,14 @@ set TZData(:Europe/Prague) {
{-844556400 7200 1 CEST}
{-828226800 3600 0 CET}
{-812502000 7200 1 CEST}
- {-798073200 3600 0 CET}
- {-780534000 7200 1 CEST}
- {-761180400 3600 0 CET}
+ {-796777200 3600 0 CET}
+ {-781052400 7200 1 CEST}
+ {-777862800 7200 0 CEST}
+ {-765327600 3600 0 CET}
{-746578800 7200 1 CEST}
{-733359600 3600 0 CET}
+ {-728517600 0 1 GMT}
+ {-721260000 0 0 CET}
{-716425200 7200 1 CEST}
{-701910000 3600 0 CET}
{-684975600 7200 1 CEST}
diff --git a/tcl8.6/library/tzdata/Europe/Volgograd b/tcl8.6/library/tzdata/Europe/Volgograd
index 05e1044..3938683 100644
--- a/tcl8.6/library/tzdata/Europe/Volgograd
+++ b/tcl8.6/library/tzdata/Europe/Volgograd
@@ -68,4 +68,5 @@ set TZData(:Europe/Volgograd) {
{1288479600 10800 0 +03}
{1301180400 14400 0 +04}
{1414274400 10800 0 +03}
+ {1540681200 14400 0 +04}
}
diff --git a/tcl8.6/library/tzdata/Indian/Mauritius b/tcl8.6/library/tzdata/Indian/Mauritius
index 2a7a0b1..4c9a051 100644
--- a/tcl8.6/library/tzdata/Indian/Mauritius
+++ b/tcl8.6/library/tzdata/Indian/Mauritius
@@ -3,8 +3,8 @@
set TZData(:Indian/Mauritius) {
{-9223372036854775808 13800 0 LMT}
{-1988164200 14400 0 +04}
- {403041600 18000 1 +05}
+ {403041600 18000 1 +04}
{417034800 14400 0 +04}
- {1224972000 18000 1 +05}
+ {1224972000 18000 1 +04}
{1238274000 14400 0 +04}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Apia b/tcl8.6/library/tzdata/Pacific/Apia
index 4c0d84a..4fc91f4 100644
--- a/tcl8.6/library/tzdata/Pacific/Apia
+++ b/tcl8.6/library/tzdata/Pacific/Apia
@@ -4,185 +4,185 @@ set TZData(:Pacific/Apia) {
{-9223372036854775808 45184 0 LMT}
{-2445424384 -41216 0 LMT}
{-1861878784 -41400 0 -1130}
- {-631110600 -39600 0 -10}
- {1285498800 -36000 1 -10}
- {1301752800 -39600 0 -10}
- {1316872800 -36000 1 -10}
- {1325239200 50400 0 +14}
- {1333202400 46800 0 +14}
- {1348927200 50400 1 +14}
- {1365256800 46800 0 +14}
- {1380376800 50400 1 +14}
- {1396706400 46800 0 +14}
- {1411826400 50400 1 +14}
- {1428156000 46800 0 +14}
- {1443276000 50400 1 +14}
- {1459605600 46800 0 +14}
- {1474725600 50400 1 +14}
- {1491055200 46800 0 +14}
- {1506175200 50400 1 +14}
- {1522504800 46800 0 +14}
- {1538229600 50400 1 +14}
- {1554559200 46800 0 +14}
- {1569679200 50400 1 +14}
- {1586008800 46800 0 +14}
- {1601128800 50400 1 +14}
- {1617458400 46800 0 +14}
- {1632578400 50400 1 +14}
- {1648908000 46800 0 +14}
- {1664028000 50400 1 +14}
- {1680357600 46800 0 +14}
- {1695477600 50400 1 +14}
- {1712412000 46800 0 +14}
- {1727532000 50400 1 +14}
- {1743861600 46800 0 +14}
- {1758981600 50400 1 +14}
- {1775311200 46800 0 +14}
- {1790431200 50400 1 +14}
- {1806760800 46800 0 +14}
- {1821880800 50400 1 +14}
- {1838210400 46800 0 +14}
- {1853330400 50400 1 +14}
- {1869660000 46800 0 +14}
- {1885384800 50400 1 +14}
- {1901714400 46800 0 +14}
- {1916834400 50400 1 +14}
- {1933164000 46800 0 +14}
- {1948284000 50400 1 +14}
- {1964613600 46800 0 +14}
- {1979733600 50400 1 +14}
- {1996063200 46800 0 +14}
- {2011183200 50400 1 +14}
- {2027512800 46800 0 +14}
- {2042632800 50400 1 +14}
- {2058962400 46800 0 +14}
- {2074687200 50400 1 +14}
- {2091016800 46800 0 +14}
- {2106136800 50400 1 +14}
- {2122466400 46800 0 +14}
- {2137586400 50400 1 +14}
- {2153916000 46800 0 +14}
- {2169036000 50400 1 +14}
- {2185365600 46800 0 +14}
- {2200485600 50400 1 +14}
- {2216815200 46800 0 +14}
- {2232540000 50400 1 +14}
- {2248869600 46800 0 +14}
- {2263989600 50400 1 +14}
- {2280319200 46800 0 +14}
- {2295439200 50400 1 +14}
- {2311768800 46800 0 +14}
- {2326888800 50400 1 +14}
- {2343218400 46800 0 +14}
- {2358338400 50400 1 +14}
- {2374668000 46800 0 +14}
- {2389788000 50400 1 +14}
- {2406117600 46800 0 +14}
- {2421842400 50400 1 +14}
- {2438172000 46800 0 +14}
- {2453292000 50400 1 +14}
- {2469621600 46800 0 +14}
- {2484741600 50400 1 +14}
- {2501071200 46800 0 +14}
- {2516191200 50400 1 +14}
- {2532520800 46800 0 +14}
- {2547640800 50400 1 +14}
- {2563970400 46800 0 +14}
- {2579090400 50400 1 +14}
- {2596024800 46800 0 +14}
- {2611144800 50400 1 +14}
- {2627474400 46800 0 +14}
- {2642594400 50400 1 +14}
- {2658924000 46800 0 +14}
- {2674044000 50400 1 +14}
- {2690373600 46800 0 +14}
- {2705493600 50400 1 +14}
- {2721823200 46800 0 +14}
- {2736943200 50400 1 +14}
- {2753272800 46800 0 +14}
- {2768997600 50400 1 +14}
- {2785327200 46800 0 +14}
- {2800447200 50400 1 +14}
- {2816776800 46800 0 +14}
- {2831896800 50400 1 +14}
- {2848226400 46800 0 +14}
- {2863346400 50400 1 +14}
- {2879676000 46800 0 +14}
- {2894796000 50400 1 +14}
- {2911125600 46800 0 +14}
- {2926245600 50400 1 +14}
- {2942575200 46800 0 +14}
- {2958300000 50400 1 +14}
- {2974629600 46800 0 +14}
- {2989749600 50400 1 +14}
- {3006079200 46800 0 +14}
- {3021199200 50400 1 +14}
- {3037528800 46800 0 +14}
- {3052648800 50400 1 +14}
- {3068978400 46800 0 +14}
- {3084098400 50400 1 +14}
- {3100428000 46800 0 +14}
- {3116152800 50400 1 +14}
- {3132482400 46800 0 +14}
- {3147602400 50400 1 +14}
- {3163932000 46800 0 +14}
- {3179052000 50400 1 +14}
- {3195381600 46800 0 +14}
- {3210501600 50400 1 +14}
- {3226831200 46800 0 +14}
- {3241951200 50400 1 +14}
- {3258280800 46800 0 +14}
- {3273400800 50400 1 +14}
- {3289730400 46800 0 +14}
- {3305455200 50400 1 +14}
- {3321784800 46800 0 +14}
- {3336904800 50400 1 +14}
- {3353234400 46800 0 +14}
- {3368354400 50400 1 +14}
- {3384684000 46800 0 +14}
- {3399804000 50400 1 +14}
- {3416133600 46800 0 +14}
- {3431253600 50400 1 +14}
- {3447583200 46800 0 +14}
- {3462703200 50400 1 +14}
- {3479637600 46800 0 +14}
- {3494757600 50400 1 +14}
- {3511087200 46800 0 +14}
- {3526207200 50400 1 +14}
- {3542536800 46800 0 +14}
- {3557656800 50400 1 +14}
- {3573986400 46800 0 +14}
- {3589106400 50400 1 +14}
- {3605436000 46800 0 +14}
- {3620556000 50400 1 +14}
- {3636885600 46800 0 +14}
- {3652610400 50400 1 +14}
- {3668940000 46800 0 +14}
- {3684060000 50400 1 +14}
- {3700389600 46800 0 +14}
- {3715509600 50400 1 +14}
- {3731839200 46800 0 +14}
- {3746959200 50400 1 +14}
- {3763288800 46800 0 +14}
- {3778408800 50400 1 +14}
- {3794738400 46800 0 +14}
- {3809858400 50400 1 +14}
- {3826188000 46800 0 +14}
- {3841912800 50400 1 +14}
- {3858242400 46800 0 +14}
- {3873362400 50400 1 +14}
- {3889692000 46800 0 +14}
- {3904812000 50400 1 +14}
- {3921141600 46800 0 +14}
- {3936261600 50400 1 +14}
- {3952591200 46800 0 +14}
- {3967711200 50400 1 +14}
- {3984040800 46800 0 +14}
- {3999765600 50400 1 +14}
- {4016095200 46800 0 +14}
- {4031215200 50400 1 +14}
- {4047544800 46800 0 +14}
- {4062664800 50400 1 +14}
- {4078994400 46800 0 +14}
- {4094114400 50400 1 +14}
+ {-631110600 -39600 0 -11}
+ {1285498800 -36000 1 -11}
+ {1301752800 -39600 0 -11}
+ {1316872800 -36000 1 -11}
+ {1325239200 50400 0 +13}
+ {1333202400 46800 0 +13}
+ {1348927200 50400 1 +13}
+ {1365256800 46800 0 +13}
+ {1380376800 50400 1 +13}
+ {1396706400 46800 0 +13}
+ {1411826400 50400 1 +13}
+ {1428156000 46800 0 +13}
+ {1443276000 50400 1 +13}
+ {1459605600 46800 0 +13}
+ {1474725600 50400 1 +13}
+ {1491055200 46800 0 +13}
+ {1506175200 50400 1 +13}
+ {1522504800 46800 0 +13}
+ {1538229600 50400 1 +13}
+ {1554559200 46800 0 +13}
+ {1569679200 50400 1 +13}
+ {1586008800 46800 0 +13}
+ {1601128800 50400 1 +13}
+ {1617458400 46800 0 +13}
+ {1632578400 50400 1 +13}
+ {1648908000 46800 0 +13}
+ {1664028000 50400 1 +13}
+ {1680357600 46800 0 +13}
+ {1695477600 50400 1 +13}
+ {1712412000 46800 0 +13}
+ {1727532000 50400 1 +13}
+ {1743861600 46800 0 +13}
+ {1758981600 50400 1 +13}
+ {1775311200 46800 0 +13}
+ {1790431200 50400 1 +13}
+ {1806760800 46800 0 +13}
+ {1821880800 50400 1 +13}
+ {1838210400 46800 0 +13}
+ {1853330400 50400 1 +13}
+ {1869660000 46800 0 +13}
+ {1885384800 50400 1 +13}
+ {1901714400 46800 0 +13}
+ {1916834400 50400 1 +13}
+ {1933164000 46800 0 +13}
+ {1948284000 50400 1 +13}
+ {1964613600 46800 0 +13}
+ {1979733600 50400 1 +13}
+ {1996063200 46800 0 +13}
+ {2011183200 50400 1 +13}
+ {2027512800 46800 0 +13}
+ {2042632800 50400 1 +13}
+ {2058962400 46800 0 +13}
+ {2074687200 50400 1 +13}
+ {2091016800 46800 0 +13}
+ {2106136800 50400 1 +13}
+ {2122466400 46800 0 +13}
+ {2137586400 50400 1 +13}
+ {2153916000 46800 0 +13}
+ {2169036000 50400 1 +13}
+ {2185365600 46800 0 +13}
+ {2200485600 50400 1 +13}
+ {2216815200 46800 0 +13}
+ {2232540000 50400 1 +13}
+ {2248869600 46800 0 +13}
+ {2263989600 50400 1 +13}
+ {2280319200 46800 0 +13}
+ {2295439200 50400 1 +13}
+ {2311768800 46800 0 +13}
+ {2326888800 50400 1 +13}
+ {2343218400 46800 0 +13}
+ {2358338400 50400 1 +13}
+ {2374668000 46800 0 +13}
+ {2389788000 50400 1 +13}
+ {2406117600 46800 0 +13}
+ {2421842400 50400 1 +13}
+ {2438172000 46800 0 +13}
+ {2453292000 50400 1 +13}
+ {2469621600 46800 0 +13}
+ {2484741600 50400 1 +13}
+ {2501071200 46800 0 +13}
+ {2516191200 50400 1 +13}
+ {2532520800 46800 0 +13}
+ {2547640800 50400 1 +13}
+ {2563970400 46800 0 +13}
+ {2579090400 50400 1 +13}
+ {2596024800 46800 0 +13}
+ {2611144800 50400 1 +13}
+ {2627474400 46800 0 +13}
+ {2642594400 50400 1 +13}
+ {2658924000 46800 0 +13}
+ {2674044000 50400 1 +13}
+ {2690373600 46800 0 +13}
+ {2705493600 50400 1 +13}
+ {2721823200 46800 0 +13}
+ {2736943200 50400 1 +13}
+ {2753272800 46800 0 +13}
+ {2768997600 50400 1 +13}
+ {2785327200 46800 0 +13}
+ {2800447200 50400 1 +13}
+ {2816776800 46800 0 +13}
+ {2831896800 50400 1 +13}
+ {2848226400 46800 0 +13}
+ {2863346400 50400 1 +13}
+ {2879676000 46800 0 +13}
+ {2894796000 50400 1 +13}
+ {2911125600 46800 0 +13}
+ {2926245600 50400 1 +13}
+ {2942575200 46800 0 +13}
+ {2958300000 50400 1 +13}
+ {2974629600 46800 0 +13}
+ {2989749600 50400 1 +13}
+ {3006079200 46800 0 +13}
+ {3021199200 50400 1 +13}
+ {3037528800 46800 0 +13}
+ {3052648800 50400 1 +13}
+ {3068978400 46800 0 +13}
+ {3084098400 50400 1 +13}
+ {3100428000 46800 0 +13}
+ {3116152800 50400 1 +13}
+ {3132482400 46800 0 +13}
+ {3147602400 50400 1 +13}
+ {3163932000 46800 0 +13}
+ {3179052000 50400 1 +13}
+ {3195381600 46800 0 +13}
+ {3210501600 50400 1 +13}
+ {3226831200 46800 0 +13}
+ {3241951200 50400 1 +13}
+ {3258280800 46800 0 +13}
+ {3273400800 50400 1 +13}
+ {3289730400 46800 0 +13}
+ {3305455200 50400 1 +13}
+ {3321784800 46800 0 +13}
+ {3336904800 50400 1 +13}
+ {3353234400 46800 0 +13}
+ {3368354400 50400 1 +13}
+ {3384684000 46800 0 +13}
+ {3399804000 50400 1 +13}
+ {3416133600 46800 0 +13}
+ {3431253600 50400 1 +13}
+ {3447583200 46800 0 +13}
+ {3462703200 50400 1 +13}
+ {3479637600 46800 0 +13}
+ {3494757600 50400 1 +13}
+ {3511087200 46800 0 +13}
+ {3526207200 50400 1 +13}
+ {3542536800 46800 0 +13}
+ {3557656800 50400 1 +13}
+ {3573986400 46800 0 +13}
+ {3589106400 50400 1 +13}
+ {3605436000 46800 0 +13}
+ {3620556000 50400 1 +13}
+ {3636885600 46800 0 +13}
+ {3652610400 50400 1 +13}
+ {3668940000 46800 0 +13}
+ {3684060000 50400 1 +13}
+ {3700389600 46800 0 +13}
+ {3715509600 50400 1 +13}
+ {3731839200 46800 0 +13}
+ {3746959200 50400 1 +13}
+ {3763288800 46800 0 +13}
+ {3778408800 50400 1 +13}
+ {3794738400 46800 0 +13}
+ {3809858400 50400 1 +13}
+ {3826188000 46800 0 +13}
+ {3841912800 50400 1 +13}
+ {3858242400 46800 0 +13}
+ {3873362400 50400 1 +13}
+ {3889692000 46800 0 +13}
+ {3904812000 50400 1 +13}
+ {3921141600 46800 0 +13}
+ {3936261600 50400 1 +13}
+ {3952591200 46800 0 +13}
+ {3967711200 50400 1 +13}
+ {3984040800 46800 0 +13}
+ {3999765600 50400 1 +13}
+ {4016095200 46800 0 +13}
+ {4031215200 50400 1 +13}
+ {4047544800 46800 0 +13}
+ {4062664800 50400 1 +13}
+ {4078994400 46800 0 +13}
+ {4094114400 50400 1 +13}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Chatham b/tcl8.6/library/tzdata/Pacific/Chatham
index 5d39879..6c1ab19 100644
--- a/tcl8.6/library/tzdata/Pacific/Chatham
+++ b/tcl8.6/library/tzdata/Pacific/Chatham
@@ -3,256 +3,256 @@
set TZData(:Pacific/Chatham) {
{-9223372036854775808 44028 0 LMT}
{-3192437628 44100 0 +1215}
- {-757426500 45900 0 +1345}
- {152632800 49500 1 +1345}
- {162309600 45900 0 +1345}
- {183477600 49500 1 +1345}
- {194968800 45900 0 +1345}
- {215532000 49500 1 +1345}
- {226418400 45900 0 +1345}
- {246981600 49500 1 +1345}
- {257868000 45900 0 +1345}
- {278431200 49500 1 +1345}
- {289317600 45900 0 +1345}
- {309880800 49500 1 +1345}
- {320767200 45900 0 +1345}
- {341330400 49500 1 +1345}
- {352216800 45900 0 +1345}
- {372780000 49500 1 +1345}
- {384271200 45900 0 +1345}
- {404834400 49500 1 +1345}
- {415720800 45900 0 +1345}
- {436284000 49500 1 +1345}
- {447170400 45900 0 +1345}
- {467733600 49500 1 +1345}
- {478620000 45900 0 +1345}
- {499183200 49500 1 +1345}
- {510069600 45900 0 +1345}
- {530632800 49500 1 +1345}
- {541519200 45900 0 +1345}
- {562082400 49500 1 +1345}
- {573573600 45900 0 +1345}
- {594136800 49500 1 +1345}
- {605023200 45900 0 +1345}
- {623772000 49500 1 +1345}
- {637682400 45900 0 +1345}
- {655221600 49500 1 +1345}
- {669132000 45900 0 +1345}
- {686671200 49500 1 +1345}
- {700581600 45900 0 +1345}
- {718120800 49500 1 +1345}
- {732636000 45900 0 +1345}
- {749570400 49500 1 +1345}
- {764085600 45900 0 +1345}
- {781020000 49500 1 +1345}
- {795535200 45900 0 +1345}
- {812469600 49500 1 +1345}
- {826984800 45900 0 +1345}
- {844524000 49500 1 +1345}
- {858434400 45900 0 +1345}
- {875973600 49500 1 +1345}
- {889884000 45900 0 +1345}
- {907423200 49500 1 +1345}
- {921938400 45900 0 +1345}
- {938872800 49500 1 +1345}
- {953388000 45900 0 +1345}
- {970322400 49500 1 +1345}
- {984837600 45900 0 +1345}
- {1002376800 49500 1 +1345}
- {1016287200 45900 0 +1345}
- {1033826400 49500 1 +1345}
- {1047736800 45900 0 +1345}
- {1065276000 49500 1 +1345}
- {1079791200 45900 0 +1345}
- {1096725600 49500 1 +1345}
- {1111240800 45900 0 +1345}
- {1128175200 49500 1 +1345}
- {1142690400 45900 0 +1345}
- {1159624800 49500 1 +1345}
- {1174140000 45900 0 +1345}
- {1191074400 49500 1 +1345}
- {1207404000 45900 0 +1345}
- {1222524000 49500 1 +1345}
- {1238853600 45900 0 +1345}
- {1253973600 49500 1 +1345}
- {1270303200 45900 0 +1345}
- {1285423200 49500 1 +1345}
- {1301752800 45900 0 +1345}
- {1316872800 49500 1 +1345}
- {1333202400 45900 0 +1345}
- {1348927200 49500 1 +1345}
- {1365256800 45900 0 +1345}
- {1380376800 49500 1 +1345}
- {1396706400 45900 0 +1345}
- {1411826400 49500 1 +1345}
- {1428156000 45900 0 +1345}
- {1443276000 49500 1 +1345}
- {1459605600 45900 0 +1345}
- {1474725600 49500 1 +1345}
- {1491055200 45900 0 +1345}
- {1506175200 49500 1 +1345}
- {1522504800 45900 0 +1345}
- {1538229600 49500 1 +1345}
- {1554559200 45900 0 +1345}
- {1569679200 49500 1 +1345}
- {1586008800 45900 0 +1345}
- {1601128800 49500 1 +1345}
- {1617458400 45900 0 +1345}
- {1632578400 49500 1 +1345}
- {1648908000 45900 0 +1345}
- {1664028000 49500 1 +1345}
- {1680357600 45900 0 +1345}
- {1695477600 49500 1 +1345}
- {1712412000 45900 0 +1345}
- {1727532000 49500 1 +1345}
- {1743861600 45900 0 +1345}
- {1758981600 49500 1 +1345}
- {1775311200 45900 0 +1345}
- {1790431200 49500 1 +1345}
- {1806760800 45900 0 +1345}
- {1821880800 49500 1 +1345}
- {1838210400 45900 0 +1345}
- {1853330400 49500 1 +1345}
- {1869660000 45900 0 +1345}
- {1885384800 49500 1 +1345}
- {1901714400 45900 0 +1345}
- {1916834400 49500 1 +1345}
- {1933164000 45900 0 +1345}
- {1948284000 49500 1 +1345}
- {1964613600 45900 0 +1345}
- {1979733600 49500 1 +1345}
- {1996063200 45900 0 +1345}
- {2011183200 49500 1 +1345}
- {2027512800 45900 0 +1345}
- {2042632800 49500 1 +1345}
- {2058962400 45900 0 +1345}
- {2074687200 49500 1 +1345}
- {2091016800 45900 0 +1345}
- {2106136800 49500 1 +1345}
- {2122466400 45900 0 +1345}
- {2137586400 49500 1 +1345}
- {2153916000 45900 0 +1345}
- {2169036000 49500 1 +1345}
- {2185365600 45900 0 +1345}
- {2200485600 49500 1 +1345}
- {2216815200 45900 0 +1345}
- {2232540000 49500 1 +1345}
- {2248869600 45900 0 +1345}
- {2263989600 49500 1 +1345}
- {2280319200 45900 0 +1345}
- {2295439200 49500 1 +1345}
- {2311768800 45900 0 +1345}
- {2326888800 49500 1 +1345}
- {2343218400 45900 0 +1345}
- {2358338400 49500 1 +1345}
- {2374668000 45900 0 +1345}
- {2389788000 49500 1 +1345}
- {2406117600 45900 0 +1345}
- {2421842400 49500 1 +1345}
- {2438172000 45900 0 +1345}
- {2453292000 49500 1 +1345}
- {2469621600 45900 0 +1345}
- {2484741600 49500 1 +1345}
- {2501071200 45900 0 +1345}
- {2516191200 49500 1 +1345}
- {2532520800 45900 0 +1345}
- {2547640800 49500 1 +1345}
- {2563970400 45900 0 +1345}
- {2579090400 49500 1 +1345}
- {2596024800 45900 0 +1345}
- {2611144800 49500 1 +1345}
- {2627474400 45900 0 +1345}
- {2642594400 49500 1 +1345}
- {2658924000 45900 0 +1345}
- {2674044000 49500 1 +1345}
- {2690373600 45900 0 +1345}
- {2705493600 49500 1 +1345}
- {2721823200 45900 0 +1345}
- {2736943200 49500 1 +1345}
- {2753272800 45900 0 +1345}
- {2768997600 49500 1 +1345}
- {2785327200 45900 0 +1345}
- {2800447200 49500 1 +1345}
- {2816776800 45900 0 +1345}
- {2831896800 49500 1 +1345}
- {2848226400 45900 0 +1345}
- {2863346400 49500 1 +1345}
- {2879676000 45900 0 +1345}
- {2894796000 49500 1 +1345}
- {2911125600 45900 0 +1345}
- {2926245600 49500 1 +1345}
- {2942575200 45900 0 +1345}
- {2958300000 49500 1 +1345}
- {2974629600 45900 0 +1345}
- {2989749600 49500 1 +1345}
- {3006079200 45900 0 +1345}
- {3021199200 49500 1 +1345}
- {3037528800 45900 0 +1345}
- {3052648800 49500 1 +1345}
- {3068978400 45900 0 +1345}
- {3084098400 49500 1 +1345}
- {3100428000 45900 0 +1345}
- {3116152800 49500 1 +1345}
- {3132482400 45900 0 +1345}
- {3147602400 49500 1 +1345}
- {3163932000 45900 0 +1345}
- {3179052000 49500 1 +1345}
- {3195381600 45900 0 +1345}
- {3210501600 49500 1 +1345}
- {3226831200 45900 0 +1345}
- {3241951200 49500 1 +1345}
- {3258280800 45900 0 +1345}
- {3273400800 49500 1 +1345}
- {3289730400 45900 0 +1345}
- {3305455200 49500 1 +1345}
- {3321784800 45900 0 +1345}
- {3336904800 49500 1 +1345}
- {3353234400 45900 0 +1345}
- {3368354400 49500 1 +1345}
- {3384684000 45900 0 +1345}
- {3399804000 49500 1 +1345}
- {3416133600 45900 0 +1345}
- {3431253600 49500 1 +1345}
- {3447583200 45900 0 +1345}
- {3462703200 49500 1 +1345}
- {3479637600 45900 0 +1345}
- {3494757600 49500 1 +1345}
- {3511087200 45900 0 +1345}
- {3526207200 49500 1 +1345}
- {3542536800 45900 0 +1345}
- {3557656800 49500 1 +1345}
- {3573986400 45900 0 +1345}
- {3589106400 49500 1 +1345}
- {3605436000 45900 0 +1345}
- {3620556000 49500 1 +1345}
- {3636885600 45900 0 +1345}
- {3652610400 49500 1 +1345}
- {3668940000 45900 0 +1345}
- {3684060000 49500 1 +1345}
- {3700389600 45900 0 +1345}
- {3715509600 49500 1 +1345}
- {3731839200 45900 0 +1345}
- {3746959200 49500 1 +1345}
- {3763288800 45900 0 +1345}
- {3778408800 49500 1 +1345}
- {3794738400 45900 0 +1345}
- {3809858400 49500 1 +1345}
- {3826188000 45900 0 +1345}
- {3841912800 49500 1 +1345}
- {3858242400 45900 0 +1345}
- {3873362400 49500 1 +1345}
- {3889692000 45900 0 +1345}
- {3904812000 49500 1 +1345}
- {3921141600 45900 0 +1345}
- {3936261600 49500 1 +1345}
- {3952591200 45900 0 +1345}
- {3967711200 49500 1 +1345}
- {3984040800 45900 0 +1345}
- {3999765600 49500 1 +1345}
- {4016095200 45900 0 +1345}
- {4031215200 49500 1 +1345}
- {4047544800 45900 0 +1345}
- {4062664800 49500 1 +1345}
- {4078994400 45900 0 +1345}
- {4094114400 49500 1 +1345}
+ {-757426500 45900 0 +1245}
+ {152632800 49500 1 +1245}
+ {162309600 45900 0 +1245}
+ {183477600 49500 1 +1245}
+ {194968800 45900 0 +1245}
+ {215532000 49500 1 +1245}
+ {226418400 45900 0 +1245}
+ {246981600 49500 1 +1245}
+ {257868000 45900 0 +1245}
+ {278431200 49500 1 +1245}
+ {289317600 45900 0 +1245}
+ {309880800 49500 1 +1245}
+ {320767200 45900 0 +1245}
+ {341330400 49500 1 +1245}
+ {352216800 45900 0 +1245}
+ {372780000 49500 1 +1245}
+ {384271200 45900 0 +1245}
+ {404834400 49500 1 +1245}
+ {415720800 45900 0 +1245}
+ {436284000 49500 1 +1245}
+ {447170400 45900 0 +1245}
+ {467733600 49500 1 +1245}
+ {478620000 45900 0 +1245}
+ {499183200 49500 1 +1245}
+ {510069600 45900 0 +1245}
+ {530632800 49500 1 +1245}
+ {541519200 45900 0 +1245}
+ {562082400 49500 1 +1245}
+ {573573600 45900 0 +1245}
+ {594136800 49500 1 +1245}
+ {605023200 45900 0 +1245}
+ {623772000 49500 1 +1245}
+ {637682400 45900 0 +1245}
+ {655221600 49500 1 +1245}
+ {669132000 45900 0 +1245}
+ {686671200 49500 1 +1245}
+ {700581600 45900 0 +1245}
+ {718120800 49500 1 +1245}
+ {732636000 45900 0 +1245}
+ {749570400 49500 1 +1245}
+ {764085600 45900 0 +1245}
+ {781020000 49500 1 +1245}
+ {795535200 45900 0 +1245}
+ {812469600 49500 1 +1245}
+ {826984800 45900 0 +1245}
+ {844524000 49500 1 +1245}
+ {858434400 45900 0 +1245}
+ {875973600 49500 1 +1245}
+ {889884000 45900 0 +1245}
+ {907423200 49500 1 +1245}
+ {921938400 45900 0 +1245}
+ {938872800 49500 1 +1245}
+ {953388000 45900 0 +1245}
+ {970322400 49500 1 +1245}
+ {984837600 45900 0 +1245}
+ {1002376800 49500 1 +1245}
+ {1016287200 45900 0 +1245}
+ {1033826400 49500 1 +1245}
+ {1047736800 45900 0 +1245}
+ {1065276000 49500 1 +1245}
+ {1079791200 45900 0 +1245}
+ {1096725600 49500 1 +1245}
+ {1111240800 45900 0 +1245}
+ {1128175200 49500 1 +1245}
+ {1142690400 45900 0 +1245}
+ {1159624800 49500 1 +1245}
+ {1174140000 45900 0 +1245}
+ {1191074400 49500 1 +1245}
+ {1207404000 45900 0 +1245}
+ {1222524000 49500 1 +1245}
+ {1238853600 45900 0 +1245}
+ {1253973600 49500 1 +1245}
+ {1270303200 45900 0 +1245}
+ {1285423200 49500 1 +1245}
+ {1301752800 45900 0 +1245}
+ {1316872800 49500 1 +1245}
+ {1333202400 45900 0 +1245}
+ {1348927200 49500 1 +1245}
+ {1365256800 45900 0 +1245}
+ {1380376800 49500 1 +1245}
+ {1396706400 45900 0 +1245}
+ {1411826400 49500 1 +1245}
+ {1428156000 45900 0 +1245}
+ {1443276000 49500 1 +1245}
+ {1459605600 45900 0 +1245}
+ {1474725600 49500 1 +1245}
+ {1491055200 45900 0 +1245}
+ {1506175200 49500 1 +1245}
+ {1522504800 45900 0 +1245}
+ {1538229600 49500 1 +1245}
+ {1554559200 45900 0 +1245}
+ {1569679200 49500 1 +1245}
+ {1586008800 45900 0 +1245}
+ {1601128800 49500 1 +1245}
+ {1617458400 45900 0 +1245}
+ {1632578400 49500 1 +1245}
+ {1648908000 45900 0 +1245}
+ {1664028000 49500 1 +1245}
+ {1680357600 45900 0 +1245}
+ {1695477600 49500 1 +1245}
+ {1712412000 45900 0 +1245}
+ {1727532000 49500 1 +1245}
+ {1743861600 45900 0 +1245}
+ {1758981600 49500 1 +1245}
+ {1775311200 45900 0 +1245}
+ {1790431200 49500 1 +1245}
+ {1806760800 45900 0 +1245}
+ {1821880800 49500 1 +1245}
+ {1838210400 45900 0 +1245}
+ {1853330400 49500 1 +1245}
+ {1869660000 45900 0 +1245}
+ {1885384800 49500 1 +1245}
+ {1901714400 45900 0 +1245}
+ {1916834400 49500 1 +1245}
+ {1933164000 45900 0 +1245}
+ {1948284000 49500 1 +1245}
+ {1964613600 45900 0 +1245}
+ {1979733600 49500 1 +1245}
+ {1996063200 45900 0 +1245}
+ {2011183200 49500 1 +1245}
+ {2027512800 45900 0 +1245}
+ {2042632800 49500 1 +1245}
+ {2058962400 45900 0 +1245}
+ {2074687200 49500 1 +1245}
+ {2091016800 45900 0 +1245}
+ {2106136800 49500 1 +1245}
+ {2122466400 45900 0 +1245}
+ {2137586400 49500 1 +1245}
+ {2153916000 45900 0 +1245}
+ {2169036000 49500 1 +1245}
+ {2185365600 45900 0 +1245}
+ {2200485600 49500 1 +1245}
+ {2216815200 45900 0 +1245}
+ {2232540000 49500 1 +1245}
+ {2248869600 45900 0 +1245}
+ {2263989600 49500 1 +1245}
+ {2280319200 45900 0 +1245}
+ {2295439200 49500 1 +1245}
+ {2311768800 45900 0 +1245}
+ {2326888800 49500 1 +1245}
+ {2343218400 45900 0 +1245}
+ {2358338400 49500 1 +1245}
+ {2374668000 45900 0 +1245}
+ {2389788000 49500 1 +1245}
+ {2406117600 45900 0 +1245}
+ {2421842400 49500 1 +1245}
+ {2438172000 45900 0 +1245}
+ {2453292000 49500 1 +1245}
+ {2469621600 45900 0 +1245}
+ {2484741600 49500 1 +1245}
+ {2501071200 45900 0 +1245}
+ {2516191200 49500 1 +1245}
+ {2532520800 45900 0 +1245}
+ {2547640800 49500 1 +1245}
+ {2563970400 45900 0 +1245}
+ {2579090400 49500 1 +1245}
+ {2596024800 45900 0 +1245}
+ {2611144800 49500 1 +1245}
+ {2627474400 45900 0 +1245}
+ {2642594400 49500 1 +1245}
+ {2658924000 45900 0 +1245}
+ {2674044000 49500 1 +1245}
+ {2690373600 45900 0 +1245}
+ {2705493600 49500 1 +1245}
+ {2721823200 45900 0 +1245}
+ {2736943200 49500 1 +1245}
+ {2753272800 45900 0 +1245}
+ {2768997600 49500 1 +1245}
+ {2785327200 45900 0 +1245}
+ {2800447200 49500 1 +1245}
+ {2816776800 45900 0 +1245}
+ {2831896800 49500 1 +1245}
+ {2848226400 45900 0 +1245}
+ {2863346400 49500 1 +1245}
+ {2879676000 45900 0 +1245}
+ {2894796000 49500 1 +1245}
+ {2911125600 45900 0 +1245}
+ {2926245600 49500 1 +1245}
+ {2942575200 45900 0 +1245}
+ {2958300000 49500 1 +1245}
+ {2974629600 45900 0 +1245}
+ {2989749600 49500 1 +1245}
+ {3006079200 45900 0 +1245}
+ {3021199200 49500 1 +1245}
+ {3037528800 45900 0 +1245}
+ {3052648800 49500 1 +1245}
+ {3068978400 45900 0 +1245}
+ {3084098400 49500 1 +1245}
+ {3100428000 45900 0 +1245}
+ {3116152800 49500 1 +1245}
+ {3132482400 45900 0 +1245}
+ {3147602400 49500 1 +1245}
+ {3163932000 45900 0 +1245}
+ {3179052000 49500 1 +1245}
+ {3195381600 45900 0 +1245}
+ {3210501600 49500 1 +1245}
+ {3226831200 45900 0 +1245}
+ {3241951200 49500 1 +1245}
+ {3258280800 45900 0 +1245}
+ {3273400800 49500 1 +1245}
+ {3289730400 45900 0 +1245}
+ {3305455200 49500 1 +1245}
+ {3321784800 45900 0 +1245}
+ {3336904800 49500 1 +1245}
+ {3353234400 45900 0 +1245}
+ {3368354400 49500 1 +1245}
+ {3384684000 45900 0 +1245}
+ {3399804000 49500 1 +1245}
+ {3416133600 45900 0 +1245}
+ {3431253600 49500 1 +1245}
+ {3447583200 45900 0 +1245}
+ {3462703200 49500 1 +1245}
+ {3479637600 45900 0 +1245}
+ {3494757600 49500 1 +1245}
+ {3511087200 45900 0 +1245}
+ {3526207200 49500 1 +1245}
+ {3542536800 45900 0 +1245}
+ {3557656800 49500 1 +1245}
+ {3573986400 45900 0 +1245}
+ {3589106400 49500 1 +1245}
+ {3605436000 45900 0 +1245}
+ {3620556000 49500 1 +1245}
+ {3636885600 45900 0 +1245}
+ {3652610400 49500 1 +1245}
+ {3668940000 45900 0 +1245}
+ {3684060000 49500 1 +1245}
+ {3700389600 45900 0 +1245}
+ {3715509600 49500 1 +1245}
+ {3731839200 45900 0 +1245}
+ {3746959200 49500 1 +1245}
+ {3763288800 45900 0 +1245}
+ {3778408800 49500 1 +1245}
+ {3794738400 45900 0 +1245}
+ {3809858400 49500 1 +1245}
+ {3826188000 45900 0 +1245}
+ {3841912800 49500 1 +1245}
+ {3858242400 45900 0 +1245}
+ {3873362400 49500 1 +1245}
+ {3889692000 45900 0 +1245}
+ {3904812000 49500 1 +1245}
+ {3921141600 45900 0 +1245}
+ {3936261600 49500 1 +1245}
+ {3952591200 45900 0 +1245}
+ {3967711200 49500 1 +1245}
+ {3984040800 45900 0 +1245}
+ {3999765600 49500 1 +1245}
+ {4016095200 45900 0 +1245}
+ {4031215200 49500 1 +1245}
+ {4047544800 45900 0 +1245}
+ {4062664800 49500 1 +1245}
+ {4078994400 45900 0 +1245}
+ {4094114400 49500 1 +1245}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Easter b/tcl8.6/library/tzdata/Pacific/Easter
index 474a32b..7a8d525 100644
--- a/tcl8.6/library/tzdata/Pacific/Easter
+++ b/tcl8.6/library/tzdata/Pacific/Easter
@@ -4,265 +4,265 @@ set TZData(:Pacific/Easter) {
{-9223372036854775808 -26248 0 LMT}
{-2524495352 -26248 0 EMT}
{-1178124152 -25200 0 -07}
- {-36619200 -21600 1 -06}
+ {-36619200 -21600 1 -07}
{-23922000 -25200 0 -07}
- {-3355200 -21600 1 -06}
+ {-3355200 -21600 1 -07}
{7527600 -25200 0 -07}
- {24465600 -21600 1 -06}
+ {24465600 -21600 1 -07}
{37767600 -25200 0 -07}
- {55915200 -21600 1 -06}
+ {55915200 -21600 1 -07}
{69217200 -25200 0 -07}
- {87969600 -21600 1 -06}
+ {87969600 -21600 1 -07}
{100666800 -25200 0 -07}
- {118209600 -21600 1 -06}
+ {118209600 -21600 1 -07}
{132116400 -25200 0 -07}
- {150868800 -21600 1 -06}
+ {150868800 -21600 1 -07}
{163566000 -25200 0 -07}
- {182318400 -21600 1 -06}
+ {182318400 -21600 1 -07}
{195620400 -25200 0 -07}
- {213768000 -21600 1 -06}
+ {213768000 -21600 1 -07}
{227070000 -25200 0 -07}
- {245217600 -21600 1 -06}
+ {245217600 -21600 1 -07}
{258519600 -25200 0 -07}
- {277272000 -21600 1 -06}
+ {277272000 -21600 1 -07}
{289969200 -25200 0 -07}
- {308721600 -21600 1 -06}
+ {308721600 -21600 1 -07}
{321418800 -25200 0 -07}
- {340171200 -21600 1 -06}
+ {340171200 -21600 1 -07}
{353473200 -25200 0 -07}
- {371620800 -21600 1 -06}
+ {371620800 -21600 1 -07}
{384922800 -21600 0 -06}
- {403070400 -18000 1 -05}
+ {403070400 -18000 1 -06}
{416372400 -21600 0 -06}
- {434520000 -18000 1 -05}
+ {434520000 -18000 1 -06}
{447822000 -21600 0 -06}
- {466574400 -18000 1 -05}
+ {466574400 -18000 1 -06}
{479271600 -21600 0 -06}
- {498024000 -18000 1 -05}
+ {498024000 -18000 1 -06}
{510721200 -21600 0 -06}
- {529473600 -18000 1 -05}
+ {529473600 -18000 1 -06}
{545194800 -21600 0 -06}
- {560923200 -18000 1 -05}
+ {560923200 -18000 1 -06}
{574225200 -21600 0 -06}
- {592372800 -18000 1 -05}
+ {592372800 -18000 1 -06}
{605674800 -21600 0 -06}
- {624427200 -18000 1 -05}
+ {624427200 -18000 1 -06}
{637124400 -21600 0 -06}
- {653457600 -18000 1 -05}
+ {653457600 -18000 1 -06}
{668574000 -21600 0 -06}
- {687326400 -18000 1 -05}
+ {687326400 -18000 1 -06}
{700628400 -21600 0 -06}
- {718776000 -18000 1 -05}
+ {718776000 -18000 1 -06}
{732078000 -21600 0 -06}
- {750225600 -18000 1 -05}
+ {750225600 -18000 1 -06}
{763527600 -21600 0 -06}
- {781675200 -18000 1 -05}
+ {781675200 -18000 1 -06}
{794977200 -21600 0 -06}
- {813729600 -18000 1 -05}
+ {813729600 -18000 1 -06}
{826426800 -21600 0 -06}
- {845179200 -18000 1 -05}
+ {845179200 -18000 1 -06}
{859690800 -21600 0 -06}
- {876628800 -18000 1 -05}
+ {876628800 -18000 1 -06}
{889930800 -21600 0 -06}
- {906868800 -18000 1 -05}
+ {906868800 -18000 1 -06}
{923194800 -21600 0 -06}
- {939528000 -18000 1 -05}
+ {939528000 -18000 1 -06}
{952830000 -21600 0 -06}
- {971582400 -18000 1 -05}
+ {971582400 -18000 1 -06}
{984279600 -21600 0 -06}
- {1003032000 -18000 1 -05}
+ {1003032000 -18000 1 -06}
{1015729200 -21600 0 -06}
- {1034481600 -18000 1 -05}
+ {1034481600 -18000 1 -06}
{1047178800 -21600 0 -06}
- {1065931200 -18000 1 -05}
+ {1065931200 -18000 1 -06}
{1079233200 -21600 0 -06}
- {1097380800 -18000 1 -05}
+ {1097380800 -18000 1 -06}
{1110682800 -21600 0 -06}
- {1128830400 -18000 1 -05}
+ {1128830400 -18000 1 -06}
{1142132400 -21600 0 -06}
- {1160884800 -18000 1 -05}
+ {1160884800 -18000 1 -06}
{1173582000 -21600 0 -06}
- {1192334400 -18000 1 -05}
+ {1192334400 -18000 1 -06}
{1206846000 -21600 0 -06}
- {1223784000 -18000 1 -05}
+ {1223784000 -18000 1 -06}
{1237086000 -21600 0 -06}
- {1255233600 -18000 1 -05}
+ {1255233600 -18000 1 -06}
{1270350000 -21600 0 -06}
- {1286683200 -18000 1 -05}
+ {1286683200 -18000 1 -06}
{1304823600 -21600 0 -06}
- {1313899200 -18000 1 -05}
+ {1313899200 -18000 1 -06}
{1335668400 -21600 0 -06}
- {1346558400 -18000 1 -05}
+ {1346558400 -18000 1 -06}
{1367118000 -21600 0 -06}
- {1378612800 -18000 1 -05}
+ {1378612800 -18000 1 -06}
{1398567600 -21600 0 -06}
- {1410062400 -18000 1 -05}
+ {1410062400 -18000 1 -06}
{1463281200 -21600 0 -06}
- {1471147200 -18000 1 -05}
+ {1471147200 -18000 1 -06}
{1494730800 -21600 0 -06}
- {1502596800 -18000 1 -05}
+ {1502596800 -18000 1 -06}
{1526180400 -21600 0 -06}
- {1534046400 -18000 1 -05}
- {1557630000 -21600 0 -06}
- {1565496000 -18000 1 -05}
- {1589079600 -21600 0 -06}
- {1596945600 -18000 1 -05}
- {1620529200 -21600 0 -06}
- {1629000000 -18000 1 -05}
- {1652583600 -21600 0 -06}
- {1660449600 -18000 1 -05}
- {1684033200 -21600 0 -06}
- {1691899200 -18000 1 -05}
- {1715482800 -21600 0 -06}
- {1723348800 -18000 1 -05}
- {1746932400 -21600 0 -06}
- {1754798400 -18000 1 -05}
- {1778382000 -21600 0 -06}
- {1786248000 -18000 1 -05}
- {1809831600 -21600 0 -06}
- {1818302400 -18000 1 -05}
- {1841886000 -21600 0 -06}
- {1849752000 -18000 1 -05}
- {1873335600 -21600 0 -06}
- {1881201600 -18000 1 -05}
- {1904785200 -21600 0 -06}
- {1912651200 -18000 1 -05}
- {1936234800 -21600 0 -06}
- {1944100800 -18000 1 -05}
- {1967684400 -21600 0 -06}
- {1976155200 -18000 1 -05}
- {1999738800 -21600 0 -06}
- {2007604800 -18000 1 -05}
- {2031188400 -21600 0 -06}
- {2039054400 -18000 1 -05}
- {2062638000 -21600 0 -06}
- {2070504000 -18000 1 -05}
- {2094087600 -21600 0 -06}
- {2101953600 -18000 1 -05}
- {2125537200 -21600 0 -06}
- {2133403200 -18000 1 -05}
- {2156986800 -21600 0 -06}
- {2165457600 -18000 1 -05}
- {2189041200 -21600 0 -06}
- {2196907200 -18000 1 -05}
- {2220490800 -21600 0 -06}
- {2228356800 -18000 1 -05}
- {2251940400 -21600 0 -06}
- {2259806400 -18000 1 -05}
- {2283390000 -21600 0 -06}
- {2291256000 -18000 1 -05}
- {2314839600 -21600 0 -06}
- {2322705600 -18000 1 -05}
- {2346894000 -21600 0 -06}
- {2354760000 -18000 1 -05}
- {2378343600 -21600 0 -06}
- {2386209600 -18000 1 -05}
- {2409793200 -21600 0 -06}
- {2417659200 -18000 1 -05}
- {2441242800 -21600 0 -06}
- {2449108800 -18000 1 -05}
- {2472692400 -21600 0 -06}
- {2480558400 -18000 1 -05}
- {2504142000 -21600 0 -06}
- {2512612800 -18000 1 -05}
- {2536196400 -21600 0 -06}
- {2544062400 -18000 1 -05}
- {2567646000 -21600 0 -06}
- {2575512000 -18000 1 -05}
- {2599095600 -21600 0 -06}
- {2606961600 -18000 1 -05}
- {2630545200 -21600 0 -06}
- {2638411200 -18000 1 -05}
- {2661994800 -21600 0 -06}
- {2669860800 -18000 1 -05}
- {2693444400 -21600 0 -06}
- {2701915200 -18000 1 -05}
- {2725498800 -21600 0 -06}
- {2733364800 -18000 1 -05}
- {2756948400 -21600 0 -06}
- {2764814400 -18000 1 -05}
- {2788398000 -21600 0 -06}
- {2796264000 -18000 1 -05}
- {2819847600 -21600 0 -06}
- {2827713600 -18000 1 -05}
- {2851297200 -21600 0 -06}
- {2859768000 -18000 1 -05}
- {2883351600 -21600 0 -06}
- {2891217600 -18000 1 -05}
- {2914801200 -21600 0 -06}
- {2922667200 -18000 1 -05}
- {2946250800 -21600 0 -06}
- {2954116800 -18000 1 -05}
- {2977700400 -21600 0 -06}
- {2985566400 -18000 1 -05}
- {3009150000 -21600 0 -06}
- {3017016000 -18000 1 -05}
- {3040599600 -21600 0 -06}
- {3049070400 -18000 1 -05}
- {3072654000 -21600 0 -06}
- {3080520000 -18000 1 -05}
- {3104103600 -21600 0 -06}
- {3111969600 -18000 1 -05}
- {3135553200 -21600 0 -06}
- {3143419200 -18000 1 -05}
- {3167002800 -21600 0 -06}
- {3174868800 -18000 1 -05}
- {3198452400 -21600 0 -06}
- {3206318400 -18000 1 -05}
- {3230506800 -21600 0 -06}
- {3238372800 -18000 1 -05}
- {3261956400 -21600 0 -06}
- {3269822400 -18000 1 -05}
- {3293406000 -21600 0 -06}
- {3301272000 -18000 1 -05}
- {3324855600 -21600 0 -06}
- {3332721600 -18000 1 -05}
- {3356305200 -21600 0 -06}
- {3364171200 -18000 1 -05}
- {3387754800 -21600 0 -06}
- {3396225600 -18000 1 -05}
- {3419809200 -21600 0 -06}
- {3427675200 -18000 1 -05}
- {3451258800 -21600 0 -06}
- {3459124800 -18000 1 -05}
- {3482708400 -21600 0 -06}
- {3490574400 -18000 1 -05}
- {3514158000 -21600 0 -06}
- {3522024000 -18000 1 -05}
- {3545607600 -21600 0 -06}
- {3553473600 -18000 1 -05}
- {3577057200 -21600 0 -06}
- {3585528000 -18000 1 -05}
- {3609111600 -21600 0 -06}
- {3616977600 -18000 1 -05}
- {3640561200 -21600 0 -06}
- {3648427200 -18000 1 -05}
- {3672010800 -21600 0 -06}
- {3679876800 -18000 1 -05}
- {3703460400 -21600 0 -06}
- {3711326400 -18000 1 -05}
- {3734910000 -21600 0 -06}
- {3743380800 -18000 1 -05}
- {3766964400 -21600 0 -06}
- {3774830400 -18000 1 -05}
- {3798414000 -21600 0 -06}
- {3806280000 -18000 1 -05}
- {3829863600 -21600 0 -06}
- {3837729600 -18000 1 -05}
- {3861313200 -21600 0 -06}
- {3869179200 -18000 1 -05}
- {3892762800 -21600 0 -06}
- {3900628800 -18000 1 -05}
- {3924212400 -21600 0 -06}
- {3932683200 -18000 1 -05}
- {3956266800 -21600 0 -06}
- {3964132800 -18000 1 -05}
- {3987716400 -21600 0 -06}
- {3995582400 -18000 1 -05}
- {4019166000 -21600 0 -06}
- {4027032000 -18000 1 -05}
- {4050615600 -21600 0 -06}
- {4058481600 -18000 1 -05}
- {4082065200 -21600 0 -06}
- {4089931200 -18000 1 -05}
+ {1534046400 -18000 1 -06}
+ {1554606000 -21600 0 -06}
+ {1567915200 -18000 1 -06}
+ {1586055600 -21600 0 -06}
+ {1599364800 -18000 1 -06}
+ {1617505200 -21600 0 -06}
+ {1630814400 -18000 1 -06}
+ {1648954800 -21600 0 -06}
+ {1662264000 -18000 1 -06}
+ {1680404400 -21600 0 -06}
+ {1693713600 -18000 1 -06}
+ {1712458800 -21600 0 -06}
+ {1725768000 -18000 1 -06}
+ {1743908400 -21600 0 -06}
+ {1757217600 -18000 1 -06}
+ {1775358000 -21600 0 -06}
+ {1788667200 -18000 1 -06}
+ {1806807600 -21600 0 -06}
+ {1820116800 -18000 1 -06}
+ {1838257200 -21600 0 -06}
+ {1851566400 -18000 1 -06}
+ {1870311600 -21600 0 -06}
+ {1883016000 -18000 1 -06}
+ {1901761200 -21600 0 -06}
+ {1915070400 -18000 1 -06}
+ {1933210800 -21600 0 -06}
+ {1946520000 -18000 1 -06}
+ {1964660400 -21600 0 -06}
+ {1977969600 -18000 1 -06}
+ {1996110000 -21600 0 -06}
+ {2009419200 -18000 1 -06}
+ {2027559600 -21600 0 -06}
+ {2040868800 -18000 1 -06}
+ {2059614000 -21600 0 -06}
+ {2072318400 -18000 1 -06}
+ {2091063600 -21600 0 -06}
+ {2104372800 -18000 1 -06}
+ {2122513200 -21600 0 -06}
+ {2135822400 -18000 1 -06}
+ {2153962800 -21600 0 -06}
+ {2167272000 -18000 1 -06}
+ {2185412400 -21600 0 -06}
+ {2198721600 -18000 1 -06}
+ {2217466800 -21600 0 -06}
+ {2230171200 -18000 1 -06}
+ {2248916400 -21600 0 -06}
+ {2262225600 -18000 1 -06}
+ {2280366000 -21600 0 -06}
+ {2293675200 -18000 1 -06}
+ {2311815600 -21600 0 -06}
+ {2325124800 -18000 1 -06}
+ {2343265200 -21600 0 -06}
+ {2356574400 -18000 1 -06}
+ {2374714800 -21600 0 -06}
+ {2388024000 -18000 1 -06}
+ {2406769200 -21600 0 -06}
+ {2419473600 -18000 1 -06}
+ {2438218800 -21600 0 -06}
+ {2451528000 -18000 1 -06}
+ {2469668400 -21600 0 -06}
+ {2482977600 -18000 1 -06}
+ {2501118000 -21600 0 -06}
+ {2514427200 -18000 1 -06}
+ {2532567600 -21600 0 -06}
+ {2545876800 -18000 1 -06}
+ {2564017200 -21600 0 -06}
+ {2577326400 -18000 1 -06}
+ {2596071600 -21600 0 -06}
+ {2609380800 -18000 1 -06}
+ {2627521200 -21600 0 -06}
+ {2640830400 -18000 1 -06}
+ {2658970800 -21600 0 -06}
+ {2672280000 -18000 1 -06}
+ {2690420400 -21600 0 -06}
+ {2703729600 -18000 1 -06}
+ {2721870000 -21600 0 -06}
+ {2735179200 -18000 1 -06}
+ {2753924400 -21600 0 -06}
+ {2766628800 -18000 1 -06}
+ {2785374000 -21600 0 -06}
+ {2798683200 -18000 1 -06}
+ {2816823600 -21600 0 -06}
+ {2830132800 -18000 1 -06}
+ {2848273200 -21600 0 -06}
+ {2861582400 -18000 1 -06}
+ {2879722800 -21600 0 -06}
+ {2893032000 -18000 1 -06}
+ {2911172400 -21600 0 -06}
+ {2924481600 -18000 1 -06}
+ {2943226800 -21600 0 -06}
+ {2955931200 -18000 1 -06}
+ {2974676400 -21600 0 -06}
+ {2987985600 -18000 1 -06}
+ {3006126000 -21600 0 -06}
+ {3019435200 -18000 1 -06}
+ {3037575600 -21600 0 -06}
+ {3050884800 -18000 1 -06}
+ {3069025200 -21600 0 -06}
+ {3082334400 -18000 1 -06}
+ {3101079600 -21600 0 -06}
+ {3113784000 -18000 1 -06}
+ {3132529200 -21600 0 -06}
+ {3145838400 -18000 1 -06}
+ {3163978800 -21600 0 -06}
+ {3177288000 -18000 1 -06}
+ {3195428400 -21600 0 -06}
+ {3208737600 -18000 1 -06}
+ {3226878000 -21600 0 -06}
+ {3240187200 -18000 1 -06}
+ {3258327600 -21600 0 -06}
+ {3271636800 -18000 1 -06}
+ {3290382000 -21600 0 -06}
+ {3303086400 -18000 1 -06}
+ {3321831600 -21600 0 -06}
+ {3335140800 -18000 1 -06}
+ {3353281200 -21600 0 -06}
+ {3366590400 -18000 1 -06}
+ {3384730800 -21600 0 -06}
+ {3398040000 -18000 1 -06}
+ {3416180400 -21600 0 -06}
+ {3429489600 -18000 1 -06}
+ {3447630000 -21600 0 -06}
+ {3460939200 -18000 1 -06}
+ {3479684400 -21600 0 -06}
+ {3492993600 -18000 1 -06}
+ {3511134000 -21600 0 -06}
+ {3524443200 -18000 1 -06}
+ {3542583600 -21600 0 -06}
+ {3555892800 -18000 1 -06}
+ {3574033200 -21600 0 -06}
+ {3587342400 -18000 1 -06}
+ {3605482800 -21600 0 -06}
+ {3618792000 -18000 1 -06}
+ {3637537200 -21600 0 -06}
+ {3650241600 -18000 1 -06}
+ {3668986800 -21600 0 -06}
+ {3682296000 -18000 1 -06}
+ {3700436400 -21600 0 -06}
+ {3713745600 -18000 1 -06}
+ {3731886000 -21600 0 -06}
+ {3745195200 -18000 1 -06}
+ {3763335600 -21600 0 -06}
+ {3776644800 -18000 1 -06}
+ {3794785200 -21600 0 -06}
+ {3808094400 -18000 1 -06}
+ {3826839600 -21600 0 -06}
+ {3839544000 -18000 1 -06}
+ {3858289200 -21600 0 -06}
+ {3871598400 -18000 1 -06}
+ {3889738800 -21600 0 -06}
+ {3903048000 -18000 1 -06}
+ {3921188400 -21600 0 -06}
+ {3934497600 -18000 1 -06}
+ {3952638000 -21600 0 -06}
+ {3965947200 -18000 1 -06}
+ {3984692400 -21600 0 -06}
+ {3997396800 -18000 1 -06}
+ {4016142000 -21600 0 -06}
+ {4029451200 -18000 1 -06}
+ {4047591600 -21600 0 -06}
+ {4060900800 -18000 1 -06}
+ {4079041200 -21600 0 -06}
+ {4092350400 -18000 1 -06}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Efate b/tcl8.6/library/tzdata/Pacific/Efate
index a43852e..a026ee1 100644
--- a/tcl8.6/library/tzdata/Pacific/Efate
+++ b/tcl8.6/library/tzdata/Pacific/Efate
@@ -3,24 +3,24 @@
set TZData(:Pacific/Efate) {
{-9223372036854775808 40396 0 LMT}
{-1829387596 39600 0 +11}
- {433256400 43200 1 +12}
+ {433256400 43200 1 +11}
{448977600 39600 0 +11}
- {467298000 43200 1 +12}
+ {467298000 43200 1 +11}
{480427200 39600 0 +11}
- {496760400 43200 1 +12}
+ {496760400 43200 1 +11}
{511876800 39600 0 +11}
- {528210000 43200 1 +12}
+ {528210000 43200 1 +11}
{543931200 39600 0 +11}
- {559659600 43200 1 +12}
+ {559659600 43200 1 +11}
{575380800 39600 0 +11}
- {591109200 43200 1 +12}
+ {591109200 43200 1 +11}
{606830400 39600 0 +11}
- {622558800 43200 1 +12}
+ {622558800 43200 1 +11}
{638280000 39600 0 +11}
- {654008400 43200 1 +12}
+ {654008400 43200 1 +11}
{669729600 39600 0 +11}
- {686062800 43200 1 +12}
+ {686062800 43200 1 +11}
{696340800 39600 0 +11}
- {719931600 43200 1 +12}
+ {719931600 43200 1 +11}
{727790400 39600 0 +11}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Enderbury b/tcl8.6/library/tzdata/Pacific/Enderbury
index 6abd57e..48eaafe 100644
--- a/tcl8.6/library/tzdata/Pacific/Enderbury
+++ b/tcl8.6/library/tzdata/Pacific/Enderbury
@@ -4,5 +4,5 @@ set TZData(:Pacific/Enderbury) {
{-9223372036854775808 -41060 0 LMT}
{-2177411740 -43200 0 -12}
{307627200 -39600 0 -11}
- {788958000 46800 0 +13}
+ {788871600 46800 0 +13}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Fiji b/tcl8.6/library/tzdata/Pacific/Fiji
index f9d393c..b05985c 100644
--- a/tcl8.6/library/tzdata/Pacific/Fiji
+++ b/tcl8.6/library/tzdata/Pacific/Fiji
@@ -3,189 +3,189 @@
set TZData(:Pacific/Fiji) {
{-9223372036854775808 42944 0 LMT}
{-1709985344 43200 0 +12}
- {909842400 46800 1 +13}
+ {909842400 46800 1 +12}
{920124000 43200 0 +12}
- {941896800 46800 1 +13}
+ {941896800 46800 1 +12}
{951573600 43200 0 +12}
- {1259416800 46800 1 +13}
+ {1259416800 46800 1 +12}
{1269698400 43200 0 +12}
- {1287842400 46800 1 +13}
+ {1287842400 46800 1 +12}
{1299333600 43200 0 +12}
- {1319292000 46800 1 +13}
+ {1319292000 46800 1 +12}
{1327154400 43200 0 +12}
- {1350741600 46800 1 +13}
+ {1350741600 46800 1 +12}
{1358604000 43200 0 +12}
- {1382796000 46800 1 +13}
+ {1382796000 46800 1 +12}
{1390050000 43200 0 +12}
- {1414850400 46800 1 +13}
+ {1414850400 46800 1 +12}
{1421503200 43200 0 +12}
- {1446300000 46800 1 +13}
+ {1446300000 46800 1 +12}
{1452952800 43200 0 +12}
- {1478354400 46800 1 +13}
+ {1478354400 46800 1 +12}
{1484402400 43200 0 +12}
- {1509804000 46800 1 +13}
+ {1509804000 46800 1 +12}
{1515852000 43200 0 +12}
- {1541253600 46800 1 +13}
- {1547906400 43200 0 +12}
- {1572703200 46800 1 +13}
+ {1541253600 46800 1 +12}
+ {1547301600 43200 0 +12}
+ {1572703200 46800 1 +12}
{1579356000 43200 0 +12}
- {1604152800 46800 1 +13}
+ {1604152800 46800 1 +12}
{1610805600 43200 0 +12}
- {1636207200 46800 1 +13}
+ {1636207200 46800 1 +12}
{1642255200 43200 0 +12}
- {1667656800 46800 1 +13}
+ {1667656800 46800 1 +12}
{1673704800 43200 0 +12}
- {1699106400 46800 1 +13}
+ {1699106400 46800 1 +12}
{1705154400 43200 0 +12}
- {1730556000 46800 1 +13}
+ {1730556000 46800 1 +12}
{1737208800 43200 0 +12}
- {1762005600 46800 1 +13}
+ {1762005600 46800 1 +12}
{1768658400 43200 0 +12}
- {1793455200 46800 1 +13}
+ {1793455200 46800 1 +12}
{1800108000 43200 0 +12}
- {1825509600 46800 1 +13}
+ {1825509600 46800 1 +12}
{1831557600 43200 0 +12}
- {1856959200 46800 1 +13}
+ {1856959200 46800 1 +12}
{1863007200 43200 0 +12}
- {1888408800 46800 1 +13}
- {1895061600 43200 0 +12}
- {1919858400 46800 1 +13}
+ {1888408800 46800 1 +12}
+ {1894456800 43200 0 +12}
+ {1919858400 46800 1 +12}
{1926511200 43200 0 +12}
- {1951308000 46800 1 +13}
+ {1951308000 46800 1 +12}
{1957960800 43200 0 +12}
- {1983362400 46800 1 +13}
+ {1983362400 46800 1 +12}
{1989410400 43200 0 +12}
- {2014812000 46800 1 +13}
+ {2014812000 46800 1 +12}
{2020860000 43200 0 +12}
- {2046261600 46800 1 +13}
+ {2046261600 46800 1 +12}
{2052309600 43200 0 +12}
- {2077711200 46800 1 +13}
- {2084364000 43200 0 +12}
- {2109160800 46800 1 +13}
+ {2077711200 46800 1 +12}
+ {2083759200 43200 0 +12}
+ {2109160800 46800 1 +12}
{2115813600 43200 0 +12}
- {2140610400 46800 1 +13}
+ {2140610400 46800 1 +12}
{2147263200 43200 0 +12}
- {2172664800 46800 1 +13}
+ {2172664800 46800 1 +12}
{2178712800 43200 0 +12}
- {2204114400 46800 1 +13}
+ {2204114400 46800 1 +12}
{2210162400 43200 0 +12}
- {2235564000 46800 1 +13}
- {2242216800 43200 0 +12}
- {2267013600 46800 1 +13}
+ {2235564000 46800 1 +12}
+ {2241612000 43200 0 +12}
+ {2267013600 46800 1 +12}
{2273666400 43200 0 +12}
- {2298463200 46800 1 +13}
+ {2298463200 46800 1 +12}
{2305116000 43200 0 +12}
- {2329912800 46800 1 +13}
+ {2329912800 46800 1 +12}
{2336565600 43200 0 +12}
- {2361967200 46800 1 +13}
+ {2361967200 46800 1 +12}
{2368015200 43200 0 +12}
- {2393416800 46800 1 +13}
+ {2393416800 46800 1 +12}
{2399464800 43200 0 +12}
- {2424866400 46800 1 +13}
- {2431519200 43200 0 +12}
- {2456316000 46800 1 +13}
+ {2424866400 46800 1 +12}
+ {2430914400 43200 0 +12}
+ {2456316000 46800 1 +12}
{2462968800 43200 0 +12}
- {2487765600 46800 1 +13}
+ {2487765600 46800 1 +12}
{2494418400 43200 0 +12}
- {2519820000 46800 1 +13}
+ {2519820000 46800 1 +12}
{2525868000 43200 0 +12}
- {2551269600 46800 1 +13}
+ {2551269600 46800 1 +12}
{2557317600 43200 0 +12}
- {2582719200 46800 1 +13}
+ {2582719200 46800 1 +12}
{2588767200 43200 0 +12}
- {2614168800 46800 1 +13}
+ {2614168800 46800 1 +12}
{2620821600 43200 0 +12}
- {2645618400 46800 1 +13}
+ {2645618400 46800 1 +12}
{2652271200 43200 0 +12}
- {2677068000 46800 1 +13}
+ {2677068000 46800 1 +12}
{2683720800 43200 0 +12}
- {2709122400 46800 1 +13}
+ {2709122400 46800 1 +12}
{2715170400 43200 0 +12}
- {2740572000 46800 1 +13}
+ {2740572000 46800 1 +12}
{2746620000 43200 0 +12}
- {2772021600 46800 1 +13}
- {2778674400 43200 0 +12}
- {2803471200 46800 1 +13}
+ {2772021600 46800 1 +12}
+ {2778069600 43200 0 +12}
+ {2803471200 46800 1 +12}
{2810124000 43200 0 +12}
- {2834920800 46800 1 +13}
+ {2834920800 46800 1 +12}
{2841573600 43200 0 +12}
- {2866975200 46800 1 +13}
+ {2866975200 46800 1 +12}
{2873023200 43200 0 +12}
- {2898424800 46800 1 +13}
+ {2898424800 46800 1 +12}
{2904472800 43200 0 +12}
- {2929874400 46800 1 +13}
+ {2929874400 46800 1 +12}
{2935922400 43200 0 +12}
- {2961324000 46800 1 +13}
- {2967976800 43200 0 +12}
- {2992773600 46800 1 +13}
+ {2961324000 46800 1 +12}
+ {2967372000 43200 0 +12}
+ {2992773600 46800 1 +12}
{2999426400 43200 0 +12}
- {3024223200 46800 1 +13}
+ {3024223200 46800 1 +12}
{3030876000 43200 0 +12}
- {3056277600 46800 1 +13}
+ {3056277600 46800 1 +12}
{3062325600 43200 0 +12}
- {3087727200 46800 1 +13}
+ {3087727200 46800 1 +12}
{3093775200 43200 0 +12}
- {3119176800 46800 1 +13}
- {3125829600 43200 0 +12}
- {3150626400 46800 1 +13}
+ {3119176800 46800 1 +12}
+ {3125224800 43200 0 +12}
+ {3150626400 46800 1 +12}
{3157279200 43200 0 +12}
- {3182076000 46800 1 +13}
+ {3182076000 46800 1 +12}
{3188728800 43200 0 +12}
- {3213525600 46800 1 +13}
+ {3213525600 46800 1 +12}
{3220178400 43200 0 +12}
- {3245580000 46800 1 +13}
+ {3245580000 46800 1 +12}
{3251628000 43200 0 +12}
- {3277029600 46800 1 +13}
+ {3277029600 46800 1 +12}
{3283077600 43200 0 +12}
- {3308479200 46800 1 +13}
- {3315132000 43200 0 +12}
- {3339928800 46800 1 +13}
+ {3308479200 46800 1 +12}
+ {3314527200 43200 0 +12}
+ {3339928800 46800 1 +12}
{3346581600 43200 0 +12}
- {3371378400 46800 1 +13}
+ {3371378400 46800 1 +12}
{3378031200 43200 0 +12}
- {3403432800 46800 1 +13}
+ {3403432800 46800 1 +12}
{3409480800 43200 0 +12}
- {3434882400 46800 1 +13}
+ {3434882400 46800 1 +12}
{3440930400 43200 0 +12}
- {3466332000 46800 1 +13}
+ {3466332000 46800 1 +12}
{3472380000 43200 0 +12}
- {3497781600 46800 1 +13}
+ {3497781600 46800 1 +12}
{3504434400 43200 0 +12}
- {3529231200 46800 1 +13}
+ {3529231200 46800 1 +12}
{3535884000 43200 0 +12}
- {3560680800 46800 1 +13}
+ {3560680800 46800 1 +12}
{3567333600 43200 0 +12}
- {3592735200 46800 1 +13}
+ {3592735200 46800 1 +12}
{3598783200 43200 0 +12}
- {3624184800 46800 1 +13}
+ {3624184800 46800 1 +12}
{3630232800 43200 0 +12}
- {3655634400 46800 1 +13}
- {3662287200 43200 0 +12}
- {3687084000 46800 1 +13}
+ {3655634400 46800 1 +12}
+ {3661682400 43200 0 +12}
+ {3687084000 46800 1 +12}
{3693736800 43200 0 +12}
- {3718533600 46800 1 +13}
+ {3718533600 46800 1 +12}
{3725186400 43200 0 +12}
- {3750588000 46800 1 +13}
+ {3750588000 46800 1 +12}
{3756636000 43200 0 +12}
- {3782037600 46800 1 +13}
+ {3782037600 46800 1 +12}
{3788085600 43200 0 +12}
- {3813487200 46800 1 +13}
+ {3813487200 46800 1 +12}
{3819535200 43200 0 +12}
- {3844936800 46800 1 +13}
- {3851589600 43200 0 +12}
- {3876386400 46800 1 +13}
+ {3844936800 46800 1 +12}
+ {3850984800 43200 0 +12}
+ {3876386400 46800 1 +12}
{3883039200 43200 0 +12}
- {3907836000 46800 1 +13}
+ {3907836000 46800 1 +12}
{3914488800 43200 0 +12}
- {3939890400 46800 1 +13}
+ {3939890400 46800 1 +12}
{3945938400 43200 0 +12}
- {3971340000 46800 1 +13}
+ {3971340000 46800 1 +12}
{3977388000 43200 0 +12}
- {4002789600 46800 1 +13}
- {4009442400 43200 0 +12}
- {4034239200 46800 1 +13}
+ {4002789600 46800 1 +12}
+ {4008837600 43200 0 +12}
+ {4034239200 46800 1 +12}
{4040892000 43200 0 +12}
- {4065688800 46800 1 +13}
+ {4065688800 46800 1 +12}
{4072341600 43200 0 +12}
- {4097138400 46800 1 +13}
+ {4097138400 46800 1 +12}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Galapagos b/tcl8.6/library/tzdata/Pacific/Galapagos
index f276f73..180ce6a 100644
--- a/tcl8.6/library/tzdata/Pacific/Galapagos
+++ b/tcl8.6/library/tzdata/Pacific/Galapagos
@@ -4,6 +4,6 @@ set TZData(:Pacific/Galapagos) {
{-9223372036854775808 -21504 0 LMT}
{-1230746496 -18000 0 -05}
{504939600 -21600 0 -06}
- {722930400 -18000 1 -05}
+ {722930400 -18000 1 -06}
{728888400 -21600 0 -06}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Honolulu b/tcl8.6/library/tzdata/Pacific/Honolulu
index 5e70598..7d03b45 100644
--- a/tcl8.6/library/tzdata/Pacific/Honolulu
+++ b/tcl8.6/library/tzdata/Pacific/Honolulu
@@ -4,8 +4,9 @@ set TZData(:Pacific/Honolulu) {
{-9223372036854775808 -37886 0 LMT}
{-2334101314 -37800 0 HST}
{-1157283000 -34200 1 HDT}
- {-1155436200 -37800 0 HST}
- {-880198200 -34200 1 HDT}
+ {-1155436200 -34200 0 HST}
+ {-880201800 -34200 1 HWT}
+ {-769395600 -34200 1 HPT}
{-765376200 -37800 0 HST}
{-712150200 -36000 0 HST}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Kiritimati b/tcl8.6/library/tzdata/Pacific/Kiritimati
index b703f19..7d600f3 100644
--- a/tcl8.6/library/tzdata/Pacific/Kiritimati
+++ b/tcl8.6/library/tzdata/Pacific/Kiritimati
@@ -4,5 +4,5 @@ set TZData(:Pacific/Kiritimati) {
{-9223372036854775808 -37760 0 LMT}
{-2177415040 -38400 0 -1040}
{307622400 -36000 0 -10}
- {788954400 50400 0 +14}
+ {788868000 50400 0 +14}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Noumea b/tcl8.6/library/tzdata/Pacific/Noumea
index 36b570d..c9da825 100644
--- a/tcl8.6/library/tzdata/Pacific/Noumea
+++ b/tcl8.6/library/tzdata/Pacific/Noumea
@@ -3,10 +3,10 @@
set TZData(:Pacific/Noumea) {
{-9223372036854775808 39948 0 LMT}
{-1829387148 39600 0 +11}
- {250002000 43200 1 +12}
+ {250002000 43200 1 +11}
{257342400 39600 0 +11}
- {281451600 43200 1 +12}
+ {281451600 43200 1 +11}
{288878400 39600 0 +11}
- {849366000 43200 1 +12}
+ {849366000 43200 1 +11}
{857228400 39600 0 +11}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Rarotonga b/tcl8.6/library/tzdata/Pacific/Rarotonga
index 9a70318..2913d68 100644
--- a/tcl8.6/library/tzdata/Pacific/Rarotonga
+++ b/tcl8.6/library/tzdata/Pacific/Rarotonga
@@ -3,30 +3,30 @@
set TZData(:Pacific/Rarotonga) {
{-9223372036854775808 -38344 0 LMT}
{-2177414456 -37800 0 -1030}
- {279714600 -34200 0 -0930}
+ {279714600 -34200 0 -10}
{289387800 -36000 0 -10}
- {309952800 -34200 1 -0930}
+ {309952800 -34200 1 -10}
{320837400 -36000 0 -10}
- {341402400 -34200 1 -0930}
+ {341402400 -34200 1 -10}
{352287000 -36000 0 -10}
- {372852000 -34200 1 -0930}
+ {372852000 -34200 1 -10}
{384341400 -36000 0 -10}
- {404906400 -34200 1 -0930}
+ {404906400 -34200 1 -10}
{415791000 -36000 0 -10}
- {436356000 -34200 1 -0930}
+ {436356000 -34200 1 -10}
{447240600 -36000 0 -10}
- {467805600 -34200 1 -0930}
+ {467805600 -34200 1 -10}
{478690200 -36000 0 -10}
- {499255200 -34200 1 -0930}
+ {499255200 -34200 1 -10}
{510139800 -36000 0 -10}
- {530704800 -34200 1 -0930}
+ {530704800 -34200 1 -10}
{541589400 -36000 0 -10}
- {562154400 -34200 1 -0930}
+ {562154400 -34200 1 -10}
{573643800 -36000 0 -10}
- {594208800 -34200 1 -0930}
+ {594208800 -34200 1 -10}
{605093400 -36000 0 -10}
- {625658400 -34200 1 -0930}
+ {625658400 -34200 1 -10}
{636543000 -36000 0 -10}
- {657108000 -34200 1 -0930}
+ {657108000 -34200 1 -10}
{667992600 -36000 0 -10}
}
diff --git a/tcl8.6/library/tzdata/Pacific/Tongatapu b/tcl8.6/library/tzdata/Pacific/Tongatapu
index 3cfaaaa..104888a 100644
--- a/tcl8.6/library/tzdata/Pacific/Tongatapu
+++ b/tcl8.6/library/tzdata/Pacific/Tongatapu
@@ -5,12 +5,12 @@ set TZData(:Pacific/Tongatapu) {
{-2177497160 44400 0 +1220}
{-915193200 46800 0 +13}
{915102000 46800 0 +13}
- {939214800 50400 1 +14}
+ {939214800 50400 1 +13}
{953384400 46800 0 +13}
- {973342800 50400 1 +14}
+ {973342800 50400 1 +13}
{980596800 46800 0 +13}
- {1004792400 50400 1 +14}
+ {1004792400 50400 1 +13}
{1012046400 46800 0 +13}
- {1478350800 50400 1 +14}
+ {1478350800 50400 1 +13}
{1484398800 46800 0 +13}
}
diff --git a/tcl8.6/macosx/configure b/tcl8.6/macosx/configure
index 7395ea0..895469f 100755
--- a/tcl8.6/macosx/configure
+++ b/tcl8.6/macosx/configure
@@ -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=".8"
+TCL_PATCH_LEVEL=".9"
VERSION=${TCL_VERSION}
EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
@@ -4286,8 +4286,6 @@ $as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h
#--------------------------------------------------------------------
# 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"
@@ -4297,40 +4295,6 @@ 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
@@ -5809,7 +5773,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -6625,7 +6589,7 @@ fi
BSD/OS*) ;;
CYGWIN_*|MINGW32_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
*) SHLIB_CFLAGS="-fPIC" ;;
@@ -7105,6 +7069,40 @@ $as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5
+$as_echo_n "checking for DIR64... " >&6; }
+if ${tcl_cv_DIR64+:} 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; DIR64 d = opendir64(".");
+ p = readdir64(d); rewinddir64(d); closedir64(d);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_DIR64=yes
+else
+ tcl_cv_DIR64=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5
+$as_echo "$tcl_cv_DIR64" >&6; }
+ if test "x${tcl_cv_DIR64}" = "xyes" ; then
+
+$as_echo "#define HAVE_DIR64 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 :
@@ -8889,140 +8887,6 @@ esac
#--------------------------------------------------------------------
-# Check for the strtod function. This is tricky because in some
-# versions of Linux strtod mis-parses strings starting with "+".
-#--------------------------------------------------------------------
-
-
- ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod"
-if test "x$ac_cv_func_strtod" = xyes; then :
- tcl_ok=1
-else
- tcl_ok=0
-fi
-
- if test "$tcl_ok" = 1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtod implementation" >&5
-$as_echo_n "checking proper strtod implementation... " >&6; }
-if ${tcl_cv_strtod_unbroken+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- tcl_cv_strtod_unbroken=unknown
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-int main() {
- extern double strtod();
- char *term, *string = " +69";
- exit(strtod(string,&term) != 69 || term != string+4);
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- tcl_cv_strtod_unbroken=ok
-else
- tcl_cv_strtod_unbroken=broken
-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_strtod_unbroken" >&5
-$as_echo "$tcl_cv_strtod_unbroken" >&6; }
- if test "$tcl_cv_strtod_unbroken" = "ok"; then
- tcl_ok=1
- else
- tcl_ok=0
- fi
- fi
- if test "$tcl_ok" = 0; then
- case " $LIBOBJS " in
- *" strtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strtod.$ac_objext"
- ;;
-esac
-
- USE_COMPAT=1
- fi
-
-
-#--------------------------------------------------------------------
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" that corrects the error.
-#--------------------------------------------------------------------
-
-
- ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod"
-if test "x$ac_cv_func_strtod" = xyes; then :
- tcl_strtod=1
-else
- tcl_strtod=0
-fi
-
- if test "$tcl_strtod" = 1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5
-$as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; }
-if ${tcl_cv_strtod_buggy+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
- if test "$cross_compiling" = yes; then :
- tcl_cv_strtod_buggy=buggy
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- tcl_cv_strtod_buggy=ok
-else
- tcl_cv_strtod_buggy=buggy
-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_strtod_buggy" >&5
-$as_echo "$tcl_cv_strtod_buggy" >&6; }
- if test "$tcl_cv_strtod_buggy" = buggy; then
- case " $LIBOBJS " in
- *" fixstrtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext"
- ;;
-esac
-
- USE_COMPAT=1
-
-$as_echo "#define strtod fixstrtod" >>confdefs.h
-
- fi
- fi
-
-
-#--------------------------------------------------------------------
# Check for various typedefs and provide substitutes if
# they don't exist.
#--------------------------------------------------------------------
diff --git a/tcl8.6/pkgs/itcl4.1.1/aclocal.m4 b/tcl8.6/pkgs/itcl4.1.1/aclocal.m4
deleted file mode 100644
index 93b411d..0000000
--- a/tcl8.6/pkgs/itcl4.1.1/aclocal.m4
+++ /dev/null
@@ -1,2 +0,0 @@
-AC_PREREQ(2.57)
-builtin(include, tclconfig/tcl.m4)
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/man.macros b/tcl8.6/pkgs/itcl4.1.1/doc/man.macros
deleted file mode 100644
index 3af2da9..0000000
--- a/tcl8.6/pkgs/itcl4.1.1/doc/man.macros
+++ /dev/null
@@ -1,236 +0,0 @@
-'\" The definitions below are for supplemental macros used in Tcl/Tk
-'\" manual entries.
-'\"
-'\" .AP type name in/out ?indent?
-'\" Start paragraph describing an argument to a library procedure.
-'\" type is type of argument (int, etc.), in/out is either "in", "out",
-'\" or "in/out" to describe whether procedure reads or modifies arg,
-'\" and indent is equivalent to second arg of .IP (shouldn't ever be
-'\" needed; use .AS below instead)
-'\"
-'\" .AS ?type? ?name?
-'\" Give maximum sizes of arguments for setting tab stops. Type and
-'\" name are examples of largest possible arguments that will be passed
-'\" to .AP later. If args are omitted, default tab stops are used.
-'\"
-'\" .BS
-'\" Start box enclosure. From here until next .BE, everything will be
-'\" enclosed in one large box.
-'\"
-'\" .BE
-'\" End of box enclosure.
-'\"
-'\" .CS
-'\" Begin code excerpt.
-'\"
-'\" .CE
-'\" End code excerpt.
-'\"
-'\" .VS ?version? ?br?
-'\" Begin vertical sidebar, for use in marking newly-changed parts
-'\" of man pages. The first argument is ignored and used for recording
-'\" the version when the .VS was added, so that the sidebars can be
-'\" found and removed when they reach a certain age. If another argument
-'\" is present, then a line break is forced before starting the sidebar.
-'\"
-'\" .VE
-'\" End of vertical sidebar.
-'\"
-'\" .DS
-'\" Begin an indented unfilled display.
-'\"
-'\" .DE
-'\" End of indented unfilled display.
-'\"
-'\" .SO
-'\" Start of list of standard options for a Tk widget. The
-'\" options follow on successive lines, in four columns separated
-'\" by tabs.
-'\"
-'\" .SE
-'\" End of list of standard options for a Tk widget.
-'\"
-'\" .OP cmdName dbName dbClass
-'\" Start of description of a specific option. cmdName gives the
-'\" option's name as specified in the class command, dbName gives
-'\" the option's name in the option database, and dbClass gives
-'\" the option's class in the option database.
-'\"
-'\" .UL arg1 arg2
-'\" Print arg1 underlined, then print arg2 normally.
-'\"
-'\" SCCS: @(#) man.macros 1.9 97/08/22 18:50:59
-'\"
-'\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
-.if t .wh -1.3i ^B
-.nr ^l \n(.l
-.ad b
-'\" # Start an argument description
-.de AP
-.ie !"\\$4"" .TP \\$4
-.el \{\
-. ie !"\\$2"" .TP \\n()Cu
-. el .TP 15
-.\}
-.ie !"\\$3"" \{\
-.ta \\n()Au \\n()Bu
-\&\\$1 \\fI\\$2\\fP (\\$3)
-.\".b
-.\}
-.el \{\
-.br
-.ie !"\\$2"" \{\
-\&\\$1 \\fI\\$2\\fP
-.\}
-.el \{\
-\&\\fI\\$1\\fP
-.\}
-.\}
-..
-'\" # define tabbing values for .AP
-.de AS
-.nr )A 10n
-.if !"\\$1"" .nr )A \\w'\\$1'u+3n
-.nr )B \\n()Au+15n
-.\"
-.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
-.nr )C \\n()Bu+\\w'(in/out)'u+2n
-..
-.AS Tcl_Interp Tcl_CreateInterp in/out
-'\" # BS - start boxed text
-'\" # ^y = starting y location
-'\" # ^b = 1
-.de BS
-.br
-.mk ^y
-.nr ^b 1u
-.if n .nf
-.if n .ti 0
-.if n \l'\\n(.lu\(ul'
-.if n .fi
-..
-'\" # BE - end boxed text (draw box now)
-.de BE
-.nf
-.ti 0
-.mk ^t
-.ie n \l'\\n(^lu\(ul'
-.el \{\
-.\" Draw four-sided box normally, but don't draw top of
-.\" box if the box started on an earlier page.
-.ie !\\n(^b-1 \{\
-\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
-.\}
-.el \}\
-\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
-.\}
-.\}
-.fi
-.br
-.nr ^b 0
-..
-'\" # VS - start vertical sidebar
-'\" # ^Y = starting y location
-'\" # ^v = 1 (for troff; for nroff this doesn't matter)
-.de VS
-.if !"\\$2"" .br
-.mk ^Y
-.ie n 'mc \s12\(br\s0
-.el .nr ^v 1u
-..
-'\" # VE - end of vertical sidebar
-.de VE
-.ie n 'mc
-.el \{\
-.ev 2
-.nf
-.ti 0
-.mk ^t
-\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
-.sp -1
-.fi
-.ev
-.\}
-.nr ^v 0
-..
-'\" # Special macro to handle page bottom: finish off current
-'\" # box/sidebar if in box/sidebar mode, then invoked standard
-'\" # page bottom macro.
-.de ^B
-.ev 2
-'ti 0
-'nf
-.mk ^t
-.if \\n(^b \{\
-.\" Draw three-sided box if this is the box's first page,
-.\" draw two sides but no top otherwise.
-.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
-.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
-.\}
-.if \\n(^v \{\
-.nr ^x \\n(^tu+1v-\\n(^Yu
-\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
-.\}
-.bp
-'fi
-.ev
-.if \\n(^b \{\
-.mk ^y
-.nr ^b 2
-.\}
-.if \\n(^v \{\
-.mk ^Y
-.\}
-..
-'\" # DS - begin display
-.de DS
-.RS
-.nf
-.sp
-..
-'\" # DE - end display
-.de DE
-.fi
-.RE
-.sp
-..
-'\" # SO - start of list of standard options
-.de SO
-.SH "STANDARD OPTIONS"
-.LP
-.nf
-.ta 4c 8c 12c
-.ft B
-..
-'\" # SE - end of list of standard options
-.de SE
-.fi
-.ft R
-.LP
-See the \\fBoptions\\fR manual entry for details on the standard options.
-..
-'\" # OP - start of full description for a single option
-.de OP
-.LP
-.nf
-.ta 4c
-Command-Line Name: \\fB\\$1\\fR
-Database Name: \\fB\\$2\\fR
-Database Class: \\fB\\$3\\fR
-.fi
-.IP
-..
-'\" # CS - begin code excerpt
-.de CS
-.RS
-.nf
-.ta .25i .5i .75i 1i
-..
-'\" # CE - end code excerpt
-.de CE
-.fi
-.RE
-..
-.de UL
-\\$1\l'|0\(ul'\\$2
-..
diff --git a/tcl8.6/pkgs/itcl4.1.2/.project b/tcl8.6/pkgs/itcl4.1.2/.project
new file mode 100644
index 0000000..43a6390
--- /dev/null
+++ b/tcl8.6/pkgs/itcl4.1.2/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>itcl</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
diff --git a/tcl8.6/pkgs/itcl4.1.1/ChangeLog b/tcl8.6/pkgs/itcl4.1.2/ChangeLog
index cd9122b..80499de 100644
--- a/tcl8.6/pkgs/itcl4.1.1/ChangeLog
+++ b/tcl8.6/pkgs/itcl4.1.2/ChangeLog
@@ -1,7 +1,7 @@
NOTICE: This ChangeLog is no longer being maintained. To examine
the series of changes checked into Itcl sources, follow the Timeline
-https://core.tcl.tk/itcl/timeline
+https://core.tcl-lang.org/itcl/timeline
2014-11-06 Don Porter <dgp@Users.sourceforge.net>
* generic/itclMigrate2TclCore.c: Fix for SF Bug 259.
diff --git a/tcl8.6/pkgs/itcl4.1.1/Makefile.in b/tcl8.6/pkgs/itcl4.1.2/Makefile.in
index 24d8e92..bb53259 100644
--- a/tcl8.6/pkgs/itcl4.1.1/Makefile.in
+++ b/tcl8.6/pkgs/itcl4.1.2/Makefile.in
@@ -85,15 +85,15 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
-top_builddir = .
+top_builddir = @abs_top_builddir@
INSTALL_OPTIONS =
-INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
-INSTALL_DATA_DIR = ${INSTALL} -d -m 755
-INSTALL_PROGRAM = ${INSTALL} -m 755
-INSTALL_DATA = ${INSTALL} -m 644
-INSTALL_SCRIPT = ${INSTALL_PROGRAM}
-INSTALL_LIBRARY = ${INSTALL_DATA}
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@@ -113,14 +113,14 @@ SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_LD = @SHLIB_LD@
SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
STLIB_LD = @STLIB_LD@
-TCL_DEFS = @TCL_DEFS@
+#TCL_DEFS = @TCL_DEFS@
TCL_BIN_DIR = @TCL_BIN_DIR@
TCL_SRC_DIR = @TCL_SRC_DIR@
#TK_BIN_DIR = @TK_BIN_DIR@
#TK_SRC_DIR = @TK_SRC_DIR@
# Not used, but retained for reference of what libs Tcl required
-TCL_LIBS = @TCL_LIBS@
+#TCL_LIBS = @TCL_LIBS@
#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
@@ -131,13 +131,15 @@ TCL_LIBS = @TCL_LIBS@
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
+TCLLIBPATH = $(top_builddir)
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
-PKG_ENV = ITCL_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
- @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(top_builddir)"
+ ITCL_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+ TCLLIBPATH="$(TCLLIBPATH)"
+
TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
@@ -147,12 +149,19 @@ SHARED_BUILD = @SHARED_BUILD@
STUBS_BUILD = @STUBS_BUILD@
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
+#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
PKG_CFLAGS = @PKG_CFLAGS@
-DEFS = @DEFS@ $(PKG_CFLAGS) \
- -DITCL_LIBRARY=\"$(pkglibdir)\"
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.ac checks for the necessary components
+# that your library may use. TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS = @DEFS@ $(PKG_CFLAGS) -DITCL_LIBRARY=\"$(pkglibdir)\"
+# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = @CONFIG_CLEAN_FILES@ Makefile itclConfig.sh pkgIndex.tcl
CLEANFILES = @CLEANFILES@
@@ -162,6 +171,11 @@ AR = @AR@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
.SUFFIXES: .c .$(OBJEXT)
#========================================================================
@@ -222,41 +236,46 @@ install-libraries: libraries
install-doc: doc
@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
@echo "Installing documentation in $(DESTDIR)$(mandir)"
- @cd $(srcdir)/doc; for i in *.n; do \
- echo "Installing $$i"; \
- rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
- sed -e '/man\.macros/r man.macros' -e '/man\.macros/d' \
- $$i > $(DESTDIR)$(mandir)/mann/$$i; \
- chmod 444 $(DESTDIR)$(mandir)/mann/$$i; \
+ @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+ if test X"$$i" = X'$(srcdir)/doc/*.n'; then break; fi; \
+ bi=`basename $$i`; \
+ echo "Installing $$bi"; \
+ sed -e '/man\.macros/r $(srcdir)/doc/man.macros' -e '/man\.macros/d' $$i > $$bi.tmp \
+ && $(INSTALL_DATA) $$bi.tmp $(DESTDIR)$(mandir)/mann/$$bi \
+ && rm -f $$bi.tmp; \
done
test: binaries libraries
- @$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
- -load "if {[catch {package present ${PACKAGE_NAME}}]} {package forget ${PACKAGE_NAME}; package ifneeded ${PACKAGE_NAME} ${PACKAGE_VERSION} \
+ $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
+ -load "if {[catch {package present ${PACKAGE_NAME}}]} {package forget ${PACKAGE_NAME}; \
+ package ifneeded ${PACKAGE_NAME} ${PACKAGE_VERSION} \
[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]}"
-genstubs: $(srcdir)/tools/genStubs.tcl $(srcdir)/generic/itcl.decls
- @echo $(TCLSH) $(srcdir)/tools/genStubs.tcl $(srcdir)/generic $(srcdir)/generic/itcl.decls
- @$(TCLSH) $(srcdir)/tools/genStubs.tcl $(srcdir)/generic $(srcdir)/generic/itcl.decls
-
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
- $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
-VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
- --leak-check=yes --show-reachable=yes -v
+gdb-test: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) \
+ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
+ $(TESTFLAGS) -singleproc 1 \
+ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+ [list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
valgrind: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
- `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
+ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
depend:
+genstubs: $(srcdir)/tools/genStubs.tcl $(srcdir)/generic/itcl.decls
+ $(TCLSH) $(srcdir)/tools/genStubs.tcl $(srcdir)/generic $(srcdir)/generic/itcl.decls
+
#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above. That will ensure that this target is built when you
@@ -284,8 +303,8 @@ $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
# containing your extension. If your sources are in a subdirectory,
# you will have to modify the paths to reflect this:
#
-# exampleA.$(OBJEXT): $(srcdir)/generic/exampleA.c
-# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/exampleA.c` -o $@
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
@@ -302,27 +321,41 @@ VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macos
# You may need to tweak this target to make it work correctly.
#========================================================================
-TAR = tar
-#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
-COMPRESS = $(TAR) zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
-DIST_ROOT = /tmp/dist
-DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT = /tmp/dist
+DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean doc
$(INSTALL_DATA_DIR) $(DIST_DIR)
- cp -p $(srcdir)/license* $(srcdir)/aclocal.m4 $(srcdir)/configure* \
- $(srcdir)/*.in $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
+
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
- cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
- $(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(srcdir)/itclConfig.sh.in \
+ $(srcdir)/TODO $(srcdir)/releasenotes.txt \
+ $(srcdir)/.project \
+ $(DIST_DIR)/
list='doc generic library tests tools win'; \
for p in $$list; do \
@@ -330,19 +363,12 @@ dist: dist-clean doc
$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
for q in $(srcdir)/$$p/*; do \
if test -f $$q ; then \
- cp -p $$q $(DIST_DIR)/$$p/; \
+ $(DIST_INSTALL_DATA) $$q $(DIST_DIR)/$$p/; \
fi; \
done; \
fi; \
done
- list='CHANGES ChangeLog INCOMPATIBLE README releasenotes.txt TODO'; \
- for p in $$list; do \
- if test -f $(srcdir)/$$p ; then \
- cp -p $(srcdir)/$$p $(DIST_DIR)/; \
- fi; \
- done
-
(cd $(DIST_ROOT); $(COMPRESS);)
#========================================================================
@@ -351,7 +377,7 @@ dist: dist-clean doc
#========================================================================
# Don't modify the file to clean here. Instead, set the "CLEANFILES"
-# variable in configure.in
+# variable in configure.ac
#========================================================================
clean:
@@ -368,10 +394,9 @@ distclean: clean
# Install binary object libraries. On Windows this includes both .dll and
# .lib files. Because the .lib files are not explicitly listed anywhere,
# we need to deduce their existence from the .dll file of the same name.
-# Additionally, the .dll files go into the bin directory, but the .lib
-# files go into the lib directory. On Unix platforms, all library files
-# go into the lib directory. In addition, this will generate the pkgIndex.tcl
-# file in the install location (assuming it can find a usable tclsh)
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================
@@ -382,14 +407,6 @@ install-lib-binaries: binaries
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
- stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
- if test "x$$stub" = "xstub"; then \
- echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
- else \
- echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
- fi; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
@@ -448,6 +465,8 @@ uninstall-binaries:
done
.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb gdb-test valgrind valgrindshell
+.PHONY: genstubs
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tcl8.6/pkgs/itcl4.1.1/README b/tcl8.6/pkgs/itcl4.1.2/README
index fe5b638..4901b89 100644
--- a/tcl8.6/pkgs/itcl4.1.1/README
+++ b/tcl8.6/pkgs/itcl4.1.2/README
@@ -1,6 +1,6 @@
README: Itcl
-This is the 4.1.1 source distribution of Itcl, an object oriented
+This is the 4.1.2 source distribution of Itcl, an object oriented
extension for Tcl. Itcl releases are available from Sourceforge at:
https://sourceforge.net/projects/incrtcl/files/%5Bincr%20Tcl_Tk%5D-4-source/
diff --git a/tcl8.6/pkgs/itcl4.1.1/TODO b/tcl8.6/pkgs/itcl4.1.2/TODO
index e707dea..e707dea 100644
--- a/tcl8.6/pkgs/itcl4.1.1/TODO
+++ b/tcl8.6/pkgs/itcl4.1.2/TODO
diff --git a/tcl8.6/pkgs/sqlite3.21.0/aclocal.m4 b/tcl8.6/pkgs/itcl4.1.2/aclocal.m4
index 0b05739..0b05739 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/aclocal.m4
+++ b/tcl8.6/pkgs/itcl4.1.2/aclocal.m4
diff --git a/tcl8.6/pkgs/itcl4.1.1/configure b/tcl8.6/pkgs/itcl4.1.2/configure
index 46ce825..2012aae 100755
--- a/tcl8.6/pkgs/itcl4.1.1/configure
+++ b/tcl8.6/pkgs/itcl4.1.2/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for itcl 4.1.1.
+# Generated by GNU Autoconf 2.69 for itcl 4.1.2.
#
#
# 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.1.1'
-PACKAGE_STRING='itcl 4.1.1'
+PACKAGE_VERSION='4.1.2'
+PACKAGE_STRING='itcl 4.1.2'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -632,8 +632,6 @@ itcl_BUILD_STUB_LIB_SPEC
itcl_LIB_SPEC
itcl_BUILD_LIB_SPEC
TCLSH_PROG
-itcl_LIB_FILE
-itcl_STUB_LIB_FILE
VC_MANIFEST_EMBED_EXE
VC_MANIFEST_EMBED_DLL
RANLIB_STUB
@@ -662,17 +660,10 @@ TCL_TOP_DIR_NATIVE
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
@@ -698,6 +689,12 @@ TCL_PATCH_LEVEL
TCL_VERSION
CONFIG_CLEAN_FILES
LN_S
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1311,7 +1308,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.1.1 to adapt to many kinds of systems.
+\`configure' configures itcl 4.1.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1372,7 +1369,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of itcl 4.1.1:";;
+ short | recursive ) echo "Configuration of itcl 4.1.2:";;
esac
cat <<\_ACEOF
@@ -1474,7 +1471,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-itcl configure 4.1.1
+itcl configure 4.1.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1749,93 +1746,6 @@ $as_echo "$ac_res" >&6; }
} # 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
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -1893,7 +1803,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.1.1, which was
+It was created by itcl $as_me 4.1.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2249,26 +2159,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2277,7 +2177,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2369,6 +2269,62 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Try to ensure the existence of a tclconfig directory in either
+# $srcdir or the current dir, if one can't be found in $srcdir.
+# If this package is being built as part of a bundle then a tclconfig
+# directory might exist in $srcdir's parent directory.
+#--------------------------------------------------------------------
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
$as_echo_n "checking whether ln -s works... " >&6; }
@@ -2384,12 +2340,16 @@ fi
CONFIG_CLEAN_FILES=
if test ! -d $srcdir/tclconfig ; then
if test -d $srcdir/../tclconfig ; then
- $LN_S $srcdir/../tclconfig tclconfig
- CONFIG_CLEAN_FILES=tclconfig
+ $LN_S $srcdir/../tclconfig tclconfig
+ CONFIG_CLEAN_FILES=tclconfig
fi
fi
+#--------------------------------------------------------------------
+# Tell autoconf where to find tcl.m4 and install.sh.
+#--------------------------------------------------------------------
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
if test -f "$ac_dir/install-sh"; then
@@ -2498,6 +2458,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2524,13 +2487,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -3524,6 +3491,10 @@ _ACEOF
+#--------------------------------------------------------------------
+# Tcl 8.6+ required.
+#--------------------------------------------------------------------
+
if test "${TCL_MAJOR_VERSION}" -lt 8; then
as_fn_error $? "${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
@@ -3535,6 +3506,13 @@ 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
+#--------------------------------------------------------------------
+# 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.
@@ -4255,20 +4233,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -4940,470 +4904,6 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
#-----------------------------------------------------------------------
@@ -5550,22 +5050,22 @@ done
#--------------------------------------------------------------------
# __CHANGE__
-# A few miscellaneous platform-specific items:
#
-# Define a special symbol for Windows (BUILD_itcl in this case) so
-# that we create the export library with the dll. See sha1.h on how
-# to use this.
-#
-# Windows creates a few extra files that need to be cleaned up.
# You can add more files to clean if your extension creates any extra
-# files.
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
-# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
-# These will be appended to the current set of compiler flags for
-# your system.
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
vars="dllEntryPoint.c"
for i in $vars; do
@@ -5601,6 +5101,11 @@ if test "${TEA_PLATFORM}" = "windows" ; then
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
@@ -5609,9 +5114,7 @@ fi
# hard to only rely on the Tcl public header files. Internal headers
# contain private data structures and are subject to change without
# notice.
-# This must be done AFTER calling TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG
-# so that we can extract TCL_SRC_DIR from the config file (in the case
-# of private headers
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
#--------------------------------------------------------------------
#TEA_PUBLIC_TCL_HEADERS
@@ -5758,6 +5261,10 @@ $as_echo_n "checking for Tcl private include files... " >&6; }
$as_echo "${result}" >&6; }
+#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.
@@ -7462,7 +6969,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8096,9 +7603,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -8878,23 +8385,11 @@ rm -f conftest*
#--------------------------------------------------------------------
-# __CHANGE__
-# Change the name from exampeA_LIB_FILE to match your package name.
-# Use the stub_LIB_FILE substitution if your package creates a stub
-# library.
-#--------------------------------------------------------------------
-
-itcl_STUB_LIB_FILE=${PKG_STUB_LIB_FILE}
-itcl_LIB_FILE=${PKG_LIB_FILE}
-
-
-
-#--------------------------------------------------------------------
-# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
-# file during the install process. Don't run the TCLSH_PROG through
-# ${CYGPATH} because it's being used directly by make.
-# Require that we use a tclsh shell version 8.2 or later since earlier
-# versions have bugs in the pkg_mkIndex routine.
+# 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.
#--------------------------------------------------------------------
@@ -8937,6 +8432,7 @@ $as_echo_n "checking for tclsh... " >&6; }
$as_echo "${TCLSH_PROG}" >&6; }
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# These are for itclConfig.sh
@@ -8980,11 +8476,13 @@ eval itcl_SRC_DIR="$srcdir"
itcl_SRC_DIR=`cd "${itcl_SRC_DIR}"; pwd`
-eval itcl_INCLUDE_SPEC="${itcl_SRC_DIR}/generic"
+eval itcl_INCLUDE_SPEC="-I${itcl_SRC_DIR}/generic"
#--------------------------------------------------------------------
# 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 the AC variables in. Include these here.
#--------------------------------------------------------------------
ac_config_files="$ac_config_files Makefile pkgIndex.tcl itclConfig.sh"
@@ -9533,7 +9031,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.1.1, which was
+This file was extended by itcl $as_me 4.1.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9586,7 +9084,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.1.1
+itcl config.status 4.1.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/itcl4.1.1/configure.ac b/tcl8.6/pkgs/itcl4.1.2/configure.ac
index 8c81d4f..c192f5c 100755..100644
--- a/tcl8.6/pkgs/itcl4.1.1/configure.ac
+++ b/tcl8.6/pkgs/itcl4.1.2/configure.ac
@@ -1,16 +1,25 @@
#!/bin/bash -norc
-#--------------------------------------------------------------------
+dnl This file is an input file used by the GNU "autoconf" program to
+dnl generate the file "configure", which is run during Tcl installation
+dnl to configure the system for the local environment.
+
+#-----------------------------------------------------------------------
# Sample configure.ac for Tcl Extensions. The only places you should
# need to modify this file are marked by the string __CHANGE__
-#--------------------------------------------------------------------
+#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
#-----------------------------------------------------------------------
-AC_INIT([itcl], [4.1.1])
+AC_INIT([itcl], [4.1.2])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -18,18 +27,29 @@ AC_INIT([itcl], [4.1.1])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
+
+#--------------------------------------------------------------------
+# Try to ensure the existence of a tclconfig directory in either
+# $srcdir or the current dir, if one can't be found in $srcdir.
+# If this package is being built as part of a bundle then a tclconfig
+# directory might exist in $srcdir's parent directory.
+#--------------------------------------------------------------------
AC_PROG_LN_S
CONFIG_CLEAN_FILES=
if test ! -d $srcdir/tclconfig ; then
if test -d $srcdir/../tclconfig ; then
- $LN_S $srcdir/../tclconfig tclconfig
- CONFIG_CLEAN_FILES=tclconfig
+ $LN_S $srcdir/../tclconfig tclconfig
+ CONFIG_CLEAN_FILES=tclconfig
fi
fi
AC_SUBST(CONFIG_CLEAN_FILES)
+#--------------------------------------------------------------------
+# Tell autoconf where to find tcl.m4 and install.sh.
+#--------------------------------------------------------------------
+
AC_CONFIG_AUX_DIR(tclconfig)
#--------------------------------------------------------------------
@@ -39,6 +59,10 @@ AC_CONFIG_AUX_DIR(tclconfig)
TEA_PATH_TCLCONFIG
TEA_LOAD_TCLCONFIG
+#--------------------------------------------------------------------
+# Tcl 8.6+ required.
+#--------------------------------------------------------------------
+
if test "${TCL_MAJOR_VERSION}" -lt 8; then
AC_MSG_ERROR([${TCL_BIN_DIR}/tclConfig.sh is for Tcl ${TCL_VERSION}.
Itcl ${PACKAGE_VERSION} needs Tcl 8.6 or higher.
@@ -50,6 +74,13 @@ 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
+#--------------------------------------------------------------------
+# 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.
@@ -114,23 +145,28 @@ TEA_ADD_TCL_SOURCES([library/itcl.tcl library/itclWidget.tcl library/itclHullCmd
#--------------------------------------------------------------------
# __CHANGE__
-# A few miscellaneous platform-specific items:
-#
-# Define a special symbol for Windows (BUILD_itcl in this case) so
-# that we create the export library with the dll. See sha1.h on how
-# to use this.
#
-# Windows creates a few extra files that need to be cleaned up.
# You can add more files to clean if your extension creates any extra
-# files.
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
-# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
-# These will be appended to the current set of compiler flags for
-# your system.
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
TEA_ADD_SOURCES([dllEntryPoint.c])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
@@ -139,14 +175,16 @@ fi
# hard to only rely on the Tcl public header files. Internal headers
# contain private data structures and are subject to change without
# notice.
-# This must be done AFTER calling TEA_PATH_TCLCONFIG/TEA_LOAD_TCLCONFIG
-# so that we can extract TCL_SRC_DIR from the config file (in the case
-# of private headers
+# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
#--------------------------------------------------------------------
#TEA_PUBLIC_TCL_HEADERS
TEA_PRIVATE_TCL_HEADERS
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
# This auto-enables if Tcl was compiled threaded.
@@ -204,26 +242,15 @@ AC_CHECK_TYPE([intptr_t], [
TEA_MAKE_LIB
#--------------------------------------------------------------------
-# __CHANGE__
-# Change the name from exampeA_LIB_FILE to match your package name.
-# Use the stub_LIB_FILE substitution if your package creates a stub
-# library.
-#--------------------------------------------------------------------
-
-itcl_STUB_LIB_FILE=${PKG_STUB_LIB_FILE}
-itcl_LIB_FILE=${PKG_LIB_FILE}
-AC_SUBST(itcl_STUB_LIB_FILE)
-AC_SUBST(itcl_LIB_FILE)
-
-#--------------------------------------------------------------------
-# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
-# file during the install process. Don't run the TCLSH_PROG through
-# ${CYGPATH} because it's being used directly by make.
-# Require that we use a tclsh shell version 8.2 or later since earlier
-# versions have bugs in the pkg_mkIndex routine.
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
#--------------------------------------------------------------------
TEA_PROG_TCLSH
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# These are for itclConfig.sh
@@ -236,11 +263,13 @@ eval itcl_SRC_DIR="$srcdir"
itcl_SRC_DIR=`cd "${itcl_SRC_DIR}"; pwd`
AC_SUBST(itcl_SRC_DIR)
-eval itcl_INCLUDE_SPEC="${itcl_SRC_DIR}/generic"
+eval itcl_INCLUDE_SPEC="-I${itcl_SRC_DIR}/generic"
AC_SUBST(itcl_INCLUDE_SPEC)
#--------------------------------------------------------------------
# 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 the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_OUTPUT([Makefile pkgIndex.tcl itclConfig.sh])
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/Class.3 b/tcl8.6/pkgs/itcl4.1.2/doc/Class.3
index e44f8c1..e44f8c1 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/Class.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/Class.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/List.3 b/tcl8.6/pkgs/itcl4.1.2/doc/List.3
index 0939daa..0939daa 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/List.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/List.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/Object.3 b/tcl8.6/pkgs/itcl4.1.2/doc/Object.3
index 18b1e2b..18b1e2b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/Object.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/Object.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/Preserve.3 b/tcl8.6/pkgs/itcl4.1.2/doc/Preserve.3
index 4a6a7c4..4a6a7c4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/Preserve.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/Preserve.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/RegisterC.3 b/tcl8.6/pkgs/itcl4.1.2/doc/RegisterC.3
index 7a7e6c0..7a7e6c0 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/RegisterC.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/RegisterC.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/Stack.3 b/tcl8.6/pkgs/itcl4.1.2/doc/Stack.3
index 20da1a5..20da1a5 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/Stack.3
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/Stack.3
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/body.n b/tcl8.6/pkgs/itcl4.1.2/doc/body.n
index 3455a5a..3455a5a 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/body.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/body.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/class.n b/tcl8.6/pkgs/itcl4.1.2/doc/class.n
index 930270c..930270c 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/class.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/class.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/code.n b/tcl8.6/pkgs/itcl4.1.2/doc/code.n
index 9da2e0a..9da2e0a 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/code.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/code.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/configbody.n b/tcl8.6/pkgs/itcl4.1.2/doc/configbody.n
index 0cecb29..0cecb29 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/configbody.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/configbody.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/delete.n b/tcl8.6/pkgs/itcl4.1.2/doc/delete.n
index 6b949f1..6b949f1 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/delete.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/delete.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/ensemble.n b/tcl8.6/pkgs/itcl4.1.2/doc/ensemble.n
index 0b303b7..0b303b7 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/ensemble.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/ensemble.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/find.n b/tcl8.6/pkgs/itcl4.1.2/doc/find.n
index 2799c6e..2799c6e 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/find.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/find.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/is.n b/tcl8.6/pkgs/itcl4.1.2/doc/is.n
index 4eb84b3..4eb84b3 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/is.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/is.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itcl.n b/tcl8.6/pkgs/itcl4.1.2/doc/itcl.n
index 6c87fd6..6c87fd6 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itcl.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itcl.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itclcomponent.n b/tcl8.6/pkgs/itcl4.1.2/doc/itclcomponent.n
index be1c8ff..be1c8ff 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itclcomponent.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itclcomponent.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itcldelegate.n b/tcl8.6/pkgs/itcl4.1.2/doc/itcldelegate.n
index 6c3ca75..6c3ca75 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itcldelegate.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itcldelegate.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itclextendedclass.n b/tcl8.6/pkgs/itcl4.1.2/doc/itclextendedclass.n
index ec70c33..ec70c33 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itclextendedclass.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itclextendedclass.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itcloption.n b/tcl8.6/pkgs/itcl4.1.2/doc/itcloption.n
index fcaa2d5..fcaa2d5 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itcloption.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itcloption.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itclvars.n b/tcl8.6/pkgs/itcl4.1.2/doc/itclvars.n
index ea1968e..ea1968e 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itclvars.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itclvars.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/itclwidget.n b/tcl8.6/pkgs/itcl4.1.2/doc/itclwidget.n
index 562edbf..562edbf 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/itclwidget.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/itclwidget.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/license.terms b/tcl8.6/pkgs/itcl4.1.2/doc/license.terms
index 5ad5643..5ad5643 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/license.terms
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/license.terms
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/local.n b/tcl8.6/pkgs/itcl4.1.2/doc/local.n
index a65b2a4..a65b2a4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/local.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/local.n
diff --git a/tcl8.6/pkgs/itcl4.1.2/doc/man.macros b/tcl8.6/pkgs/itcl4.1.2/doc/man.macros
new file mode 100644
index 0000000..ddd073d
--- /dev/null
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/man.macros
@@ -0,0 +1,267 @@
+.\" 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 ""
+..
diff --git a/tcl8.6/pkgs/itcl4.1.1/doc/scope.n b/tcl8.6/pkgs/itcl4.1.2/doc/scope.n
index c2cbee4..c2cbee4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/doc/scope.n
+++ b/tcl8.6/pkgs/itcl4.1.2/doc/scope.n
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/clientData b/tcl8.6/pkgs/itcl4.1.2/generic/clientData
index 62e3f3c..62e3f3c 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/clientData
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/clientData
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itcl.decls b/tcl8.6/pkgs/itcl4.1.2/generic/itcl.decls
index 1530464..1530464 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itcl.decls
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itcl.decls
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itcl.h b/tcl8.6/pkgs/itcl4.1.2/generic/itcl.h
index 23a84a6..9c845c0 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itcl.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itcl.h
@@ -82,10 +82,10 @@ extern "C" {
#define ITCL_MAJOR_VERSION 4
#define ITCL_MINOR_VERSION 1
#define ITCL_RELEASE_LEVEL TCL_FINAL_RELEASE
-#define ITCL_RELEASE_SERIAL 1
+#define ITCL_RELEASE_SERIAL 2
#define ITCL_VERSION "4.1"
-#define ITCL_PATCH_LEVEL "4.1.1"
+#define ITCL_PATCH_LEVEL "4.1.2"
/*
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.c b/tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.c
index 30ea887..2fdfc8f 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.c
@@ -173,6 +173,21 @@ FreeProcedureMethod(
return result;
}
+static void
+EnsembleErrorProc(
+ Tcl_Interp *interp,
+ Tcl_Obj *procNameObj)
+{
+ int overflow, limit = 60, nameLen;
+ const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
+
+ overflow = (nameLen > limit);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (itcl ensemble part \"%.*s%s\" line %d)",
+ (overflow ? limit : nameLen), procName,
+ (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+}
+
int
Itcl_InvokeEnsembleMethod(
Tcl_Interp *interp,
@@ -188,6 +203,7 @@ Itcl_InvokeEnsembleMethod(
pmPtr->version = TCLOO_PROCEDURE_METHOD_VERSION;
pmPtr->procPtr = (Proc *)procPtr;
pmPtr->flags = USE_DECLARER_NS;
+ pmPtr->errProc = EnsembleErrorProc;
Tcl_NRAddCallback(interp, FreeProcedureMethod, pmPtr, NULL, NULL, NULL);
return Tcl_InvokeClassProcedureMethod(interp, namePtr, nsPtr,
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.h b/tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.h
index 4f9df0a..4f9df0a 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itcl2TclOO.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itcl2TclOO.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclBase.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclBase.c
index 450074a..5e38689 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclBase.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclBase.c
@@ -213,7 +213,7 @@ Initialize (
int opt;
int isNew;
Tcl_Object clazzObjectPtr, root;
- Tcl_Obj *objPtr;
+ Tcl_Obj *objPtr, *resPtr;
if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
return TCL_ERROR;
@@ -224,14 +224,18 @@ Initialize (
return TCL_ERROR;
}
- nsPtr = Tcl_CreateNamespace(interp, ITCL_NAMESPACE, NULL, NULL);
+ infoPtr = (ItclObjectInfo*)ckalloc(sizeof(ItclObjectInfo));
+
+ nsPtr = Tcl_CreateNamespace(interp, ITCL_NAMESPACE, infoPtr, FreeItclObjectInfo);
if (nsPtr == NULL) {
+ ckfree(infoPtr);
Tcl_Panic("Itcl: cannot create namespace: \"%s\" \n", ITCL_NAMESPACE);
}
nsPtr = Tcl_CreateNamespace(interp, ITCL_NAMESPACE"::internal::dicts",
NULL, NULL);
if (nsPtr == NULL) {
+ ckfree(infoPtr);
Tcl_Panic("Itcl: cannot create namespace: \"%s::internal::dicts\" \n",
ITCL_NAMESPACE);
}
@@ -258,7 +262,6 @@ Initialize (
* Store this as "associated data" for easy access, but link
* it to the itcl namespace for ownership.
*/
- infoPtr = (ItclObjectInfo*)ckalloc(sizeof(ItclObjectInfo));
memset(infoPtr, 0, sizeof(ItclObjectInfo));
infoPtr->interp = interp;
infoPtr->class_meta_type = (Tcl_ObjectMetadataType *)ckalloc(
@@ -330,8 +333,7 @@ Initialize (
infoPtr->useOldResolvers = opt;
Itcl_InitStack(&infoPtr->clsStack);
- Tcl_SetAssocData(interp, ITCL_INTERP_DATA,
- (Tcl_InterpDeleteProc*)FreeItclObjectInfo, (ClientData)infoPtr);
+ Tcl_SetAssocData(interp, ITCL_INTERP_DATA, NULL, (ClientData)infoPtr);
Itcl_PreserveData((ClientData)infoPtr);
@@ -359,8 +361,14 @@ Initialize (
if (Tcl_EvalEx(interp, clazzClassScript, -1, 0) != TCL_OK) {
Tcl_Panic("cannot create Itcl root class ::itcl::clazz");
}
- clazzObjectPtr = Tcl_GetObjectFromObj(interp, Tcl_GetObjResult(interp));
-
+ resPtr = Tcl_GetObjResult(interp);
+ /*
+ * Tcl_GetObjectFromObject can call Tcl_SetObjResult, so increment the
+ * refcount first.
+ */
+ Tcl_IncrRefCount(resPtr);
+ clazzObjectPtr = Tcl_GetObjectFromObj(interp, resPtr);
+ Tcl_DecrRefCount(resPtr);
if (clazzObjectPtr == NULL) {
Tcl_AppendResult(interp,
@@ -661,7 +669,7 @@ ItclFinishCmd(
Tcl_DecrRefCount(newObjv[0]);
ckfree((char *)newObjv);
- /* remove the unknow handler, to free the reference to the
+ /* remove the unknown handler, to free the reference to the
* Tcl_Obj with the name of it */
ensObjPtr = Tcl_NewStringObj("::itcl::builtin::Info::delegated", -1);
cmdPtr = Tcl_FindEnsemble(interp, ensObjPtr, TCL_LEAVE_ERR_MSG);
@@ -716,7 +724,8 @@ ItclFinishCmd(
Tcl_GetEnsembleMappingDict(NULL, cmdPtr, &mapDict);
if (mapDict != NULL) {
- objPtr = Tcl_NewStringObj("vars", -1);
+ objPtr = Tcl_NewStringObj("vars", -1);
+ Tcl_IncrRefCount(objPtr);
Tcl_DictObjRemove(interp, mapDict, objPtr);
Tcl_DictObjPut(interp, mapDict, objPtr, infoPtr->infoVars4Ptr);
Tcl_DecrRefCount(objPtr);
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclBuiltin.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclBuiltin.c
index e605762..59b29f5 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclBuiltin.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclBuiltin.c
@@ -41,9 +41,6 @@ static char initHullCmdsScript[] =
" if {[info exists library]} {\n"
" lappend dirs $library\n"
" } else {\n"
-" if {[catch {uplevel #0 source -rsrc itcl}] == 0} {\n"
-" return\n"
-" }\n"
" set dirs {}\n"
" if {[info exists env(ITCL_LIBRARY)]} {\n"
" lappend dirs $env(ITCL_LIBRARY)\n"
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclClass.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclClass.c
index af02d6e..7295751 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclClass.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclClass.c
@@ -2055,8 +2055,7 @@ Itcl_CreateVariable(
Tcl_DeleteHashEntry(hPtr);
return TCL_ERROR;
}
- Itcl_PreserveData((ClientData)mCodePtr);
- Itcl_EventuallyFree((ClientData)mCodePtr, Itcl_DeleteMemberCode);
+ ItclPreserveMemberCode(mCodePtr);
} else {
mCodePtr = NULL;
}
@@ -2119,10 +2118,8 @@ Itcl_CreateOption(
ItclOption* ioptPtr) /* new option definition */
{
int newEntry;
- ItclMemberCode *mCodePtr;
Tcl_HashEntry *hPtr;
- mCodePtr = NULL;
/*
* Add this option to the options table for the class.
* Make sure that the option name does not already exist.
@@ -2140,7 +2137,7 @@ Itcl_CreateOption(
iclsPtr->numOptions++;
ioptPtr->iclsPtr = iclsPtr;
- ioptPtr->codePtr = mCodePtr;
+ ioptPtr->codePtr = NULL;
ioptPtr->fullNamePtr = Tcl_NewStringObj(
Tcl_GetString(iclsPtr->fullNamePtr), -1);
Tcl_AppendToObj(ioptPtr->fullNamePtr, "::", 2);
@@ -2431,7 +2428,7 @@ if (ivPtr->arrayInitPtr != NULL) {
}
}
if (ivPtr->codePtr != NULL) {
- Itcl_ReleaseData(ivPtr->codePtr);
+ ItclReleaseMemberCode(ivPtr->codePtr);
}
Tcl_DecrRefCount(ivPtr->namePtr);
Tcl_DecrRefCount(ivPtr->fullNamePtr);
@@ -2468,7 +2465,9 @@ ItclDeleteOption(
Tcl_DecrRefCount(ioptPtr->classNamePtr);
}
- Itcl_ReleaseData(ioptPtr->codePtr);
+ if (ioptPtr->codePtr) {
+ ItclReleaseMemberCode(ioptPtr->codePtr);
+ }
if (ioptPtr->defaultValuePtr != NULL) {
Tcl_DecrRefCount(ioptPtr->defaultValuePtr);
}
@@ -2524,7 +2523,7 @@ if (imPtr->iclsPtr) {
}
}
if (imPtr->codePtr != NULL) {
- Itcl_ReleaseData(imPtr->codePtr);
+ ItclReleaseMemberCode(imPtr->codePtr);
}
Tcl_DecrRefCount(imPtr->namePtr);
Tcl_DecrRefCount(imPtr->fullNamePtr);
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclCmd.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclCmd.c
index 1111953..1111953 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclCmd.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclCmd.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclDecls.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclDecls.h
index 4af4200..4af4200 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclDecls.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclDecls.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclEnsemble.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclEnsemble.c
index 1d5ac19..1d5ac19 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclEnsemble.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclEnsemble.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclHelpers.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclHelpers.c
index a3f136b..a3f136b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclHelpers.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclHelpers.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclInfo.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclInfo.c
index bbd7513..069612f 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclInfo.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclInfo.c
@@ -1565,12 +1565,8 @@ Itcl_BiInfoVarsCmd(
}
if (TCL_OK != Itcl_GetContext(interp, &iclsPtr, &ioPtr)) {
- if (objc == 2) {
- /* Give pattern a chance to determine context */
- Tcl_ResetResult(interp);
- } else {
- return TCL_ERROR;
- }
+ /* Clear the error message */
+ Tcl_ResetResult(interp);
}
if (iclsPtr) {
if (iclsPtr->flags & (ITCL_TYPE|ITCL_WIDGETADAPTOR|ITCL_WIDGET)) {
@@ -2070,6 +2066,12 @@ Itcl_BiInfoOptionCmd(
* Return info for a specific option.
*/
if (optionName) {
+ if (contextIoPtr == NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot access object-specific info ",
+ "without an object context", (char*)NULL);
+ return TCL_ERROR;
+ }
optionNamePtr = Tcl_NewStringObj(optionName, -1);
hPtr = Tcl_FindHashEntry(&contextIoPtr->objectOptions,
(char *)optionNamePtr);
@@ -4738,6 +4740,12 @@ Itcl_BiInfoDelegatedOptionCmd(
* Return info for a specific option.
*/
if (optionName) {
+ if (contextIoPtr == NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot access object-specific info ",
+ "without an object context", (char*)NULL);
+ return TCL_ERROR;
+ }
optionNamePtr = Tcl_NewStringObj(optionName, -1);
hPtr = Tcl_FindHashEntry(&contextIoPtr->objectDelegatedOptions,
(char *)optionNamePtr);
@@ -5202,17 +5210,19 @@ Itcl_BiInfoDelegatedTypeMethodCmd(
}
if (hPtr == NULL) {
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "\"", cmdName, "\" isn't a delegated typemethod in object \"",
- Tcl_GetString(contextIoPtr->namePtr), "\"",
- (char*)NULL);
+ "\"", cmdName, "\" isn't a delegated typemethod in ",
+ contextIoPtr ? "object \"" : "class \"",
+ contextIoPtr ? Tcl_GetString(contextIoPtr->namePtr)
+ : Tcl_GetString(contextIclsPtr->namePtr), "\"", (char*)NULL);
return TCL_ERROR;
}
idmPtr = (ItclDelegatedFunction*)Tcl_GetHashValue(hPtr);
if (!(idmPtr->flags & ITCL_TYPE_METHOD)) {
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "\"", cmdName, "\" isn't a delegated typemethod in object \"",
- Tcl_GetString(contextIoPtr->namePtr), "\"",
- (char*)NULL);
+ "\"", cmdName, "\" isn't a delegated typemethod in ",
+ contextIoPtr ? "object \"" : "class \"",
+ contextIoPtr ? Tcl_GetString(contextIoPtr->namePtr)
+ : Tcl_GetString(contextIclsPtr->namePtr), "\"", (char*)NULL);
return TCL_ERROR;
}
/*
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclInt.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclInt.h
index 5134023..9541648 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclInt.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclInt.h
@@ -415,6 +415,7 @@ typedef struct ItclMemberCode {
Tcl_ObjCmdProc *objCmd; /* (objc,objv) C implementation */
} cfunc;
ClientData clientData; /* client data for C implementations */
+ int refCount;
} ItclMemberCode;
/*
@@ -688,6 +689,9 @@ MODULE_SCOPE void ItclReleaseIMF(ClientData imPtr);
MODULE_SCOPE void ItclPreserveClass(ItclClass *iclsPtr);
MODULE_SCOPE void ItclReleaseClass(ClientData iclsPtr);
+MODULE_SCOPE void ItclPreserveMemberCode(ItclMemberCode *mcodePtr);
+MODULE_SCOPE void ItclReleaseMemberCode(ItclMemberCode *mcodePtr);
+
MODULE_SCOPE void ItclPreserveObject(ItclObject *ioPtr);
MODULE_SCOPE void ItclReleaseObject(ClientData ioPtr);
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclIntDecls.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclIntDecls.h
index 5c68fb3..5c68fb3 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclIntDecls.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclIntDecls.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclLinkage.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclLinkage.c
index b0e87d8..b0e87d8 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclLinkage.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclLinkage.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclMethod.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclMethod.c
index e33e62b..00fc065 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclMethod.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclMethod.c
@@ -40,6 +40,7 @@ static int ItclCreateMemberCode(Tcl_Interp* interp, ItclClass *iclsPtr,
static int ItclCreateMemberFunc(Tcl_Interp* interp, ItclClass *iclsPtr,
Tcl_Obj *namePtr, const char* arglist, const char* body,
ItclMemberFunc** imPtrPtr, int flags);
+void ItclFreeMemberCode (ItclMemberCode *mcodePtr);
void
ItclPreserveIMF(
@@ -58,6 +59,22 @@ ItclReleaseIMF(
Itcl_DeleteMemberFunc(clientData);
}
}
+
+void
+ItclPreserveMemberCode(
+ ItclMemberCode *mcodePtr)
+{
+ mcodePtr->refCount++;
+}
+
+void
+ItclReleaseMemberCode(
+ ItclMemberCode *mcodePtr)
+{
+ if (--mcodePtr->refCount == 0) {
+ ItclFreeMemberCode(mcodePtr);
+ }
+}
/*
* ------------------------------------------------------------------------
@@ -293,11 +310,10 @@ NRConfigBodyCmd(
goto configBodyCmdDone;
}
- Itcl_PreserveData((ClientData)mcode);
- Itcl_EventuallyFree((ClientData)mcode, Itcl_DeleteMemberCode);
+ ItclPreserveMemberCode(mcode);
if (ivPtr->codePtr) {
- Itcl_ReleaseData((ClientData)ivPtr->codePtr);
+ ItclReleaseMemberCode(ivPtr->codePtr);
}
ivPtr->codePtr = mcode;
@@ -498,9 +514,6 @@ ItclCreateMemberFunc(
return TCL_ERROR;
}
- Itcl_PreserveData((ClientData)mcode);
- Itcl_EventuallyFree((ClientData)mcode, Itcl_DeleteMemberCode);
-
/*
* Allocate a member function definition and return.
*/
@@ -521,6 +534,7 @@ ItclCreateMemberFunc(
Tcl_IncrRefCount(imPtr->origArgsPtr);
}
imPtr->codePtr = mcode;
+ ItclPreserveMemberCode(mcode);
if (imPtr->protection == ITCL_DEFAULT_PROTECT) {
imPtr->protection = ITCL_PUBLIC;
@@ -779,10 +793,8 @@ Itcl_ChangeMemberFunc(
/*
* Free up the old implementation and install the new one.
*/
- Itcl_PreserveData((ClientData)mcode);
- Itcl_EventuallyFree((ClientData)mcode, Itcl_DeleteMemberCode);
-
- Itcl_ReleaseData((ClientData)imPtr->codePtr);
+ ItclPreserveMemberCode(mcode);
+ ItclReleaseMemberCode(imPtr->codePtr);
imPtr->codePtr = mcode;
if (mcode->flags & ITCL_IMPLEMENT_TCL) {
ClientData pmPtr;
@@ -1054,6 +1066,7 @@ ItclCreateMemberCode(
}
*mcodePtr = mcode;
+
return TCL_OK;
}
@@ -1066,15 +1079,13 @@ ItclCreateMemberCode(
* of the function. If the body is of the form "@name", then it is
* treated as a label for a C procedure registered by Itcl_RegisterC().
*
- * The implementation is kept by the member function definition, and
- * controlled by a preserve/release paradigm. That way, if it is in
- * use while it is being redefined, it will stay around long enough
- * to avoid a core dump.
+ * A member function definition holds a handle for the implementation, and
+ * calls ItclReleaseMemberCode when finished with it.
*
* If any errors are encountered, this procedure returns TCL_ERROR
* along with an error message in the interpreter. Otherwise, it
- * returns TCL_OK, and "mcodePtr" returns a pointer to the new
- * implementation.
+ * returns TCL_OK, and stores a pointer to the new implementation in
+ * "mcodePtr".
* ------------------------------------------------------------------------
*/
int
@@ -1094,17 +1105,13 @@ Itcl_CreateMemberCode(
* Itcl_DeleteMemberCode()
*
* Destroys all data associated with the given command implementation.
- * Invoked automatically by Itcl_ReleaseData() when the implementation
+ * Invoked automatically by ItclReleaseData() when the implementation
* is no longer being used.
* ------------------------------------------------------------------------
*/
-void
-Itcl_DeleteMemberCode(
- char* cdata) /* pointer to member code definition */
+void ItclFreeMemberCode (
+ ItclMemberCode* mCodePtr)
{
- ItclMemberCode* mCodePtr;
-
- mCodePtr = (ItclMemberCode*)cdata;
if (mCodePtr == NULL) {
return;
}
@@ -1124,6 +1131,14 @@ Itcl_DeleteMemberCode(
ckfree((char*)mCodePtr);
}
+
+void
+Itcl_DeleteMemberCode(
+ char* cdata) /* pointer to member code definition */
+{
+ ItclReleaseMemberCode((ItclMemberCode *)cdata);
+}
+
/*
* ------------------------------------------------------------------------
@@ -1276,7 +1291,7 @@ Itcl_EvalMemberCode(
* Bump the reference count on this code, in case it is
* redefined or deleted during execution.
*/
- Itcl_PreserveData((ClientData)mcode);
+ ItclPreserveMemberCode(mcode);
if ((imPtr->flags & ITCL_DESTRUCTOR) && (contextIoPtr != NULL)) {
contextIoPtr->destructorHasBeenCalled = 1;
@@ -1314,7 +1329,7 @@ Itcl_EvalMemberCode(
}
}
- Itcl_ReleaseData((ClientData)mcode);
+ ItclReleaseMemberCode(mcode);
return result;
}
@@ -1511,6 +1526,15 @@ Itcl_GetContext(
hPtr = Tcl_FindHashEntry(&infoPtr->namespaceClasses, (char *)nsPtr);
if (hPtr) {
*iclsPtrPtr = (ItclClass *)Tcl_GetHashValue(hPtr);
+
+ /*
+ * DANGER! Following stanza of code was added to address a
+ * regression from Itcl 4.0 -> Itcl 4.1 reported in Ticket
+ * [c949e73d3e] without really understanding. May be trouble here!
+ */
+ if ((*iclsPtrPtr)->nsPtr) {
+ *ioPtrPtr = (*iclsPtrPtr)->infoPtr->currIoPtr;
+ }
return TCL_OK;
}
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.c
index 9f035c8..9f035c8 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.h
index 012ea0b..012ea0b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclMigrate2TclCore.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclMigrate2TclCore.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclObject.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclObject.c
index 2e60c97..2e60c97 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclObject.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclObject.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclParse.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclParse.c
index 9b34dc6..8a8ad37 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclParse.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclParse.c
@@ -56,9 +56,6 @@ static const char initWidgetScript[] =
" if {[info exists library]} {\n"
" lappend dirs $library\n"
" } else {\n"
-" if {[catch {uplevel #0 source -rsrc itcl}] == 0} {\n"
-" return\n"
-" }\n"
" set dirs {}\n"
" if {[info exists env(ITCL_LIBRARY)]} {\n"
" lappend dirs $env(ITCL_LIBRARY)\n"
@@ -90,12 +87,14 @@ static const char initWidgetScript[] =
" foreach i $dirs {\n"
" set library $i\n"
" set itclfile [file join $i itclWidget.tcl]\n"
-" if {![catch {uplevel #0 [list source $itclfile]} msg]} {\n"
+" if {![catch {uplevel #0 [list source $itclfile]} emsg]} {\n"
" return\n"
" }\n"
" }\n"
" set msg \"Can't find a usable itclWidget.tcl in the following directories:\n\"\n"
" append msg \" $dirs\n\"\n"
+" append msg \"Last error:\n\"\n"
+" append msg \" $emsg\n\"\n"
" append msg \"This probably means that Itcl/Tcl weren't installed properly.\n\"\n"
" append msg \"If you know where the Itcl library directory was installed,\n\"\n"
" append msg \"you can set the environment variable ITCL_LIBRARY to point\n\"\n"
@@ -1525,6 +1524,8 @@ Itcl_ClassInheritCmd(
}
Tcl_DStringFree(&buffer);
+ Itcl_BuildVirtualTables(iclsPtr);
+
return result;
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclResolve.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclResolve.c
index c22ced2..c22ced2 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclResolve.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclResolve.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclResolve2.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclResolve2.c
index b75a5a3..b75a5a3 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclResolve2.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclResolve2.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubInit.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubInit.c
index 63d6437..63d6437 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubInit.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubInit.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubLib.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubLib.c
index 50683b7..50683b7 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubLib.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubLib.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubs.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubs.c
index bc7189c..bc7189c 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclStubs.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclStubs.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.c
index 7d3cdf4..7d3cdf4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.h
index b22ee06..b22ee06 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclTclIntStubsFcn.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclTclIntStubsFcn.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclTestRegisterC.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclTestRegisterC.c
index 7489b89..7489b89 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclTestRegisterC.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclTestRegisterC.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclUtil.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclUtil.c
index 057f01b..057f01b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclUtil.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclUtil.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclVCInt.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclVCInt.h
index 93ba54f..93ba54f 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclVCInt.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclVCInt.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.c b/tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.c
index 0511d14..0511d14 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.c
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.h b/tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.h
index 966806b..966806b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/generic/itclVarsAndCmds.h
+++ b/tcl8.6/pkgs/itcl4.1.2/generic/itclVarsAndCmds.h
diff --git a/tcl8.6/pkgs/itcl4.1.1/itclConfig.sh.in b/tcl8.6/pkgs/itcl4.1.2/itclConfig.sh.in
index 74504e1..c7bd6e3 100644
--- a/tcl8.6/pkgs/itcl4.1.1/itclConfig.sh.in
+++ b/tcl8.6/pkgs/itcl4.1.2/itclConfig.sh.in
@@ -16,8 +16,8 @@ itcl_VERSION='@PACKAGE_VERSION@'
ITCL_VERSION='@PACKAGE_VERSION@'
# The name of the Itcl library (may be either a .a file or a shared library):
-itcl_LIB_FILE=@itcl_LIB_FILE@
-ITCL_LIB_FILE=@itcl_LIB_FILE@
+itcl_LIB_FILE=@PKG_LIB_FILE@
+ITCL_LIB_FILE=@PKG_LIB_FILE@
# String to pass to linker to pick up the Itcl library from its
# build directory.
@@ -30,8 +30,8 @@ itcl_LIB_SPEC='@itcl_LIB_SPEC@'
ITCL_LIB_SPEC='@itcl_LIB_SPEC@'
# The name of the Itcl stub library (a .a file):
-itcl_STUB_LIB_FILE=@itcl_STUB_LIB_FILE@
-ITCL_STUB_LIB_FILE=@itcl_STUB_LIB_FILE@
+itcl_STUB_LIB_FILE=@PKG_STUB_LIB_FILE@
+ITCL_STUB_LIB_FILE=@PKG_STUB_LIB_FILE@
# String to pass to linker to pick up the Itcl stub library from its
# build directory.
diff --git a/tcl8.6/pkgs/itcl4.1.1/library/itcl.tcl b/tcl8.6/pkgs/itcl4.1.2/library/itcl.tcl
index 15ca220..15ca220 100644
--- a/tcl8.6/pkgs/itcl4.1.1/library/itcl.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/library/itcl.tcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/library/itclHullCmds.tcl b/tcl8.6/pkgs/itcl4.1.2/library/itclHullCmds.tcl
index 2f4a12c..2f4a12c 100644
--- a/tcl8.6/pkgs/itcl4.1.1/library/itclHullCmds.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/library/itclHullCmds.tcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/library/itclWidget.tcl b/tcl8.6/pkgs/itcl4.1.2/library/itclWidget.tcl
index 6ca2497..6ca2497 100644
--- a/tcl8.6/pkgs/itcl4.1.1/library/itclWidget.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/library/itclWidget.tcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/library/test_Itcl_CreateObject.tcl b/tcl8.6/pkgs/itcl4.1.2/library/test_Itcl_CreateObject.tcl
index a9a7fcb..a9a7fcb 100644
--- a/tcl8.6/pkgs/itcl4.1.1/library/test_Itcl_CreateObject.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/library/test_Itcl_CreateObject.tcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/license.terms b/tcl8.6/pkgs/itcl4.1.2/license.terms
index 9e11593..9e11593 100644
--- a/tcl8.6/pkgs/itcl4.1.1/license.terms
+++ b/tcl8.6/pkgs/itcl4.1.2/license.terms
diff --git a/tcl8.6/pkgs/itcl4.1.1/pkgIndex.tcl.in b/tcl8.6/pkgs/itcl4.1.2/pkgIndex.tcl.in
index 31fe6b1..31fe6b1 100644
--- a/tcl8.6/pkgs/itcl4.1.1/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/itcl4.1.2/pkgIndex.tcl.in
diff --git a/tcl8.6/pkgs/itcl4.1.1/releasenotes.txt b/tcl8.6/pkgs/itcl4.1.2/releasenotes.txt
index 89ee45e..abed445 100644
--- a/tcl8.6/pkgs/itcl4.1.1/releasenotes.txt
+++ b/tcl8.6/pkgs/itcl4.1.2/releasenotes.txt
@@ -1,4 +1,4 @@
-This is the release 4.1.1 of Itcl.
+This is the release 4.1.2 of Itcl.
It is intended to be script compatible with Itcl 4.0.* and Itcl 3.4.* .
It very likely presents the same public C interface as Itcl 4.0.* .
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/README.txt b/tcl8.6/pkgs/itcl4.1.2/tclconfig/README.txt
index 59b5a3e..59b5a3e 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/README.txt
+++ b/tcl8.6/pkgs/itcl4.1.2/tclconfig/README.txt
diff --git a/tcl8.6/pkgs/thread2.8.2/tclconfig/install-sh b/tcl8.6/pkgs/itcl4.1.2/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/thread2.8.2/tclconfig/install-sh
+++ b/tcl8.6/pkgs/itcl4.1.2/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/tcl.m4 b/tcl8.6/pkgs/itcl4.1.2/tclconfig/tcl.m4
index e8234a2..2ec82a2 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/tcl.m4
+++ b/tcl8.6/pkgs/itcl4.1.2/tclconfig/tcl.m4
@@ -11,10 +11,6 @@
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.10"
-
# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
@@ -109,6 +105,9 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -135,13 +134,17 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -265,6 +268,9 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tk.framework/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
@@ -280,8 +286,15 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
; do
if test -f "$i/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i; pwd)`"
@@ -1693,7 +1706,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LDFLAGS="$LDFLAGS -pthread"
])
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -2053,9 +2066,9 @@ dnl # preprocessing tests use only CPPFLAGS.
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -2305,96 +2318,6 @@ int main() {
])
#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
# TEA_PATH_X
#
# Locate the X11 header files and the X11 library archive. Try
@@ -2649,92 +2572,6 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
])
#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
# TEA_TCL_EARLY_FLAGS
#
# Check for what flags are needed to be passed so the correct OS
@@ -2895,23 +2732,14 @@ 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.10"
+ TEA_VERSION="3.13"
- AC_MSG_CHECKING([for correct TEA configuration])
+ AC_MSG_CHECKING([TEA configuration])
if test x"${PACKAGE_NAME}" = x ; then
AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.ac])
fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
# 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".
@@ -2920,7 +2748,7 @@ TEA version not specified.])
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
EXEEXT=".exe"
TEA_PLATFORM="windows"
@@ -2973,6 +2801,9 @@ TEA version not specified.])
AC_SUBST(PKG_INCLUDES)
AC_SUBST(PKG_LIBS)
AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
])
#------------------------------------------------------------------------
@@ -3264,20 +3095,6 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
AC_PROG_CC
AC_PROG_CPP
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -3336,14 +3153,6 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
#--------------------------------------------------------------------
AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
])
#------------------------------------------------------------------------
@@ -3989,6 +3798,7 @@ AC_DEFUN([TEA_PATH_CONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4223,6 +4033,45 @@ AC_DEFUN([TEA_PATH_CELIB], [
fi
])
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
###
# Tip 430 - ZipFS Modifications
###
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/all.tcl b/tcl8.6/pkgs/itcl4.1.2/tests/all.tcl
index 3b2e65d..74ae333 100755..100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/all.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/all.tcl
@@ -7,9 +7,12 @@
# Copyright (c) 1998-2000 by Ajuba Solutions
# All rights reserved.
-package require tcltest 2.1
+package prefer latest
-tcltest::testsDirectory [file dir [info script]]
+package require Tcl 8.6
+package require tcltest 2.2
+
+tcltest::configure {*}$argv -testdir [file dir [info script]]
tcltest::runAllTests
return
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/basic.test b/tcl8.6/pkgs/itcl4.1.2/tests/basic.test
index 7681762..51056df 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/basic.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/basic.test
@@ -24,8 +24,8 @@ test basic-1.0 {empty string as class name should fail but not crash
# ----------------------------------------------------------------------
# Simple class definition
# ----------------------------------------------------------------------
-test basic-1.1 {define a simple class
-} -body {
+
+variable setup {
itcl::class Counter {
constructor {args} {
incr num
@@ -45,104 +45,133 @@ test basic-1.1 {define a simple class
protected variable val 0
private common num 0
}
-} -result {}
+}
+
+variable cleanup {
+ itcl::delete class Counter
+}
+
+variable setup2 $setup
+append setup2 {
+ set x [Counter x]
+}
+
+variable cleanup2 $cleanup
+append cleanup2 {
+ unset x
+}
+
+variable setup3 $setup
+append setup3 {
+ Counter -foo
+}
+
+variable setup4 $setup
+append setup4 {
+ Counter c
+}
+
+
+test basic-1.1 {define a simple class
+} -setup $setup -body {
+} -cleanup $cleanup -result {}
test basic-1.2 {class is now defined
-} -body {
+} -setup $setup -body {
itcl::find classes Counter
-} -result {Counter}
+} -cleanup $cleanup -result Counter
test basic-1.3 {access command exists with class name
-} -body {
+} -setup $setup -body {
namespace which -command Counter
-} -result {::Counter}
+} -cleanup $cleanup -result ::Counter
test basic-1.4 {create a simple object
-} -body {
- Counter x
-} -result {x}
+} -setup $setup2 -body {
+ return $x
+} -cleanup $cleanup2 -result x
test basic-1.5a {object names cannot be duplicated
-} -body {
+} -setup $setup2 -body {
list [catch "Counter x" msg] $msg
-} -result {1 {command "x" already exists in namespace "::"}}
+} -cleanup $cleanup2 -result {1 {command "x" already exists in namespace "::"}}
test basic-1.5b {built-in commands cannot be clobbered
-} -body {
+} -setup $setup -body {
list [catch "Counter info" msg] $msg
-} -result {1 {command "info" already exists in namespace "::"}}
+} -cleanup $cleanup -result {1 {command "info" already exists in namespace "::"}}
test basic-1.6 {objects have an access command
-} -body {
+} -setup $setup2 -body {
namespace which -command x
-} -result {::x}
+} -cleanup $cleanup2 -result ::x
test basic-1.7a {objects are added to the master list
-} -body {
+} -setup $setup2 -body {
itcl::find objects x
-} -result {x}
+} -cleanup $cleanup2 -result x
test basic-1.7b {objects are added to the master list
-} -body {
+} -setup $setup2 -body {
itcl::find objects -class Counter x
-} -result {x}
+} -cleanup $cleanup2 -result x
test basic-1.8 {objects can be deleted
-} -body {
+} -setup $setup2 -body {
list [itcl::delete object x] [namespace which -command x]
-} -result {{} {}}
+} -cleanup $cleanup2 -result {{} {}}
test basic-1.9 {objects can be recreated with the same name
-} -body {
+} -setup $setup2 -body {
+ itcl::delete object x
Counter x
-} -result {x}
+} -cleanup $cleanup2 -result x
test basic-1.10 {objects can be destroyed by deleting their access command
-} -body {
- rename ::x ""
+} -setup $setup2 -body {
+ rename ::x {}
itcl::find objects x
-} -result {}
+} -cleanup $cleanup2 -result {}
test basic-1.11 {find command supports object names starting with -
-} -body {
- Counter -foo
+} -setup $setup3 -body {
itcl::find objects -class Counter -foo
-} -result {-foo}
+} -cleanup $cleanup -result -foo
test basic-1.12 {is command with class argument
-} -body {
+} -setup $setup -body {
itcl::is class Counter
-} -result {1}
+} -cleanup $cleanup -result 1
test basic-1.13 {is command with class argument (global namespace)
-} -body {
+} -setup $setup -body {
itcl::is class ::Counter
-} -result {1}
+} -cleanup $cleanup -result 1
test basic-1.14 {is command with class argument (wrapped in code command)
-} -body {
+} -setup $setup -body {
itcl::is class [itcl::code Counter]
-} -result {1}
+} -cleanup $cleanup -result 1
test basic-1.15 {is command with class argument (class does not exist)
} -body {
itcl::is class Count
-} -result {0}
+} -result 0
test basic-1.16 {is command with object argument
-} -body {
+} -setup $setup3 -body {
itcl::is object -foo
-} -result {1}
+} -cleanup $cleanup -result 1
test basic-1.17 {is command with object argument (object does not exist)
} -body {
itcl::is object xxx
-} -result {0}
+} -result 0
test basic-1.18 {is command with object argument (with code command)
-} -body {
+} -setup $setup3 -body {
itcl::is object [itcl::code -- -foo]
-} -result {1}
+} -cleanup $cleanup -result 1
test basic-1.19 {classes can be unicode
} -body {
@@ -150,7 +179,8 @@ test basic-1.19 {classes can be unicode
\u6210bcd #auto
} -result "\u6210bcd0"
-test basic-1.20 {classes can be unicode
+test basic-1.20 {
+ classes can be unicode
} -body {
\u6210bcd0 foo
} -cleanup {
@@ -163,25 +193,25 @@ test basic-1.20 {classes can be unicode
# #auto names
# ----------------------------------------------------------------------
test basic-2.1 {create an object with an automatic name
-} -body {
+} -setup $setup -body {
Counter #auto
-} -result {counter0}
+} -cleanup $cleanup -result {counter0}
test basic-2.2 {bury "#auto" within object name
-} -body {
+} -setup $setup -body {
Counter x#autoy
-} -result {xcounter1y}
+} -cleanup $cleanup -result {xcounter0y}
test basic-2.3 {bury "#auto" within object name
-} -body {
+} -setup $setup -body {
Counter a#aut#autob
-} -result {a#autcounter2b}
+} -cleanup $cleanup -result {a#autcounter0b}
test basic-2.4 {"#auto" is smart enough to skip names that are taken
-} -body {
+} -setup $setup -body {
Counter counter3
Counter #auto
-} -result {counter4}
+} -cleanup $cleanup -result {counter0}
test basic-2.5 {"#auto" with :: at front of name
} -body {
@@ -219,49 +249,48 @@ test basic-2.7 {"#auto" with :: at front of name inside method inside namespace
} -result {::autoCheck0}
test basic-3.1 {object access command works
-} -body {
- Counter c
+} -setup $setup4 -body {
list [c ++] [c ++] [c ++]
-} -result {1 2 3}
+} -cleanup $cleanup -result {1 2 3}
test basic-3.2 {errors produce usage info
-} -body {
+} -setup $setup4 -body {
list [catch "c xyzzy" msg] $msg
-} -result {1 {bad option "xyzzy": should be one of...
+} -cleanup $cleanup -result {1 {bad option "xyzzy": should be one of...
c ++
c cget -option
c configure ?-option? ?value -option value...?
c isa className}}
test basic-3.3 {built-in configure can query public variables
-} -body {
+} -setup $setup4 -body {
c configure
-} -result {{-by 1 1}}
+} -cleanup $cleanup -result {{-by 1 1}}
test basic-3.4 {built-in configure can query one public variable
-} -body {
+} -setup $setup4 -body {
c configure -by
-} -result {-by 1 1}
+} -cleanup $cleanup -result {-by 1 1}
test basic-3.5 {built-in configure can set public variable
-} -body {
+} -setup $setup4 -body {
list [c configure -by 2] [c cget -by]
-} -result {{} 2}
+} -cleanup $cleanup -result {{} 2}
test basic-3.6 {configure actually changes public variable
-} -body {
+} -setup $setup4 -body {
list [c ++] [c ++]
-} -result {5 7}
+} -cleanup $cleanup -result {1 2}
test basic-3.7 {class procs can be accessed
-} -body {
+} -setup $setup -body {
Counter::num
-} -result {7}
+} -cleanup $cleanup -result 0
test basic-3.8 {obsolete syntax is no longer allowed
-} -body {
+} -setup $setup -body {
list [catch "Counter :: num" msg] $msg
-} -result {1 {syntax "class :: proc" is an anachronism
+} -cleanup $cleanup -result {1 {syntax "class :: proc" is an anachronism
[incr Tcl] no longer supports this syntax.
Instead, remove the spaces from your procedure invocations:
Counter::num ?args?}}
@@ -271,7 +300,7 @@ Instead, remove the spaces from your procedure invocations:
# Classes can be destroyed and redefined
# ----------------------------------------------------------------------
test basic-4.1 {classes can be destroyed
-} -body {
+} -setup $setup -body {
list [itcl::delete class Counter] \
[itcl::find classes Counter] \
[namespace children :: Counter] \
@@ -389,7 +418,10 @@ test basic-5.9 {variable names can have ":" in them
namespace eval :: {info globals test:global:2}
} -result {test:global:2}
-::itcl::delete class test_globals
+if {[namespace which [namespace current]::test_globals] ne {}} {
+ ::itcl::delete class test_globals
+}
+
# ----------------------------------------------------------------------
@@ -475,7 +507,10 @@ test basic-6.8 {common variables can be redefined
test_arrays0 do set undefined "scalar"
} -result {scalar}
-::itcl::delete class test_arrays
+if {[namespace which [namespace current]::test:arrays] ne {}} {
+ ::itcl::delete class test_arrays
+}
+
::tcltest::cleanupTests
return
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/body.test b/tcl8.6/pkgs/itcl4.1.2/tests/body.test
index cf31f50..cf31f50 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/body.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/body.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/chain.test b/tcl8.6/pkgs/itcl4.1.2/tests/chain.test
index e80a1d6..e80a1d6 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/chain.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/chain.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/delete.test b/tcl8.6/pkgs/itcl4.1.2/tests/delete.test
index 4211ef2..a217576 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/delete.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/delete.test
@@ -174,7 +174,9 @@ test delete-4.4 {an object being destructed can't be deleted} {
list [catch {itcl::delete object $obj} msg] $msg
} {1 {can't delete an object while it is being destructed}}
-namespace delete test_delete
+if {[namespace which [namespace current]::test_delete] ne {}} {
+ namespace delete test_delete
+}
# ----------------------------------------------------------------------
# Delete objects using path names and scoped values
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/eclasscomponent.test b/tcl8.6/pkgs/itcl4.1.2/tests/eclasscomponent.test
index 56df617..56df617 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/eclasscomponent.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/eclasscomponent.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/ensemble.test b/tcl8.6/pkgs/itcl4.1.2/tests/ensemble.test
index 4d79a9b..09b1977 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/ensemble.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/ensemble.test
@@ -208,6 +208,16 @@ test ensemble-3.1a {the error handler part shows up as generic "...and"
test_numbers two x y
...and others described on the man page}}
+test ensemble-4.0 {SF Bug 119} -setup {
+ itcl::ensemble foo part sub {} {error bar}
+} -cleanup {
+ unset -nocomplain m o
+ rename foo {}
+} -body {
+ catch {foo sub} m o
+ dict get $o -errorinfo
+} -match glob -result {*itcl ensemble part*}
+
::itcl::delete ensemble test_numbers
::tcltest::cleanupTests
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/general1.test b/tcl8.6/pkgs/itcl4.1.2/tests/general1.test
index 3aa7a03..3aa7a03 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/general1.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/general1.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/import.test b/tcl8.6/pkgs/itcl4.1.2/tests/import.test
index d35a789..d35a789 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/import.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/import.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/info.test b/tcl8.6/pkgs/itcl4.1.2/tests/info.test
index c132e93..c132e93 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/info.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/info.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/inherit.test b/tcl8.6/pkgs/itcl4.1.2/tests/inherit.test
index 502bf09..502bf09 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/inherit.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/inherit.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/interp.test b/tcl8.6/pkgs/itcl4.1.2/tests/interp.test
index a1dce2b..a1dce2b 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/interp.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/interp.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/local.test b/tcl8.6/pkgs/itcl4.1.2/tests/local.test
index 15c99ab..15c99ab 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/local.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/local.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/methods.test b/tcl8.6/pkgs/itcl4.1.2/tests/methods.test
index bd83a67..bd83a67 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/methods.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/methods.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/mkindex.itcl b/tcl8.6/pkgs/itcl4.1.2/tests/mkindex.itcl
index 5480c67..5480c67 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/mkindex.itcl
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/mkindex.itcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/mkindex.test b/tcl8.6/pkgs/itcl4.1.2/tests/mkindex.test
index 339336f..339336f 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/mkindex.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/mkindex.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/namespace.test b/tcl8.6/pkgs/itcl4.1.2/tests/namespace.test
index e2ff9c7..e2ff9c7 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/namespace.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/namespace.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/protection.test b/tcl8.6/pkgs/itcl4.1.2/tests/protection.test
index ba99e49..ba99e49 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/protection.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/protection.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/scope.test b/tcl8.6/pkgs/itcl4.1.2/tests/scope.test
index 0613bf4..0613bf4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/scope.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/scope.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/sfbugs.test b/tcl8.6/pkgs/itcl4.1.2/tests/sfbugs.test
index 799c245..4c2b8c2 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/sfbugs.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/sfbugs.test
@@ -581,6 +581,17 @@ test fossil-9.3 {c45384364c} -setup {
itcl::delete class A B
} -result {::b ::b}
+test sfbugs-281 {Resolve inherited common} -setup {
+ itcl::class Parent {protected common x 0}
+} -cleanup {
+ itcl::delete class Parent
+} -body {
+ itcl::class Child {
+ inherit Parent
+ set Parent::x
+ }
+} -result {}
+
#test sfbug-xxx { SF bug xxx
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/tclIndex b/tcl8.6/pkgs/itcl4.1.2/tests/tclIndex
index 4f6bdae..4f6bdae 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/tclIndex
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/tclIndex
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typeclass.test b/tcl8.6/pkgs/itcl4.1.2/tests/typeclass.test
index f1ae2e3..f1ae2e3 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typeclass.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typeclass.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typedelegation.test b/tcl8.6/pkgs/itcl4.1.2/tests/typedelegation.test
index 4b18bb5..4b18bb5 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typedelegation.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typedelegation.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typefunction.test b/tcl8.6/pkgs/itcl4.1.2/tests/typefunction.test
index f54c988..f54c988 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typefunction.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typefunction.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typeinfo.test b/tcl8.6/pkgs/itcl4.1.2/tests/typeinfo.test
index 8d6ddc9..8d6ddc9 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typeinfo.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typeinfo.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typeoption.test b/tcl8.6/pkgs/itcl4.1.2/tests/typeoption.test
index 4114294..4114294 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typeoption.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typeoption.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/typevariable.test b/tcl8.6/pkgs/itcl4.1.2/tests/typevariable.test
index 15a538d..15a538d 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/typevariable.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/typevariable.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/widgetadaptor.test b/tcl8.6/pkgs/itcl4.1.2/tests/widgetadaptor.test
index 31ea020..31ea020 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/widgetadaptor.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/widgetadaptor.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tests/widgetclass.test b/tcl8.6/pkgs/itcl4.1.2/tests/widgetclass.test
index a3cef0c..a3cef0c 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tests/widgetclass.test
+++ b/tcl8.6/pkgs/itcl4.1.2/tests/widgetclass.test
diff --git a/tcl8.6/pkgs/itcl4.1.1/tools/genStubs.tcl b/tcl8.6/pkgs/itcl4.1.2/tools/genStubs.tcl
index 7a75dc6..7a75dc6 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tools/genStubs.tcl
+++ b/tcl8.6/pkgs/itcl4.1.2/tools/genStubs.tcl
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/dllEntryPoint.c b/tcl8.6/pkgs/itcl4.1.2/win/dllEntryPoint.c
index c9842b5..c9842b5 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/dllEntryPoint.c
+++ b/tcl8.6/pkgs/itcl4.1.2/win/dllEntryPoint.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/itcl.rc b/tcl8.6/pkgs/itcl4.1.2/win/itcl.rc
index eb2fbdd..eb2fbdd 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/itcl.rc
+++ b/tcl8.6/pkgs/itcl4.1.2/win/itcl.rc
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/makefile.vc b/tcl8.6/pkgs/itcl4.1.2/win/makefile.vc
index 624a3ec..c4ed3e4 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/makefile.vc
+++ b/tcl8.6/pkgs/itcl4.1.2/win/makefile.vc
@@ -1,101 +1,101 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for ITcl
-#
-# Basic build, test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = itcl
-NEED_TCL_SOURCE = 1
-RCFILE = itcl.rc
-# Tcl 8.6 etc. compile with /DUNICODE. ITcl pre-nmake reform compiled
-# without -DUNICODE. Keep that behaviour for now.
-USE_WIDECHAR_API = 0
-
-!include "rules-ext.vc"
-
-PRJ_OBJS = \
- $(TMP_DIR)\itcl2TclOO.obj \
- $(TMP_DIR)\itclBase.obj \
- $(TMP_DIR)\itclBuiltin.obj \
- $(TMP_DIR)\itclClass.obj \
- $(TMP_DIR)\itclCmd.obj \
- $(TMP_DIR)\itclEnsemble.obj \
- $(TMP_DIR)\itclHelpers.obj \
- $(TMP_DIR)\itclInfo.obj \
- $(TMP_DIR)\itclLinkage.obj \
- $(TMP_DIR)\itclMethod.obj \
- $(TMP_DIR)\itclMigrate2TclCore.obj \
- $(TMP_DIR)\itclObject.obj \
- $(TMP_DIR)\itclParse.obj \
- $(TMP_DIR)\itclResolve.obj \
- $(TMP_DIR)\itclStubs.obj \
- $(TMP_DIR)\itclStubInit.obj \
- $(TMP_DIR)\itclTclIntStubsFcn.obj \
- $(TMP_DIR)\itclUtil.obj \
-!if !$(STATIC_BUILD)
- $(TMP_DIR)\dllEntryPoint.obj \
-!endif
-
-PRJ_STUBOBJS = $(TMP_DIR)\itclStubLib.obj
-
-PRJ_DEFINES = -D_CRT_SECURE_NO_WARNINGS
-!if $(DEBUG)
-PRJ_DEFINES = $(PRJ_DEFINES) -DITCL_DEBUG
-!endif
-
-PRJ_HEADERS_PUBLIC = \
- $(GENERICDIR)\itcl.h \
- $(GENERICDIR)\itclDecls.h
-
-
-# Define the standard targets except we have a custom test target
-DISABLE_TARGET_test = 1
-!include "$(_RULESDIR)\targets.vc"
-
-pkgindex: $(OUT_DIR)\pkgIndex.tcl
-$(OUT_DIR)\pkgIndex.tcl:
- @$(COPY) << "$(OUT_DIR)\pkgIndex.tcl"
-if {[package vsatisfies 8.0 [package provide Tcl]]} {
- set add 80
-} else {
- set add {t}
-}
-if {[info exists ::tcl_platform(debug)] && $$::tcl_platform(debug) && \
- [file exists [file join $$dir itcl$(VERSION)$${add}g.dll]]} {
- package ifneeded Itcl $(DOTVERSION) [list load [file join $$dir itcl$(VERSION)$${add}g.dll] Itcl]
-} else {
- package ifneeded Itcl $(DOTVERSION) [list load [file join $$dir itcl$(VERSION)$${add}.dll] Itcl]
-}
-unset add
-<<
-
-!if $(STATIC_BUILD)
-test :
- @echo test target not supported for a static library.
-!else
-test : setup $(PROJECT)
- $(TCLSH) ..\tests\all.tcl $(TESTFLAGS) -loadfile <<
- set env(ITCL_LIBRARY) [file normalize [file join $(MAKEDIR:\=/) .. library]]
- package ifneeded $(PROJECT) $(DOTVERSION) [list load [file normalize [file join $(MAKEDIR:\=/) $(PRJLIB:\=/)]]]
-<<
-!endif
-
-genstubs:
-!if $(TCLINSTALL)
- @echo Need the source distribution to regenerate the Stubs table.
-!else
- $(TCLSH) $(TOOLSDIR)\genStubs.tcl $(GENERICDIR) \
- $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
-!endif
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for ITcl
+#
+# Basic build, test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = itcl
+NEED_TCL_SOURCE = 1
+RCFILE = itcl.rc
+# Tcl 8.6 etc. compile with /DUNICODE. ITcl pre-nmake reform compiled
+# without -DUNICODE. Keep that behaviour for now.
+USE_WIDECHAR_API = 0
+
+!include "rules-ext.vc"
+
+PRJ_OBJS = \
+ $(TMP_DIR)\itcl2TclOO.obj \
+ $(TMP_DIR)\itclBase.obj \
+ $(TMP_DIR)\itclBuiltin.obj \
+ $(TMP_DIR)\itclClass.obj \
+ $(TMP_DIR)\itclCmd.obj \
+ $(TMP_DIR)\itclEnsemble.obj \
+ $(TMP_DIR)\itclHelpers.obj \
+ $(TMP_DIR)\itclInfo.obj \
+ $(TMP_DIR)\itclLinkage.obj \
+ $(TMP_DIR)\itclMethod.obj \
+ $(TMP_DIR)\itclMigrate2TclCore.obj \
+ $(TMP_DIR)\itclObject.obj \
+ $(TMP_DIR)\itclParse.obj \
+ $(TMP_DIR)\itclResolve.obj \
+ $(TMP_DIR)\itclStubs.obj \
+ $(TMP_DIR)\itclStubInit.obj \
+ $(TMP_DIR)\itclTclIntStubsFcn.obj \
+ $(TMP_DIR)\itclUtil.obj \
+!if !$(STATIC_BUILD)
+ $(TMP_DIR)\dllEntryPoint.obj \
+!endif
+
+PRJ_STUBOBJS = $(TMP_DIR)\itclStubLib.obj
+
+PRJ_DEFINES = -D_CRT_SECURE_NO_WARNINGS
+!if $(DEBUG)
+PRJ_DEFINES = $(PRJ_DEFINES) -DITCL_DEBUG
+!endif
+
+PRJ_HEADERS_PUBLIC = \
+ $(GENERICDIR)\itcl.h \
+ $(GENERICDIR)\itclDecls.h
+
+
+# Define the standard targets except we have a custom test target
+DISABLE_TARGET_test = 1
+!include "$(_RULESDIR)\targets.vc"
+
+pkgindex: $(OUT_DIR)\pkgIndex.tcl
+$(OUT_DIR)\pkgIndex.tcl:
+ @$(COPY) << "$(OUT_DIR)\pkgIndex.tcl"
+if {[package vsatisfies 8.0 [package provide Tcl]]} {
+ set add 80
+} else {
+ set add {t}
+}
+if {[info exists ::tcl_platform(debug)] && $$::tcl_platform(debug) && \
+ [file exists [file join $$dir itcl$(VERSION)$${add}g.dll]]} {
+ package ifneeded Itcl $(DOTVERSION) [list load [file join $$dir itcl$(VERSION)$${add}g.dll] Itcl]
+} else {
+ package ifneeded Itcl $(DOTVERSION) [list load [file join $$dir itcl$(VERSION)$${add}.dll] Itcl]
+}
+unset add
+<<
+
+!if $(STATIC_BUILD)
+test :
+ @echo test target not supported for a static library.
+!else
+test : setup $(PROJECT)
+ $(TCLSH) ..\tests\all.tcl $(TESTFLAGS) -loadfile <<
+ set env(ITCL_LIBRARY) [file normalize [file join $(MAKEDIR:\=/) .. library]]
+ package ifneeded $(PROJECT) $(DOTVERSION) [list load [file normalize [file join $(MAKEDIR:\=/) $(PRJLIB:\=/)]]]
+<<
+!endif
+
+genstubs:
+!if $(TCLINSTALL)
+ @echo Need the source distribution to regenerate the Stubs table.
+!else
+ $(TCLSH) $(TOOLSDIR)\genStubs.tcl $(GENERICDIR) \
+ $(GENERICDIR)\$(PROJECT).decls $(GENERICDIR)\$(PROJECT)Int.decls
+!endif
diff --git a/tcl8.6/pkgs/thread2.8.2/win/nmakehlp.c b/tcl8.6/pkgs/itcl4.1.2/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/nmakehlp.c
+++ b/tcl8.6/pkgs/itcl4.1.2/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/thread2.8.2/win/rules-ext.vc b/tcl8.6/pkgs/itcl4.1.2/win/rules-ext.vc
index 58c70fa..58c70fa 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/rules-ext.vc
+++ b/tcl8.6/pkgs/itcl4.1.2/win/rules-ext.vc
diff --git a/tcl8.6/pkgs/itcl4.1.2/win/rules.vc b/tcl8.6/pkgs/itcl4.1.2/win/rules.vc
new file mode 100644
index 0000000..543e959
--- /dev/null
+++ b/tcl8.6/pkgs/itcl4.1.2/win/rules.vc
@@ -0,0 +1,1752 @@
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 1
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+# When building extensions, we need to locate tclsh. Depending on version
+# of Tcl we are building against, this may or may not have a "t" suffix.
+# Try various possibilities in turn.
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+!if !exist("$(TCLSH)")
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+!if !exist($(TCLSH))
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+# Old linkers (Visual C++ 6 in particular) will link for fast loading
+# on Win98. Since we do not support Win98 any more, we specify nowin98
+# as recommended for NT and later. However, this is only required by
+# IX86 on older compilers and only needed if we are not doing a static build.
+
+!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
+# Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!endif
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/sqlite3.21.0/win/targets.vc b/tcl8.6/pkgs/itcl4.1.2/win/targets.vc
index 7f1d388..7f1d388 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/win/targets.vc
+++ b/tcl8.6/pkgs/itcl4.1.2/win/targets.vc
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/toaster.bmp b/tcl8.6/pkgs/itcl4.1.2/win/toaster.bmp
index 5ea80e6..5ea80e6 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/toaster.bmp
+++ b/tcl8.6/pkgs/itcl4.1.2/win/toaster.bmp
Binary files differ
diff --git a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/shell.c b/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/shell.c
deleted file mode 100644
index 6b9cc57..0000000
--- a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/shell.c
+++ /dev/null
@@ -1,8380 +0,0 @@
-/* DO NOT EDIT!
-** This file is automatically generated by the script in the canonical
-** SQLite source tree at tool/mkshellc.tcl. That script combines source
-** code from various constituent source files of SQLite into this single
-** "shell.c" file used to implement the SQLite command-line shell.
-**
-** Most of the code found below comes from the "src/shell.c.in" file in
-** the canonical SQLite source tree. That main file contains "INCLUDE"
-** lines that specify other files in the canonical source tree that are
-** inserted to getnerate this complete program source file.
-**
-** The code from multiple files is combined into this single "shell.c"
-** source file to help make the command-line program easier to compile.
-**
-** To modify this program, get a copy of the canonical SQLite source tree,
-** edit the src/shell.c.in" and/or some of the other files that are included
-** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
-*/
-/*
-** 2001 September 15
-**
-** 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 contains code to implement the "sqlite" command line
-** utility for accessing SQLite databases.
-*/
-#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
-/* This needs to come before any includes for MSVC compiler */
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-/*
-** Warning pragmas copied from msvc.h in the core.
-*/
-#if defined(_MSC_VER)
-#pragma warning(disable : 4054)
-#pragma warning(disable : 4055)
-#pragma warning(disable : 4100)
-#pragma warning(disable : 4127)
-#pragma warning(disable : 4130)
-#pragma warning(disable : 4152)
-#pragma warning(disable : 4189)
-#pragma warning(disable : 4206)
-#pragma warning(disable : 4210)
-#pragma warning(disable : 4232)
-#pragma warning(disable : 4244)
-#pragma warning(disable : 4305)
-#pragma warning(disable : 4306)
-#pragma warning(disable : 4702)
-#pragma warning(disable : 4706)
-#endif /* defined(_MSC_VER) */
-
-/*
-** No support for loadable extensions in VxWorks.
-*/
-#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
-# define SQLITE_OMIT_LOAD_EXTENSION 1
-#endif
-
-/*
-** Enable large-file support for fopen() and friends on unix.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include "sqlite3.h"
-#if SQLITE_USER_AUTHENTICATION
-# include "sqlite3userauth.h"
-#endif
-#include <ctype.h>
-#include <stdarg.h>
-
-#include <signal.h>
-#if !defined(_WIN32) && !defined(WIN32)
-# if !defined(__RTP__) && !defined(_WRS_KERNEL)
-# include <pwd.h>
-# endif
-# include <unistd.h>
-# include <sys/types.h>
-#endif
-
-#if HAVE_READLINE
-# include <readline/readline.h>
-# include <readline/history.h>
-#endif
-
-#if HAVE_EDITLINE
-# include <editline/readline.h>
-#endif
-
-#if HAVE_EDITLINE || HAVE_READLINE
-
-# define shell_add_history(X) add_history(X)
-# define shell_read_history(X) read_history(X)
-# define shell_write_history(X) write_history(X)
-# define shell_stifle_history(X) stifle_history(X)
-# define shell_readline(X) readline(X)
-
-#elif HAVE_LINENOISE
-
-# include "linenoise.h"
-# define shell_add_history(X) linenoiseHistoryAdd(X)
-# define shell_read_history(X) linenoiseHistoryLoad(X)
-# define shell_write_history(X) linenoiseHistorySave(X)
-# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
-# define shell_readline(X) linenoise(X)
-
-#else
-
-# define shell_read_history(X)
-# define shell_write_history(X)
-# define shell_stifle_history(X)
-
-# define SHELL_USE_LOCAL_GETLINE 1
-#endif
-
-
-#if defined(_WIN32) || defined(WIN32)
-# include <io.h>
-# include <fcntl.h>
-# define isatty(h) _isatty(h)
-# ifndef access
-# define access(f,m) _access((f),(m))
-# endif
-# undef popen
-# define popen _popen
-# undef pclose
-# define pclose _pclose
-#else
- /* Make sure isatty() has a prototype. */
- extern int isatty(int);
-
-# if !defined(__RTP__) && !defined(_WRS_KERNEL)
- /* popen and pclose are not C89 functions and so are
- ** sometimes omitted from the <stdio.h> header */
- extern FILE *popen(const char*,const char*);
- extern int pclose(FILE*);
-# else
-# define SQLITE_OMIT_POPEN 1
-# endif
-#endif
-
-#if defined(_WIN32_WCE)
-/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
- * thus we always assume that we have a console. That can be
- * overridden with the -batch command line option.
- */
-#define isatty(x) 1
-#endif
-
-/* ctype macros that work with signed characters */
-#define IsSpace(X) isspace((unsigned char)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);
-extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
-#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
-** rendering quoted strings that contain \n characters). The following
-** routines take care of that.
-*/
-#if defined(_WIN32) || defined(WIN32)
-static void setBinaryMode(FILE *file, int isOutput){
- if( isOutput ) fflush(file);
- _setmode(_fileno(file), _O_BINARY);
-}
-static void setTextMode(FILE *file, int isOutput){
- if( isOutput ) fflush(file);
- _setmode(_fileno(file), _O_TEXT);
-}
-#else
-# define setBinaryMode(X,Y)
-# define setTextMode(X,Y)
-#endif
-
-
-/* True if the timer is enabled */
-static int enableTimer = 0;
-
-/* Return the current wall-clock time */
-static sqlite3_int64 timeOfDay(void){
- static sqlite3_vfs *clockVfs = 0;
- sqlite3_int64 t;
- if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
- if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
- clockVfs->xCurrentTimeInt64(clockVfs, &t);
- }else{
- double r;
- clockVfs->xCurrentTime(clockVfs, &r);
- t = (sqlite3_int64)(r*86400000.0);
- }
- return t;
-}
-
-#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* VxWorks does not support getrusage() as far as we can determine */
-#if defined(_WRS_KERNEL) || defined(__RTP__)
-struct rusage {
- struct timeval ru_utime; /* user CPU time used */
- struct timeval ru_stime; /* system CPU time used */
-};
-#define getrusage(A,B) memset(B,0,sizeof(*B))
-#endif
-
-/* Saved resource information for the beginning of an operation */
-static struct rusage sBegin; /* CPU time at start */
-static sqlite3_int64 iBegin; /* Wall-clock time at start */
-
-/*
-** Begin timing an operation
-*/
-static void beginTimer(void){
- if( enableTimer ){
- getrusage(RUSAGE_SELF, &sBegin);
- iBegin = timeOfDay();
- }
-}
-
-/* Return the difference of two time_structs in seconds */
-static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
- return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
- (double)(pEnd->tv_sec - pStart->tv_sec);
-}
-
-/*
-** Print the timing results.
-*/
-static void endTimer(void){
- if( enableTimer ){
- sqlite3_int64 iEnd = timeOfDay();
- struct rusage sEnd;
- getrusage(RUSAGE_SELF, &sEnd);
- printf("Run Time: real %.3f user %f sys %f\n",
- (iEnd - iBegin)*0.001,
- timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
- timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
- }
-}
-
-#define BEGIN_TIMER beginTimer()
-#define END_TIMER endTimer()
-#define HAS_TIMER 1
-
-#elif (defined(_WIN32) || defined(WIN32))
-
-/* Saved resource information for the beginning of an operation */
-static HANDLE hProcess;
-static FILETIME ftKernelBegin;
-static FILETIME ftUserBegin;
-static sqlite3_int64 ftWallBegin;
-
-/*
-** Begin timing an operation
-*/
-static void beginTimer(void){
- if( enableTimer ){
- FILETIME ftCreation, ftExit;
- GetProcessTimes(hProcess,&ftCreation,&ftExit,
- &ftKernelBegin,&ftUserBegin);
- ftWallBegin = timeOfDay();
- }
-}
-
-/* Return the difference of two FILETIME structs in seconds */
-static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
- sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
- sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
- return (double) ((i64End - i64Start) / 10000000.0);
-}
-
-/*
-** Print the timing results.
-*/
-static void endTimer(void){
- if( enableTimer){
- FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
- sqlite3_int64 ftWallEnd = timeOfDay();
- GetProcessTimes(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
- printf("Run Time: real %.3f user %f sys %f\n",
- (ftWallEnd - ftWallBegin)*0.001,
- timeDiff(&ftUserBegin, &ftUserEnd),
- timeDiff(&ftKernelBegin, &ftKernelEnd));
- }
-}
-
-#define BEGIN_TIMER beginTimer()
-#define END_TIMER endTimer()
-#define HAS_TIMER 1
-
-#else
-#define BEGIN_TIMER
-#define END_TIMER
-#define HAS_TIMER 0
-#endif
-
-/*
-** Used to prevent warnings about unused parameters
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-
-/*
-** If the following flag is set, then command execution stops
-** at an error if we are not interactive.
-*/
-static int bail_on_error = 0;
-
-/*
-** Threat stdin as an interactive input if the following variable
-** is true. Otherwise, assume stdin is connected to a file or pipe.
-*/
-static int stdin_is_interactive = 1;
-
-/*
-** On Windows systems we have to know if standard output is a console
-** in order to translate UTF-8 into MBCS. The following variable is
-** true if translation is required.
-*/
-static int stdout_is_console = 1;
-
-/*
-** The following is the open SQLite database. We make a pointer
-** to this database a static variable so that it can be accessed
-** by the SIGINT handler to interrupt database processing.
-*/
-static sqlite3 *globalDb = 0;
-
-/*
-** True if an interrupt (Control-C) has been received.
-*/
-static volatile int seenInterrupt = 0;
-
-/*
-** This is the name of our program. It is set in main(), used
-** in a number of other places, mostly for error messages.
-*/
-static char *Argv0;
-
-/*
-** Prompt strings. Initialized in main. Settable with
-** .prompt main continue
-*/
-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
-static FILE *iotrace = 0;
-#endif
-
-/*
-** This routine works like printf in that its first argument is a
-** format string and subsequent arguments are values to be substituted
-** in place of % fields. The result of formatting this string
-** is written to iotrace.
-*/
-#ifdef SQLITE_ENABLE_IOTRACE
-static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
- va_list ap;
- char *z;
- if( iotrace==0 ) return;
- va_start(ap, zFormat);
- z = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
- utf8_printf(iotrace, "%s", z);
- sqlite3_free(z);
-}
-#endif
-
-/*
-** Output string zUtf to stream pOut as w characters. If w is negative,
-** then right-justify the text. W is the width in UTF-8 characters, not
-** in bytes. This is different from the %*.*s specification in printf
-** since with %*.*s the width is measured in bytes, not characters.
-*/
-static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
- int i;
- int n;
- int aw = w<0 ? -w : w;
- char zBuf[1000];
- if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
- for(i=n=0; zUtf[i]; i++){
- if( (zUtf[i]&0xc0)!=0x80 ){
- n++;
- if( n==aw ){
- do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
- break;
- }
- }
- }
- if( n>=aw ){
- utf8_printf(pOut, "%.*s", i, zUtf);
- }else if( w<0 ){
- utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
- }else{
- utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
- }
-}
-
-
-/*
-** Determines if a string is a number of not.
-*/
-static int isNumber(const char *z, int *realnum){
- if( *z=='-' || *z=='+' ) z++;
- if( !IsDigit(*z) ){
- return 0;
- }
- z++;
- if( realnum ) *realnum = 0;
- while( IsDigit(*z) ){ z++; }
- if( *z=='.' ){
- z++;
- if( !IsDigit(*z) ) return 0;
- while( IsDigit(*z) ){ z++; }
- if( realnum ) *realnum = 1;
- }
- if( *z=='e' || *z=='E' ){
- z++;
- if( *z=='+' || *z=='-' ) z++;
- if( !IsDigit(*z) ) return 0;
- while( IsDigit(*z) ){ z++; }
- if( realnum ) *realnum = 1;
- }
- return *z==0;
-}
-
-/*
-** Compute a string length that is limited to what can be stored in
-** lower 30 bits of a 32-bit signed integer.
-*/
-static int strlen30(const char *z){
- const char *z2 = z;
- while( *z2 ){ z2++; }
- return 0x3fffffff & (int)(z2 - z);
-}
-
-/*
-** Return the length of a string in characters. Multibyte UTF8 characters
-** count as a single character.
-*/
-static int strlenChar(const char *z){
- int n = 0;
- while( *z ){
- if( (0xc0&*(z++))!=0x80 ) n++;
- }
- return n;
-}
-
-/*
-** This routine reads a line of text from FILE in, stores
-** the text in memory obtained from malloc() and returns a pointer
-** to the text. NULL is returned at end of file, or if malloc()
-** fails.
-**
-** If zLine is not NULL then it is a malloced buffer returned from
-** a previous call to this routine that may be reused.
-*/
-static char *local_getline(char *zLine, FILE *in){
- int nLine = zLine==0 ? 0 : 100;
- int n = 0;
-
- while( 1 ){
- if( n+100>nLine ){
- nLine = nLine*2 + 100;
- zLine = realloc(zLine, nLine);
- if( zLine==0 ) return 0;
- }
- if( fgets(&zLine[n], nLine - n, in)==0 ){
- if( n==0 ){
- free(zLine);
- return 0;
- }
- zLine[n] = 0;
- break;
- }
- while( zLine[n] ) n++;
- if( n>0 && zLine[n-1]=='\n' ){
- n--;
- if( n>0 && zLine[n-1]=='\r' ) n--;
- zLine[n] = 0;
- break;
- }
- }
-#if defined(_WIN32) || defined(WIN32)
- /* For interactive input on Windows systems, translate the
- ** multi-byte characterset characters into UTF-8. */
- if( stdin_is_interactive && in==stdin ){
- char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
- if( zTrans ){
- int nTrans = strlen30(zTrans)+1;
- if( nTrans>nLine ){
- zLine = realloc(zLine, nTrans);
- if( zLine==0 ){
- sqlite3_free(zTrans);
- return 0;
- }
- }
- memcpy(zLine, zTrans, nTrans);
- sqlite3_free(zTrans);
- }
- }
-#endif /* defined(_WIN32) || defined(WIN32) */
- return zLine;
-}
-
-/*
-** Retrieve a single line of input text.
-**
-** If in==0 then read from standard input and prompt before each line.
-** If isContinuation is true, then a continuation prompt is appropriate.
-** If isContinuation is zero, then the main prompt should be used.
-**
-** If zPrior is not NULL then it is a buffer from a prior call to this
-** routine that can be reused.
-**
-** The result is stored in space obtained from malloc() and must either
-** be freed by the caller or else passed back into this routine via the
-** zPrior argument for reuse.
-*/
-static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
- char *zPrompt;
- char *zResult;
- if( in!=0 ){
- zResult = local_getline(zPrior, in);
- }else{
- zPrompt = isContinuation ? continuePrompt : mainPrompt;
-#if SHELL_USE_LOCAL_GETLINE
- printf("%s", zPrompt);
- fflush(stdout);
- zResult = local_getline(zPrior, stdin);
-#else
- free(zPrior);
- zResult = shell_readline(zPrompt);
- if( zResult && *zResult ) shell_add_history(zResult);
-#endif
- }
- return zResult;
-}
-/*
-** A variable length string to which one can append text.
-*/
-typedef struct ShellText ShellText;
-struct ShellText {
- char *z;
- int n;
- int nAlloc;
-};
-
-/*
-** Initialize and destroy a ShellText object
-*/
-static void initText(ShellText *p){
- memset(p, 0, sizeof(*p));
-}
-static void freeText(ShellText *p){
- free(p->z);
- initText(p);
-}
-
-/* zIn is either a pointer to a NULL-terminated string in memory obtained
-** from malloc(), or a NULL pointer. The string pointed to by zAppend is
-** added to zIn, and the result returned in memory obtained from malloc().
-** zIn, if it was not NULL, is freed.
-**
-** If the third argument, quote, is not '\0', then it is used as a
-** quote character for zAppend.
-*/
-static void appendText(ShellText *p, char const *zAppend, char quote){
- int len;
- int i;
- int nAppend = strlen30(zAppend);
-
- len = nAppend+p->n+1;
- if( quote ){
- len += 2;
- for(i=0; i<nAppend; i++){
- if( zAppend[i]==quote ) len++;
- }
- }
-
- if( p->n+len>=p->nAlloc ){
- p->nAlloc = p->nAlloc*2 + len + 20;
- p->z = realloc(p->z, p->nAlloc);
- if( p->z==0 ){
- memset(p, 0, sizeof(*p));
- return;
- }
- }
-
- if( quote ){
- char *zCsr = p->z+p->n;
- *zCsr++ = quote;
- for(i=0; i<nAppend; i++){
- *zCsr++ = zAppend[i];
- if( zAppend[i]==quote ) *zCsr++ = quote;
- }
- *zCsr++ = quote;
- p->n = (int)(zCsr - p->z);
- *zCsr = '\0';
- }else{
- memcpy(p->z+p->n, zAppend, nAppend);
- p->n += nAppend;
- p->z[p->n] = '\0';
- }
-}
-
-/*
-** Attempt to determine if identifier zName needs to be quoted, either
-** because it contains non-alphanumeric characters, or because it is an
-** SQLite keyword. Be conservative in this estimate: When in doubt assume
-** that quoting is required.
-**
-** Return '"' if quoting is required. Return 0 if no quoting is required.
-*/
-static char quoteChar(const char *zName){
- /* All SQLite keywords, in alphabetical order */
- static const char *azKeywords[] = {
- "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
- "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
- "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
- "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
- "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
- "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
- "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
- "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
- "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
- "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
- "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
- "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
- "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
- "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
- "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
- "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
- "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
- "WITH", "WITHOUT",
- };
- int i, lwr, upr, mid, c;
- if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
- for(i=0; zName[i]; i++){
- if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
- }
- lwr = 0;
- upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
- while( lwr<=upr ){
- mid = (lwr+upr)/2;
- c = sqlite3_stricmp(azKeywords[mid], zName);
- if( c==0 ) return '"';
- if( c<0 ){
- lwr = mid+1;
- }else{
- upr = mid-1;
- }
- }
- return 0;
-}
-
-/*
-** SQL function: shell_add_schema(S,X)
-**
-** Add the schema name X to the CREATE statement in S and return the result.
-** Examples:
-**
-** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x);
-**
-** Also works on
-**
-** CREATE INDEX
-** CREATE UNIQUE INDEX
-** CREATE VIEW
-** CREATE TRIGGER
-** CREATE VIRTUAL TABLE
-**
-** This UDF is used by the .schema command to insert the schema name of
-** attached databases into the middle of the sqlite_master.sql field.
-*/
-static void shellAddSchemaName(
- sqlite3_context *pCtx,
- int nVal,
- sqlite3_value **apVal
-){
- static const char *aPrefix[] = {
- "TABLE",
- "INDEX",
- "UNIQUE INDEX",
- "VIEW",
- "TRIGGER",
- "VIRTUAL TABLE"
- };
- int i = 0;
- const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
- const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
- assert( nVal==2 );
- if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
- for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
- int n = strlen30(aPrefix[i]);
- if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
- char cQuote = quoteChar(zSchema);
- char *z;
- if( cQuote ){
- z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
- }else{
- z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
- }
- sqlite3_result_text(pCtx, z, -1, sqlite3_free);
- return;
- }
- }
- }
- sqlite3_result_value(pCtx, apVal[0]);
-}
-
-/*
-** The source code for several run-time loadable extensions is inserted
-** below by the ../tool/mkshellc.tcl script. Before processing that included
-** code, we need to override some macros to make the included program code
-** work here in the middle of this regular program.
-*/
-#define SQLITE_EXTENSION_INIT1
-#define SQLITE_EXTENSION_INIT2(X) (void)(X)
-
-/************************* Begin ../ext/misc/shathree.c ******************/
-/*
-** 2017-03-08
-**
-** 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 SQLite extension implements a functions that compute SHA1 hashes.
-** Two SQL functions are implemented:
-**
-** sha3(X,SIZE)
-** sha3_query(Y,SIZE)
-**
-** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
-** X is NULL.
-**
-** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
-** and returns a hash of their results.
-**
-** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
-** is used. If SIZE is included it must be one of the integers 224, 256,
-** 384, or 512, to determine SHA3 hash variant that is computed.
-*/
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <stdarg.h>
-typedef sqlite3_uint64 u64;
-
-/******************************************************************************
-** The Hash Engine
-*/
-/*
-** Macros to determine whether the machine is big or little endian,
-** and whether or not that determination is run-time or compile-time.
-**
-** For best performance, an attempt is made to guess at the byte-order
-** using C-preprocessor macros. If that is unsuccessful, or if
-** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
-** at run-time.
-*/
-#ifndef SHA3_BYTEORDER
-# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
- defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__)
-# define SHA3_BYTEORDER 1234
-# elif defined(sparc) || defined(__ppc__)
-# define SHA3_BYTEORDER 4321
-# else
-# define SHA3_BYTEORDER 0
-# endif
-#endif
-
-
-/*
-** State structure for a SHA3 hash in progress
-*/
-typedef struct SHA3Context SHA3Context;
-struct SHA3Context {
- union {
- u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
- unsigned char x[1600]; /* ... or 1600 bytes */
- } u;
- unsigned nRate; /* Bytes of input accepted per Keccak iteration */
- unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
- unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
-};
-
-/* Allow the following routine to use the B0 variable, which is also
-** a macro in the termios.h header file */
-#undef B0
-
-/*
-** A single step of the Keccak mixing function for a 1600-bit state
-*/
-static void KeccakF1600Step(SHA3Context *p){
- int i;
- u64 B0, B1, B2, B3, B4;
- u64 C0, C1, C2, C3, C4;
- u64 D0, D1, D2, D3, D4;
- static const u64 RC[] = {
- 0x0000000000000001ULL, 0x0000000000008082ULL,
- 0x800000000000808aULL, 0x8000000080008000ULL,
- 0x000000000000808bULL, 0x0000000080000001ULL,
- 0x8000000080008081ULL, 0x8000000000008009ULL,
- 0x000000000000008aULL, 0x0000000000000088ULL,
- 0x0000000080008009ULL, 0x000000008000000aULL,
- 0x000000008000808bULL, 0x800000000000008bULL,
- 0x8000000000008089ULL, 0x8000000000008003ULL,
- 0x8000000000008002ULL, 0x8000000000000080ULL,
- 0x000000000000800aULL, 0x800000008000000aULL,
- 0x8000000080008081ULL, 0x8000000000008080ULL,
- 0x0000000080000001ULL, 0x8000000080008008ULL
- };
-# define A00 (p->u.s[0])
-# define A01 (p->u.s[1])
-# define A02 (p->u.s[2])
-# define A03 (p->u.s[3])
-# define A04 (p->u.s[4])
-# define A10 (p->u.s[5])
-# define A11 (p->u.s[6])
-# define A12 (p->u.s[7])
-# define A13 (p->u.s[8])
-# define A14 (p->u.s[9])
-# define A20 (p->u.s[10])
-# define A21 (p->u.s[11])
-# define A22 (p->u.s[12])
-# define A23 (p->u.s[13])
-# define A24 (p->u.s[14])
-# define A30 (p->u.s[15])
-# define A31 (p->u.s[16])
-# define A32 (p->u.s[17])
-# define A33 (p->u.s[18])
-# define A34 (p->u.s[19])
-# define A40 (p->u.s[20])
-# define A41 (p->u.s[21])
-# define A42 (p->u.s[22])
-# define A43 (p->u.s[23])
-# define A44 (p->u.s[24])
-# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
-
- for(i=0; i<24; i+=4){
- C0 = A00^A10^A20^A30^A40;
- C1 = A01^A11^A21^A31^A41;
- C2 = A02^A12^A22^A32^A42;
- C3 = A03^A13^A23^A33^A43;
- C4 = A04^A14^A24^A34^A44;
- D0 = C4^ROL64(C1, 1);
- D1 = C0^ROL64(C2, 1);
- D2 = C1^ROL64(C3, 1);
- D3 = C2^ROL64(C4, 1);
- D4 = C3^ROL64(C0, 1);
-
- B0 = (A00^D0);
- B1 = ROL64((A11^D1), 44);
- B2 = ROL64((A22^D2), 43);
- B3 = ROL64((A33^D3), 21);
- B4 = ROL64((A44^D4), 14);
- A00 = B0 ^((~B1)& B2 );
- A00 ^= RC[i];
- A11 = B1 ^((~B2)& B3 );
- A22 = B2 ^((~B3)& B4 );
- A33 = B3 ^((~B4)& B0 );
- A44 = B4 ^((~B0)& B1 );
-
- B2 = ROL64((A20^D0), 3);
- B3 = ROL64((A31^D1), 45);
- B4 = ROL64((A42^D2), 61);
- B0 = ROL64((A03^D3), 28);
- B1 = ROL64((A14^D4), 20);
- A20 = B0 ^((~B1)& B2 );
- A31 = B1 ^((~B2)& B3 );
- A42 = B2 ^((~B3)& B4 );
- A03 = B3 ^((~B4)& B0 );
- A14 = B4 ^((~B0)& B1 );
-
- B4 = ROL64((A40^D0), 18);
- B0 = ROL64((A01^D1), 1);
- B1 = ROL64((A12^D2), 6);
- B2 = ROL64((A23^D3), 25);
- B3 = ROL64((A34^D4), 8);
- A40 = B0 ^((~B1)& B2 );
- A01 = B1 ^((~B2)& B3 );
- A12 = B2 ^((~B3)& B4 );
- A23 = B3 ^((~B4)& B0 );
- A34 = B4 ^((~B0)& B1 );
-
- B1 = ROL64((A10^D0), 36);
- B2 = ROL64((A21^D1), 10);
- B3 = ROL64((A32^D2), 15);
- B4 = ROL64((A43^D3), 56);
- B0 = ROL64((A04^D4), 27);
- A10 = B0 ^((~B1)& B2 );
- A21 = B1 ^((~B2)& B3 );
- A32 = B2 ^((~B3)& B4 );
- A43 = B3 ^((~B4)& B0 );
- A04 = B4 ^((~B0)& B1 );
-
- B3 = ROL64((A30^D0), 41);
- B4 = ROL64((A41^D1), 2);
- B0 = ROL64((A02^D2), 62);
- B1 = ROL64((A13^D3), 55);
- B2 = ROL64((A24^D4), 39);
- A30 = B0 ^((~B1)& B2 );
- A41 = B1 ^((~B2)& B3 );
- A02 = B2 ^((~B3)& B4 );
- A13 = B3 ^((~B4)& B0 );
- A24 = B4 ^((~B0)& B1 );
-
- C0 = A00^A20^A40^A10^A30;
- C1 = A11^A31^A01^A21^A41;
- C2 = A22^A42^A12^A32^A02;
- C3 = A33^A03^A23^A43^A13;
- C4 = A44^A14^A34^A04^A24;
- D0 = C4^ROL64(C1, 1);
- D1 = C0^ROL64(C2, 1);
- D2 = C1^ROL64(C3, 1);
- D3 = C2^ROL64(C4, 1);
- D4 = C3^ROL64(C0, 1);
-
- B0 = (A00^D0);
- B1 = ROL64((A31^D1), 44);
- B2 = ROL64((A12^D2), 43);
- B3 = ROL64((A43^D3), 21);
- B4 = ROL64((A24^D4), 14);
- A00 = B0 ^((~B1)& B2 );
- A00 ^= RC[i+1];
- A31 = B1 ^((~B2)& B3 );
- A12 = B2 ^((~B3)& B4 );
- A43 = B3 ^((~B4)& B0 );
- A24 = B4 ^((~B0)& B1 );
-
- B2 = ROL64((A40^D0), 3);
- B3 = ROL64((A21^D1), 45);
- B4 = ROL64((A02^D2), 61);
- B0 = ROL64((A33^D3), 28);
- B1 = ROL64((A14^D4), 20);
- A40 = B0 ^((~B1)& B2 );
- A21 = B1 ^((~B2)& B3 );
- A02 = B2 ^((~B3)& B4 );
- A33 = B3 ^((~B4)& B0 );
- A14 = B4 ^((~B0)& B1 );
-
- B4 = ROL64((A30^D0), 18);
- B0 = ROL64((A11^D1), 1);
- B1 = ROL64((A42^D2), 6);
- B2 = ROL64((A23^D3), 25);
- B3 = ROL64((A04^D4), 8);
- A30 = B0 ^((~B1)& B2 );
- A11 = B1 ^((~B2)& B3 );
- A42 = B2 ^((~B3)& B4 );
- A23 = B3 ^((~B4)& B0 );
- A04 = B4 ^((~B0)& B1 );
-
- B1 = ROL64((A20^D0), 36);
- B2 = ROL64((A01^D1), 10);
- B3 = ROL64((A32^D2), 15);
- B4 = ROL64((A13^D3), 56);
- B0 = ROL64((A44^D4), 27);
- A20 = B0 ^((~B1)& B2 );
- A01 = B1 ^((~B2)& B3 );
- A32 = B2 ^((~B3)& B4 );
- A13 = B3 ^((~B4)& B0 );
- A44 = B4 ^((~B0)& B1 );
-
- B3 = ROL64((A10^D0), 41);
- B4 = ROL64((A41^D1), 2);
- B0 = ROL64((A22^D2), 62);
- B1 = ROL64((A03^D3), 55);
- B2 = ROL64((A34^D4), 39);
- A10 = B0 ^((~B1)& B2 );
- A41 = B1 ^((~B2)& B3 );
- A22 = B2 ^((~B3)& B4 );
- A03 = B3 ^((~B4)& B0 );
- A34 = B4 ^((~B0)& B1 );
-
- C0 = A00^A40^A30^A20^A10;
- C1 = A31^A21^A11^A01^A41;
- C2 = A12^A02^A42^A32^A22;
- C3 = A43^A33^A23^A13^A03;
- C4 = A24^A14^A04^A44^A34;
- D0 = C4^ROL64(C1, 1);
- D1 = C0^ROL64(C2, 1);
- D2 = C1^ROL64(C3, 1);
- D3 = C2^ROL64(C4, 1);
- D4 = C3^ROL64(C0, 1);
-
- B0 = (A00^D0);
- B1 = ROL64((A21^D1), 44);
- B2 = ROL64((A42^D2), 43);
- B3 = ROL64((A13^D3), 21);
- B4 = ROL64((A34^D4), 14);
- A00 = B0 ^((~B1)& B2 );
- A00 ^= RC[i+2];
- A21 = B1 ^((~B2)& B3 );
- A42 = B2 ^((~B3)& B4 );
- A13 = B3 ^((~B4)& B0 );
- A34 = B4 ^((~B0)& B1 );
-
- B2 = ROL64((A30^D0), 3);
- B3 = ROL64((A01^D1), 45);
- B4 = ROL64((A22^D2), 61);
- B0 = ROL64((A43^D3), 28);
- B1 = ROL64((A14^D4), 20);
- A30 = B0 ^((~B1)& B2 );
- A01 = B1 ^((~B2)& B3 );
- A22 = B2 ^((~B3)& B4 );
- A43 = B3 ^((~B4)& B0 );
- A14 = B4 ^((~B0)& B1 );
-
- B4 = ROL64((A10^D0), 18);
- B0 = ROL64((A31^D1), 1);
- B1 = ROL64((A02^D2), 6);
- B2 = ROL64((A23^D3), 25);
- B3 = ROL64((A44^D4), 8);
- A10 = B0 ^((~B1)& B2 );
- A31 = B1 ^((~B2)& B3 );
- A02 = B2 ^((~B3)& B4 );
- A23 = B3 ^((~B4)& B0 );
- A44 = B4 ^((~B0)& B1 );
-
- B1 = ROL64((A40^D0), 36);
- B2 = ROL64((A11^D1), 10);
- B3 = ROL64((A32^D2), 15);
- B4 = ROL64((A03^D3), 56);
- B0 = ROL64((A24^D4), 27);
- A40 = B0 ^((~B1)& B2 );
- A11 = B1 ^((~B2)& B3 );
- A32 = B2 ^((~B3)& B4 );
- A03 = B3 ^((~B4)& B0 );
- A24 = B4 ^((~B0)& B1 );
-
- B3 = ROL64((A20^D0), 41);
- B4 = ROL64((A41^D1), 2);
- B0 = ROL64((A12^D2), 62);
- B1 = ROL64((A33^D3), 55);
- B2 = ROL64((A04^D4), 39);
- A20 = B0 ^((~B1)& B2 );
- A41 = B1 ^((~B2)& B3 );
- A12 = B2 ^((~B3)& B4 );
- A33 = B3 ^((~B4)& B0 );
- A04 = B4 ^((~B0)& B1 );
-
- C0 = A00^A30^A10^A40^A20;
- C1 = A21^A01^A31^A11^A41;
- C2 = A42^A22^A02^A32^A12;
- C3 = A13^A43^A23^A03^A33;
- C4 = A34^A14^A44^A24^A04;
- D0 = C4^ROL64(C1, 1);
- D1 = C0^ROL64(C2, 1);
- D2 = C1^ROL64(C3, 1);
- D3 = C2^ROL64(C4, 1);
- D4 = C3^ROL64(C0, 1);
-
- B0 = (A00^D0);
- B1 = ROL64((A01^D1), 44);
- B2 = ROL64((A02^D2), 43);
- B3 = ROL64((A03^D3), 21);
- B4 = ROL64((A04^D4), 14);
- A00 = B0 ^((~B1)& B2 );
- A00 ^= RC[i+3];
- A01 = B1 ^((~B2)& B3 );
- A02 = B2 ^((~B3)& B4 );
- A03 = B3 ^((~B4)& B0 );
- A04 = B4 ^((~B0)& B1 );
-
- B2 = ROL64((A10^D0), 3);
- B3 = ROL64((A11^D1), 45);
- B4 = ROL64((A12^D2), 61);
- B0 = ROL64((A13^D3), 28);
- B1 = ROL64((A14^D4), 20);
- A10 = B0 ^((~B1)& B2 );
- A11 = B1 ^((~B2)& B3 );
- A12 = B2 ^((~B3)& B4 );
- A13 = B3 ^((~B4)& B0 );
- A14 = B4 ^((~B0)& B1 );
-
- B4 = ROL64((A20^D0), 18);
- B0 = ROL64((A21^D1), 1);
- B1 = ROL64((A22^D2), 6);
- B2 = ROL64((A23^D3), 25);
- B3 = ROL64((A24^D4), 8);
- A20 = B0 ^((~B1)& B2 );
- A21 = B1 ^((~B2)& B3 );
- A22 = B2 ^((~B3)& B4 );
- A23 = B3 ^((~B4)& B0 );
- A24 = B4 ^((~B0)& B1 );
-
- B1 = ROL64((A30^D0), 36);
- B2 = ROL64((A31^D1), 10);
- B3 = ROL64((A32^D2), 15);
- B4 = ROL64((A33^D3), 56);
- B0 = ROL64((A34^D4), 27);
- A30 = B0 ^((~B1)& B2 );
- A31 = B1 ^((~B2)& B3 );
- A32 = B2 ^((~B3)& B4 );
- A33 = B3 ^((~B4)& B0 );
- A34 = B4 ^((~B0)& B1 );
-
- B3 = ROL64((A40^D0), 41);
- B4 = ROL64((A41^D1), 2);
- B0 = ROL64((A42^D2), 62);
- B1 = ROL64((A43^D3), 55);
- B2 = ROL64((A44^D4), 39);
- A40 = B0 ^((~B1)& B2 );
- A41 = B1 ^((~B2)& B3 );
- A42 = B2 ^((~B3)& B4 );
- A43 = B3 ^((~B4)& B0 );
- A44 = B4 ^((~B0)& B1 );
- }
-}
-
-/*
-** Initialize a new hash. iSize determines the size of the hash
-** in bits and should be one of 224, 256, 384, or 512. Or iSize
-** can be zero to use the default hash size of 256 bits.
-*/
-static void SHA3Init(SHA3Context *p, int iSize){
- memset(p, 0, sizeof(*p));
- if( iSize>=128 && iSize<=512 ){
- p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
- }else{
- p->nRate = (1600 - 2*256)/8;
- }
-#if SHA3_BYTEORDER==1234
- /* Known to be little-endian at compile-time. No-op */
-#elif SHA3_BYTEORDER==4321
- p->ixMask = 7; /* Big-endian */
-#else
- {
- static unsigned int one = 1;
- if( 1==*(unsigned char*)&one ){
- /* Little endian. No byte swapping. */
- p->ixMask = 0;
- }else{
- /* Big endian. Byte swap. */
- p->ixMask = 7;
- }
- }
-#endif
-}
-
-/*
-** Make consecutive calls to the SHA3Update function to add new content
-** to the hash
-*/
-static void SHA3Update(
- SHA3Context *p,
- const unsigned char *aData,
- unsigned int nData
-){
- unsigned int i = 0;
-#if SHA3_BYTEORDER==1234
- if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
- for(; i+7<nData; i+=8){
- p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
- p->nLoaded += 8;
- if( p->nLoaded>=p->nRate ){
- KeccakF1600Step(p);
- p->nLoaded = 0;
- }
- }
- }
-#endif
- for(; i<nData; i++){
-#if SHA3_BYTEORDER==1234
- p->u.x[p->nLoaded] ^= aData[i];
-#elif SHA3_BYTEORDER==4321
- p->u.x[p->nLoaded^0x07] ^= aData[i];
-#else
- p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
-#endif
- p->nLoaded++;
- if( p->nLoaded==p->nRate ){
- KeccakF1600Step(p);
- p->nLoaded = 0;
- }
- }
-}
-
-/*
-** After all content has been added, invoke SHA3Final() to compute
-** the final hash. The function returns a pointer to the binary
-** hash value.
-*/
-static unsigned char *SHA3Final(SHA3Context *p){
- unsigned int i;
- if( p->nLoaded==p->nRate-1 ){
- const unsigned char c1 = 0x86;
- SHA3Update(p, &c1, 1);
- }else{
- const unsigned char c2 = 0x06;
- const unsigned char c3 = 0x80;
- SHA3Update(p, &c2, 1);
- p->nLoaded = p->nRate - 1;
- SHA3Update(p, &c3, 1);
- }
- for(i=0; i<p->nRate; i++){
- p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
- }
- return &p->u.x[p->nRate];
-}
-/* End of the hashing logic
-*****************************************************************************/
-
-/*
-** Implementation of the sha3(X,SIZE) function.
-**
-** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
-** size is 256. If X is a BLOB, it is hashed as is.
-** For all other non-NULL types of input, X is converted into a UTF-8 string
-** and the string is hashed without the trailing 0x00 terminator. The hash
-** of a NULL value is NULL.
-*/
-static void sha3Func(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- SHA3Context cx;
- int eType = sqlite3_value_type(argv[0]);
- int nByte = sqlite3_value_bytes(argv[0]);
- int iSize;
- if( argc==1 ){
- iSize = 256;
- }else{
- iSize = sqlite3_value_int(argv[1]);
- if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
- sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
- "384 512", -1);
- return;
- }
- }
- if( eType==SQLITE_NULL ) return;
- SHA3Init(&cx, iSize);
- if( eType==SQLITE_BLOB ){
- SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
- }else{
- SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
- }
- sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
-}
-
-/* Compute a string using sqlite3_vsnprintf() with a maximum length
-** of 50 bytes and add it to the hash.
-*/
-static void hash_step_vformat(
- SHA3Context *p, /* Add content to this context */
- const char *zFormat,
- ...
-){
- va_list ap;
- int n;
- char zBuf[50];
- va_start(ap, zFormat);
- sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
- va_end(ap);
- n = (int)strlen(zBuf);
- SHA3Update(p, (unsigned char*)zBuf, n);
-}
-
-/*
-** Implementation of the sha3_query(SQL,SIZE) function.
-**
-** This function compiles and runs the SQL statement(s) given in the
-** argument. The results are hashed using a SIZE-bit SHA3. The default
-** size is 256.
-**
-** The format of the byte stream that is hashed is summarized as follows:
-**
-** S<n>:<sql>
-** R
-** N
-** I<int>
-** F<ieee-float>
-** B<size>:<bytes>
-** T<size>:<text>
-**
-** <sql> is the original SQL text for each statement run and <n> is
-** the size of that text. The SQL text is UTF-8. A single R character
-** occurs before the start of each row. N means a NULL value.
-** I mean an 8-byte little-endian integer <int>. F is a floating point
-** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
-** B means blobs of <size> bytes. T means text rendered as <size>
-** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
-** text integers.
-**
-** For each SQL statement in the X input, there is one S segment. Each
-** S segment is followed by zero or more R segments, one for each row in the
-** result set. After each R, there are one or more N, I, F, B, or T segments,
-** one for each column in the result set. Segments are concatentated directly
-** with no delimiters of any kind.
-*/
-static void sha3QueryFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zSql = (const char*)sqlite3_value_text(argv[0]);
- sqlite3_stmt *pStmt = 0;
- int nCol; /* Number of columns in the result set */
- int i; /* Loop counter */
- int rc;
- int n;
- const char *z;
- SHA3Context cx;
- int iSize;
-
- if( argc==1 ){
- iSize = 256;
- }else{
- iSize = sqlite3_value_int(argv[1]);
- if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
- sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
- "384 512", -1);
- return;
- }
- }
- if( zSql==0 ) return;
- SHA3Init(&cx, iSize);
- while( zSql[0] ){
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
- if( rc ){
- char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
- zSql, sqlite3_errmsg(db));
- sqlite3_finalize(pStmt);
- sqlite3_result_error(context, zMsg, -1);
- sqlite3_free(zMsg);
- return;
- }
- if( !sqlite3_stmt_readonly(pStmt) ){
- char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
- sqlite3_finalize(pStmt);
- sqlite3_result_error(context, zMsg, -1);
- sqlite3_free(zMsg);
- return;
- }
- nCol = sqlite3_column_count(pStmt);
- z = sqlite3_sql(pStmt);
- n = (int)strlen(z);
- hash_step_vformat(&cx,"S%d:",n);
- SHA3Update(&cx,(unsigned char*)z,n);
-
- /* Compute a hash over the result of the query */
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- SHA3Update(&cx,(const unsigned char*)"R",1);
- for(i=0; i<nCol; i++){
- switch( sqlite3_column_type(pStmt,i) ){
- case SQLITE_NULL: {
- SHA3Update(&cx, (const unsigned char*)"N",1);
- break;
- }
- case SQLITE_INTEGER: {
- sqlite3_uint64 u;
- int j;
- unsigned char x[9];
- sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
- memcpy(&u, &v, 8);
- for(j=8; j>=1; j--){
- x[j] = u & 0xff;
- u >>= 8;
- }
- x[0] = 'I';
- SHA3Update(&cx, x, 9);
- break;
- }
- case SQLITE_FLOAT: {
- sqlite3_uint64 u;
- int j;
- unsigned char x[9];
- double r = sqlite3_column_double(pStmt,i);
- memcpy(&u, &r, 8);
- for(j=8; j>=1; j--){
- x[j] = u & 0xff;
- u >>= 8;
- }
- x[0] = 'F';
- SHA3Update(&cx,x,9);
- break;
- }
- case SQLITE_TEXT: {
- int n2 = sqlite3_column_bytes(pStmt, i);
- const unsigned char *z2 = sqlite3_column_text(pStmt, i);
- hash_step_vformat(&cx,"T%d:",n2);
- SHA3Update(&cx, z2, n2);
- break;
- }
- case SQLITE_BLOB: {
- int n2 = sqlite3_column_bytes(pStmt, i);
- const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
- hash_step_vformat(&cx,"B%d:",n2);
- SHA3Update(&cx, z2, n2);
- break;
- }
- }
- }
- }
- sqlite3_finalize(pStmt);
- }
- sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
-}
-
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_shathree_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
- sha3Func, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
- sha3Func, 0, 0);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
- sha3QueryFunc, 0, 0);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
- sha3QueryFunc, 0, 0);
- }
- return rc;
-}
-
-/************************* End ../ext/misc/shathree.c ********************/
-/************************* Begin ../ext/misc/fileio.c ******************/
-/*
-** 2014-06-13
-**
-** 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 SQLite extension implements SQL functions readfile() and
-** writefile().
-*/
-SQLITE_EXTENSION_INIT1
-#include <stdio.h>
-
-/*
-** Implementation of the "readfile(X)" SQL function. The entire content
-** of the file named X is read and returned as a BLOB. NULL is returned
-** if the file does not exist or is unreadable.
-*/
-static void readfileFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zName;
- FILE *in;
- long nIn;
- void *pBuf;
-
- (void)(argc); /* Unused parameter */
- zName = (const char*)sqlite3_value_text(argv[0]);
- if( zName==0 ) return;
- in = fopen(zName, "rb");
- if( in==0 ) return;
- fseek(in, 0, SEEK_END);
- nIn = ftell(in);
- rewind(in);
- pBuf = sqlite3_malloc( nIn );
- if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
- sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
- }else{
- sqlite3_free(pBuf);
- }
- fclose(in);
-}
-
-/*
-** Implementation of the "writefile(X,Y)" SQL function. The argument Y
-** is written into file X. The number of bytes written is returned. Or
-** NULL is returned if something goes wrong, such as being unable to open
-** file X for writing.
-*/
-static void writefileFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- FILE *out;
- const char *z;
- sqlite3_int64 rc;
- const char *zFile;
-
- (void)(argc); /* Unused parameter */
- zFile = (const char*)sqlite3_value_text(argv[0]);
- if( zFile==0 ) return;
- out = fopen(zFile, "wb");
- if( out==0 ) return;
- z = (const char*)sqlite3_value_blob(argv[1]);
- if( z==0 ){
- rc = 0;
- }else{
- rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
- }
- fclose(out);
- sqlite3_result_int64(context, rc);
-}
-
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_fileio_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
- readfileFunc, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
- writefileFunc, 0, 0);
- }
- return rc;
-}
-
-/************************* End ../ext/misc/fileio.c ********************/
-/************************* Begin ../ext/misc/completion.c ******************/
-/*
-** 2017-07-10
-**
-** 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 an eponymous virtual table that returns suggested
-** completions for a partial SQL input.
-**
-** Suggested usage:
-**
-** SELECT DISTINCT candidate COLLATE nocase
-** FROM completion($prefix,$wholeline)
-** ORDER BY 1;
-**
-** The two query parameters are optional. $prefix is the text of the
-** current word being typed and that is to be completed. $wholeline is
-** the complete input line, used for context.
-**
-** The raw completion() table might return the same candidate multiple
-** times, for example if the same column name is used to two or more
-** tables. And the candidates are returned in an arbitrary order. Hence,
-** the DISTINCT and ORDER BY are recommended.
-**
-** This virtual table operates at the speed of human typing, and so there
-** is no attempt to make it fast. Even a slow implementation will be much
-** faster than any human can type.
-**
-*/
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/* completion_vtab is a subclass of sqlite3_vtab which will
-** serve as the underlying representation of a completion virtual table
-*/
-typedef struct completion_vtab completion_vtab;
-struct completion_vtab {
- sqlite3_vtab base; /* Base class - must be first */
- sqlite3 *db; /* Database connection for this completion vtab */
-};
-
-/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
-** serve as the underlying representation of a cursor that scans
-** over rows of the result
-*/
-typedef struct completion_cursor completion_cursor;
-struct completion_cursor {
- sqlite3_vtab_cursor base; /* Base class - must be first */
- sqlite3 *db; /* Database connection for this cursor */
- int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
- char *zPrefix; /* The prefix for the word we want to complete */
- char *zLine; /* The whole that we want to complete */
- const char *zCurrentRow; /* Current output row */
- sqlite3_stmt *pStmt; /* Current statement */
- sqlite3_int64 iRowid; /* The rowid */
- int ePhase; /* Current phase */
- int j; /* inter-phase counter */
-};
-
-/* Values for ePhase:
-*/
-#define COMPLETION_FIRST_PHASE 1
-#define COMPLETION_KEYWORDS 1
-#define COMPLETION_PRAGMAS 2
-#define COMPLETION_FUNCTIONS 3
-#define COMPLETION_COLLATIONS 4
-#define COMPLETION_INDEXES 5
-#define COMPLETION_TRIGGERS 6
-#define COMPLETION_DATABASES 7
-#define COMPLETION_TABLES 8
-#define COMPLETION_COLUMNS 9
-#define COMPLETION_MODULES 10
-#define COMPLETION_EOF 11
-
-/*
-** The completionConnect() method is invoked to create a new
-** completion_vtab that describes the completion virtual table.
-**
-** Think of this routine as the constructor for completion_vtab objects.
-**
-** All this routine needs to do is:
-**
-** (1) Allocate the completion_vtab object and initialize all fields.
-**
-** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
-** result set of queries against completion will look like.
-*/
-static int completionConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- completion_vtab *pNew;
- int rc;
-
- (void)(pAux); /* Unused parameter */
- (void)(argc); /* Unused parameter */
- (void)(argv); /* Unused parameter */
- (void)(pzErr); /* Unused parameter */
-
-/* Column numbers */
-#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
-#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
-#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
-#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
-
- rc = sqlite3_declare_vtab(db,
- "CREATE TABLE x("
- " candidate TEXT,"
- " prefix TEXT HIDDEN,"
- " wholeline TEXT HIDDEN,"
- " phase INT HIDDEN" /* Used for debugging only */
- ")");
- if( rc==SQLITE_OK ){
- pNew = sqlite3_malloc( sizeof(*pNew) );
- *ppVtab = (sqlite3_vtab*)pNew;
- if( pNew==0 ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(*pNew));
- pNew->db = db;
- }
- return rc;
-}
-
-/*
-** This method is the destructor for completion_cursor objects.
-*/
-static int completionDisconnect(sqlite3_vtab *pVtab){
- sqlite3_free(pVtab);
- return SQLITE_OK;
-}
-
-/*
-** Constructor for a new completion_cursor object.
-*/
-static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
- completion_cursor *pCur;
- pCur = sqlite3_malloc( sizeof(*pCur) );
- if( pCur==0 ) return SQLITE_NOMEM;
- memset(pCur, 0, sizeof(*pCur));
- pCur->db = ((completion_vtab*)p)->db;
- *ppCursor = &pCur->base;
- return SQLITE_OK;
-}
-
-/*
-** Reset the completion_cursor.
-*/
-static void completionCursorReset(completion_cursor *pCur){
- sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
- sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
- sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
- pCur->j = 0;
-}
-
-/*
-** Destructor for a completion_cursor.
-*/
-static int completionClose(sqlite3_vtab_cursor *cur){
- completionCursorReset((completion_cursor*)cur);
- sqlite3_free(cur);
- return SQLITE_OK;
-}
-
-/*
-** All SQL keywords understood by SQLite
-*/
-static const char *const completionKwrds[] = {
- "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
- "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
- "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
- "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
- "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
- "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
- "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
- "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
- "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
- "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
- "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
- "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
- "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
- "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
- "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
- "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
- "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
- "WITH", "WITHOUT",
-};
-#define completionKwCount \
- (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0]))
-
-/*
-** Advance a completion_cursor to its next row of output.
-**
-** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
-** record the current state of the scan. This routine sets ->zCurrentRow
-** to the current row of output and then returns. If no more rows remain,
-** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
-** table that has reached the end of its scan.
-**
-** The current implementation just lists potential identifiers and
-** keywords and filters them by zPrefix. Future enhancements should
-** take zLine into account to try to restrict the set of identifiers and
-** keywords based on what would be legal at the current point of input.
-*/
-static int completionNext(sqlite3_vtab_cursor *cur){
- completion_cursor *pCur = (completion_cursor*)cur;
- int eNextPhase = 0; /* Next phase to try if current phase reaches end */
- int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
- pCur->iRowid++;
- while( pCur->ePhase!=COMPLETION_EOF ){
- switch( pCur->ePhase ){
- case COMPLETION_KEYWORDS: {
- if( pCur->j >= completionKwCount ){
- pCur->zCurrentRow = 0;
- pCur->ePhase = COMPLETION_DATABASES;
- }else{
- pCur->zCurrentRow = completionKwrds[pCur->j++];
- }
- iCol = -1;
- break;
- }
- case COMPLETION_DATABASES: {
- if( pCur->pStmt==0 ){
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
- &pCur->pStmt, 0);
- }
- iCol = 1;
- eNextPhase = COMPLETION_TABLES;
- break;
- }
- case COMPLETION_TABLES: {
- if( pCur->pStmt==0 ){
- sqlite3_stmt *pS2;
- char *zSql = 0;
- const char *zSep = "";
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
- while( sqlite3_step(pS2)==SQLITE_ROW ){
- const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
- zSql = sqlite3_mprintf(
- "%z%s"
- "SELECT name FROM \"%w\".sqlite_master"
- " WHERE type='table'",
- zSql, zSep, zDb
- );
- if( zSql==0 ) return SQLITE_NOMEM;
- zSep = " UNION ";
- }
- sqlite3_finalize(pS2);
- sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
- sqlite3_free(zSql);
- }
- iCol = 0;
- eNextPhase = COMPLETION_COLUMNS;
- break;
- }
- case COMPLETION_COLUMNS: {
- if( pCur->pStmt==0 ){
- sqlite3_stmt *pS2;
- char *zSql = 0;
- const char *zSep = "";
- sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
- while( sqlite3_step(pS2)==SQLITE_ROW ){
- const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
- zSql = sqlite3_mprintf(
- "%z%s"
- "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
- " JOIN pragma_table_info(sm.name,%Q) AS pti"
- " WHERE sm.type='table'",
- zSql, zSep, zDb, zDb
- );
- if( zSql==0 ) return SQLITE_NOMEM;
- zSep = " UNION ";
- }
- sqlite3_finalize(pS2);
- sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
- sqlite3_free(zSql);
- }
- iCol = 0;
- eNextPhase = COMPLETION_EOF;
- break;
- }
- }
- if( iCol<0 ){
- /* This case is when the phase presets zCurrentRow */
- if( pCur->zCurrentRow==0 ) continue;
- }else{
- if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
- /* Extract the next row of content */
- pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
- }else{
- /* When all rows are finished, advance to the next phase */
- sqlite3_finalize(pCur->pStmt);
- pCur->pStmt = 0;
- pCur->ePhase = eNextPhase;
- continue;
- }
- }
- if( pCur->nPrefix==0 ) break;
- if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
- break;
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Return values of columns for the row at which the completion_cursor
-** is currently pointing.
-*/
-static int completionColumn(
- sqlite3_vtab_cursor *cur, /* The cursor */
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
- int i /* Which column to return */
-){
- completion_cursor *pCur = (completion_cursor*)cur;
- switch( i ){
- case COMPLETION_COLUMN_CANDIDATE: {
- sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT);
- break;
- }
- case COMPLETION_COLUMN_PREFIX: {
- sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
- break;
- }
- case COMPLETION_COLUMN_WHOLELINE: {
- sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
- break;
- }
- case COMPLETION_COLUMN_PHASE: {
- sqlite3_result_int(ctx, pCur->ePhase);
- break;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the rowid for the current row. In this implementation, the
-** rowid is the same as the output value.
-*/
-static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
- completion_cursor *pCur = (completion_cursor*)cur;
- *pRowid = pCur->iRowid;
- return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int completionEof(sqlite3_vtab_cursor *cur){
- completion_cursor *pCur = (completion_cursor*)cur;
- return pCur->ePhase >= COMPLETION_EOF;
-}
-
-/*
-** This method is called to "rewind" the completion_cursor object back
-** to the first row of output. This method is always called at least
-** once prior to any call to completionColumn() or completionRowid() or
-** completionEof().
-*/
-static int completionFilter(
- sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- completion_cursor *pCur = (completion_cursor *)pVtabCursor;
- int iArg = 0;
- (void)(idxStr); /* Unused parameter */
- (void)(argc); /* Unused parameter */
- completionCursorReset(pCur);
- if( idxNum & 1 ){
- pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
- if( pCur->nPrefix>0 ){
- pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
- if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
- }
- iArg++;
- }
- if( idxNum & 2 ){
- pCur->nLine = sqlite3_value_bytes(argv[iArg]);
- if( pCur->nLine>0 ){
- pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
- if( pCur->zLine==0 ) return SQLITE_NOMEM;
- }
- iArg++;
- }
- if( pCur->zLine!=0 && pCur->zPrefix==0 ){
- int i = pCur->nLine;
- while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
- i--;
- }
- pCur->nPrefix = pCur->nLine - i;
- if( pCur->nPrefix>0 ){
- pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
- if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
- }
- }
- pCur->iRowid = 0;
- pCur->ePhase = COMPLETION_FIRST_PHASE;
- return completionNext(pVtabCursor);
-}
-
-/*
-** SQLite will invoke this method one or more times while planning a query
-** that uses the completion virtual table. This routine needs to create
-** a query plan for each invocation and compute an estimated cost for that
-** plan.
-**
-** There are two hidden parameters that act as arguments to the table-valued
-** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
-** is available and bit 1 is set if "wholeline" is available.
-*/
-static int completionBestIndex(
- sqlite3_vtab *tab,
- sqlite3_index_info *pIdxInfo
-){
- int i; /* Loop over constraints */
- int idxNum = 0; /* The query plan bitmask */
- int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
- int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
- int nArg = 0; /* Number of arguments that completeFilter() expects */
- const struct sqlite3_index_constraint *pConstraint;
-
- (void)(tab); /* Unused parameter */
- pConstraint = pIdxInfo->aConstraint;
- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- switch( pConstraint->iColumn ){
- case COMPLETION_COLUMN_PREFIX:
- prefixIdx = i;
- idxNum |= 1;
- break;
- case COMPLETION_COLUMN_WHOLELINE:
- wholelineIdx = i;
- idxNum |= 2;
- break;
- }
- }
- if( prefixIdx>=0 ){
- pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
- pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
- }
- if( wholelineIdx>=0 ){
- pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
- pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
- }
- pIdxInfo->idxNum = idxNum;
- pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
- pIdxInfo->estimatedRows = 500 - 100*nArg;
- return SQLITE_OK;
-}
-
-/*
-** This following structure defines all the methods for the
-** completion virtual table.
-*/
-static const sqlite3_module completionModule = {
- 0, /* iVersion */
- 0, /* xCreate */
- completionConnect, /* xConnect */
- completionBestIndex, /* xBestIndex */
- completionDisconnect, /* xDisconnect */
- 0, /* xDestroy */
- completionOpen, /* xOpen - open a cursor */
- completionClose, /* xClose - close a cursor */
- completionFilter, /* xFilter - configure scan constraints */
- completionNext, /* xNext - advance a cursor */
- completionEof, /* xEof - check for end of scan */
- completionColumn, /* xColumn - read data */
- completionRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0 /* xRollbackTo */
-};
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-int sqlite3CompletionVtabInit(sqlite3 *db){
- int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- rc = sqlite3_create_module(db, "completion", &completionModule, 0);
-#endif
- return rc;
-}
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_completion_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- int rc = SQLITE_OK;
- SQLITE_EXTENSION_INIT2(pApi);
- (void)(pzErrMsg); /* Unused parameter */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- rc = sqlite3CompletionVtabInit(db);
-#endif
- return rc;
-}
-
-/************************* End ../ext/misc/completion.c ********************/
-
-#if defined(SQLITE_ENABLE_SESSION)
-/*
-** State information for a single open session
-*/
-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",
-** saved so that it can be restored by ".explain off"
-*/
-typedef struct SavedModeInfo SavedModeInfo;
-struct SavedModeInfo {
- int valid; /* Is there legit data in here? */
- int mode; /* Mode prior to ".explain on" */
- int showHeader; /* The ".header" setting prior to ".explain on" */
- int colWidth[100]; /* Column widths prior to ".explain on" */
-};
-
-/*
-** State information about the database connection is contained in an
-** instance of the following structure.
-*/
-typedef struct ShellState ShellState;
-struct ShellState {
- sqlite3 *db; /* The database */
- int autoExplain; /* Automatically turn on .explain mode */
- int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
- int statsOn; /* True to display memory stats before each finalize */
- int scanstatsOn; /* True to display scan stats before each finalize */
- int outCount; /* Revert to stdout when reaching zero */
- int cnt; /* Number of records displayed so far */
- FILE *out; /* Write results here */
- FILE *traceOut; /* Output for sqlite3_trace() */
- int nErr; /* Number of errors seen */
- int mode; /* An output mode setting */
- int cMode; /* temporary output mode for the current query */
- int normalMode; /* Output mode before ".explain on" */
- int writableSchema; /* True if PRAGMA writable_schema=ON */
- int showHeader; /* True to show column names in List or Column mode */
- int nCheck; /* Number of ".check" commands run */
- unsigned shellFlgs; /* Various flags */
- char *zDestTable; /* Name of destination table when MODE_Insert */
- char zTestcase[30]; /* Name of current test case */
- char colSeparator[20]; /* Column separator character for several modes */
- char rowSeparator[20]; /* Row separator character for MODE_Ascii */
- int colWidth[100]; /* Requested width of each column when in column mode*/
- int actualWidth[100]; /* Actual width of each column */
- char nullValue[20]; /* The text to print when a NULL comes back from
- ** the database */
- char outfile[FILENAME_MAX]; /* Filename for *out */
- const char *zDbFilename; /* name of the database file */
- char *zFreeOnClose; /* Filename to free when closing */
- const char *zVfs; /* Name of VFS to use */
- sqlite3_stmt *pStmt; /* Current statement if any. */
- FILE *pLog; /* Write log output here */
- 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
-};
-
-/*
-** These are the allowed shellFlgs values
-*/
-#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
-#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
-#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
-#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
-#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
-#define SHFLG_CountChanges 0x00000020 /* .changes setting */
-#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
-
-/*
-** Macros for testing and setting shellFlgs
-*/
-#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
-#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
-#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
-
-/*
-** These are the allowed modes.
-*/
-#define MODE_Line 0 /* One column per line. Blank line between records */
-#define MODE_Column 1 /* One record per line in neat columns */
-#define MODE_List 2 /* One record per line with a separator */
-#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
-#define MODE_Html 4 /* Generate an XHTML table */
-#define MODE_Insert 5 /* Generate SQL "insert" statements */
-#define MODE_Quote 6 /* Quote values as for SQL */
-#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
-#define MODE_Csv 8 /* Quote strings, numbers are plain */
-#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
-#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
-#define MODE_Pretty 11 /* Pretty-print schemas */
-
-static const char *const modeDescr[] = {
- "line",
- "column",
- "list",
- "semi",
- "html",
- "insert",
- "quote",
- "tcl",
- "csv",
- "explain",
- "ascii",
- "prettyprint",
-};
-
-/*
-** These are the column/row/line separators used by the various
-** import/export modes.
-*/
-#define SEP_Column "|"
-#define SEP_Row "\n"
-#define SEP_Tab "\t"
-#define SEP_Space " "
-#define SEP_Comma ","
-#define SEP_CrLf "\r\n"
-#define SEP_Unit "\x1F"
-#define SEP_Record "\x1E"
-
-/*
-** Number of elements in an array
-*/
-#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
-
-/*
-** A callback for the sqlite3_log() interface.
-*/
-static void shellLog(void *pArg, int iErrCode, const char *zMsg){
- ShellState *p = (ShellState*)pArg;
- if( p->pLog==0 ) return;
- utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
- fflush(p->pLog);
-}
-
-/*
-** Output the given string as a hex-encoded blob (eg. X'1234' )
-*/
-static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
- int i;
- char *zBlob = (char *)pBlob;
- raw_printf(out,"X'");
- for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
- raw_printf(out,"'");
-}
-
-/*
-** Find a string that is not found anywhere in z[]. Return a pointer
-** to that string.
-**
-** Try to use zA and zB first. If both of those are already found in z[]
-** then make up some string and store it in the buffer zBuf.
-*/
-static const char *unused_string(
- const char *z, /* Result must not appear anywhere in z */
- const char *zA, const char *zB, /* Try these first */
- char *zBuf /* Space to store a generated string */
-){
- unsigned i = 0;
- if( strstr(z, zA)==0 ) return zA;
- if( strstr(z, zB)==0 ) return zB;
- do{
- sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
- }while( strstr(z,zBuf)!=0 );
- return zBuf;
-}
-
-/*
-** Output the given string as a quoted string using SQL quoting conventions.
-**
-** See also: output_quoted_escaped_string()
-*/
-static void output_quoted_string(FILE *out, const char *z){
- int i;
- char c;
- setBinaryMode(out, 1);
- for(i=0; (c = z[i])!=0 && c!='\''; i++){}
- if( c==0 ){
- utf8_printf(out,"'%s'",z);
- }else{
- raw_printf(out, "'");
- while( *z ){
- for(i=0; (c = z[i])!=0 && c!='\''; i++){}
- if( c=='\'' ) i++;
- if( i ){
- utf8_printf(out, "%.*s", i, z);
- z += i;
- }
- if( c=='\'' ){
- raw_printf(out, "'");
- continue;
- }
- if( c==0 ){
- break;
- }
- z++;
- }
- raw_printf(out, "'");
- }
- setTextMode(out, 1);
-}
-
-/*
-** Output the given string as a quoted string using SQL quoting conventions.
-** Additionallly , escape the "\n" and "\r" characters so that they do not
-** get corrupted by end-of-line translation facilities in some operating
-** systems.
-**
-** This is like output_quoted_string() but with the addition of the \r\n
-** escape mechanism.
-*/
-static void output_quoted_escaped_string(FILE *out, const char *z){
- int i;
- char c;
- setBinaryMode(out, 1);
- for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
- if( c==0 ){
- utf8_printf(out,"'%s'",z);
- }else{
- const char *zNL = 0;
- const char *zCR = 0;
- int nNL = 0;
- int nCR = 0;
- char zBuf1[20], zBuf2[20];
- for(i=0; z[i]; i++){
- if( z[i]=='\n' ) nNL++;
- if( z[i]=='\r' ) nCR++;
- }
- if( nNL ){
- raw_printf(out, "replace(");
- zNL = unused_string(z, "\\n", "\\012", zBuf1);
- }
- if( nCR ){
- raw_printf(out, "replace(");
- zCR = unused_string(z, "\\r", "\\015", zBuf2);
- }
- raw_printf(out, "'");
- while( *z ){
- for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
- if( c=='\'' ) i++;
- if( i ){
- utf8_printf(out, "%.*s", i, z);
- z += i;
- }
- if( c=='\'' ){
- raw_printf(out, "'");
- continue;
- }
- if( c==0 ){
- break;
- }
- z++;
- if( c=='\n' ){
- raw_printf(out, "%s", zNL);
- continue;
- }
- raw_printf(out, "%s", zCR);
- }
- raw_printf(out, "'");
- if( nCR ){
- raw_printf(out, ",'%s',char(13))", zCR);
- }
- if( nNL ){
- raw_printf(out, ",'%s',char(10))", zNL);
- }
- }
- setTextMode(out, 1);
-}
-
-/*
-** Output the given string as a quoted according to C or TCL quoting rules.
-*/
-static void output_c_string(FILE *out, const char *z){
- unsigned int c;
- fputc('"', out);
- while( (c = *(z++))!=0 ){
- if( c=='\\' ){
- fputc(c, out);
- fputc(c, out);
- }else if( c=='"' ){
- fputc('\\', out);
- fputc('"', out);
- }else if( c=='\t' ){
- fputc('\\', out);
- fputc('t', out);
- }else if( c=='\n' ){
- fputc('\\', out);
- fputc('n', out);
- }else if( c=='\r' ){
- fputc('\\', out);
- fputc('r', out);
- }else if( !isprint(c&0xff) ){
- raw_printf(out, "\\%03o", c&0xff);
- }else{
- fputc(c, out);
- }
- }
- fputc('"', out);
-}
-
-/*
-** Output the given string with characters that are special to
-** HTML escaped.
-*/
-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]!='\"'
- && z[i]!='\'';
- i++){}
- if( i>0 ){
- utf8_printf(out,"%.*s",i,z);
- }
- if( z[i]=='<' ){
- raw_printf(out,"&lt;");
- }else if( z[i]=='&' ){
- raw_printf(out,"&amp;");
- }else if( z[i]=='>' ){
- raw_printf(out,"&gt;");
- }else if( z[i]=='\"' ){
- raw_printf(out,"&quot;");
- }else if( z[i]=='\'' ){
- raw_printf(out,"&#39;");
- }else{
- break;
- }
- z += i + 1;
- }
-}
-
-/*
-** If a field contains any character identified by a 1 in the following
-** array, then the string must be quoted for CSV.
-*/
-static const char needCsvQuote[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-};
-
-/*
-** Output a single term of CSV. Actually, p->colSeparator is used for
-** the separator, which may or may not be a comma. p->nullValue is
-** the null value. Strings are quoted if necessary. The separator
-** is only issued if bSep is true.
-*/
-static void output_csv(ShellState *p, const char *z, int bSep){
- FILE *out = p->out;
- if( z==0 ){
- utf8_printf(out,"%s",p->nullValue);
- }else{
- int i;
- int nSep = strlen30(p->colSeparator);
- for(i=0; z[i]; i++){
- if( needCsvQuote[((unsigned char*)z)[i]]
- || (z[i]==p->colSeparator[0] &&
- (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
- i = 0;
- break;
- }
- }
- if( i==0 ){
- putc('"', out);
- for(i=0; z[i]; i++){
- if( z[i]=='"' ) putc('"', out);
- putc(z[i], out);
- }
- putc('"', out);
- }else{
- utf8_printf(out, "%s", z);
- }
- }
- if( bSep ){
- utf8_printf(p->out, "%s", p->colSeparator);
- }
-}
-
-#if defined(SIGINT) || defined(_WIN32) || defined(WIN32)
-/*
-** This routine runs when the user presses Ctrl-C
-*/
-static void interrupt_handler(int NotUsed){
- UNUSED_PARAMETER(NotUsed);
- seenInterrupt++;
- if( seenInterrupt>2 ) exit(1);
- if( globalDb ) sqlite3_interrupt(globalDb);
-}
-
-#if defined(_WIN32) || defined(WIN32)
-/*
-** Windows event handler
-*/
-BOOL WINAPI CtrlHandler(DWORD dwType){
- switch( dwType ){
- case CTRL_C_EVENT:
- interrupt_handler(0);
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-#endif
-#endif
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
-/*
-** 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;
- utf8_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;
-}
-#endif
-
-/*
-** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
-**
-** This routine converts some CREATE TABLE statements for shadow tables
-** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
-*/
-static void printSchemaLine(FILE *out, const char *z, const char *zTail){
- if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
- utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
- }else{
- utf8_printf(out, "%s%s", z, zTail);
- }
-}
-static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
- char c = z[n];
- z[n] = 0;
- printSchemaLine(out, z, zTail);
- z[n] = c;
-}
-
-/*
-** This is the callback routine that the shell
-** invokes for each row of a query result.
-*/
-static int shell_callback(
- void *pArg,
- int nArg, /* Number of result columns */
- char **azArg, /* Text of each result column */
- char **azCol, /* Column names */
- int *aiType /* Column types */
-){
- int i;
- ShellState *p = (ShellState*)pArg;
-
- if( azArg==0 ) return 0;
- switch( p->cMode ){
- case MODE_Line: {
- int w = 5;
- if( azArg==0 ) break;
- for(i=0; i<nArg; i++){
- int len = strlen30(azCol[i] ? azCol[i] : "");
- if( len>w ) w = len;
- }
- if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
- for(i=0; i<nArg; i++){
- utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
- azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
- }
- break;
- }
- case MODE_Explain:
- case MODE_Column: {
- static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
- const int *colWidth;
- int showHdr;
- char *rowSep;
- if( p->cMode==MODE_Column ){
- colWidth = p->colWidth;
- showHdr = p->showHeader;
- rowSep = p->rowSeparator;
- }else{
- colWidth = aExplainWidths;
- showHdr = 1;
- rowSep = SEP_Row;
- }
- if( p->cnt++==0 ){
- for(i=0; i<nArg; i++){
- int w, n;
- if( i<ArraySize(p->colWidth) ){
- w = colWidth[i];
- }else{
- w = 0;
- }
- if( w==0 ){
- w = strlenChar(azCol[i] ? azCol[i] : "");
- if( w<10 ) w = 10;
- n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
- if( w<n ) w = n;
- }
- if( i<ArraySize(p->actualWidth) ){
- p->actualWidth[i] = w;
- }
- if( showHdr ){
- utf8_width_print(p->out, w, azCol[i]);
- utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
- }
- }
- if( showHdr ){
- for(i=0; i<nArg; i++){
- int w;
- if( i<ArraySize(p->actualWidth) ){
- w = p->actualWidth[i];
- if( w<0 ) w = -w;
- }else{
- w = 10;
- }
- utf8_printf(p->out,"%-*.*s%s",w,w,
- "----------------------------------------------------------"
- "----------------------------------------------------------",
- i==nArg-1 ? rowSep : " ");
- }
- }
- }
- if( azArg==0 ) break;
- for(i=0; i<nArg; i++){
- int w;
- if( i<ArraySize(p->actualWidth) ){
- w = p->actualWidth[i];
- }else{
- w = 10;
- }
- if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){
- w = strlenChar(azArg[i]);
- }
- if( i==1 && p->aiIndent && p->pStmt ){
- if( p->iIndent<p->nIndent ){
- utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
- }
- p->iIndent++;
- }
- utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
- utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
- }
- break;
- }
- case MODE_Semi: { /* .schema and .fullschema output */
- printSchemaLine(p->out, azArg[0], ";\n");
- 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( z[j-1]=='\r' ) z[j-1] = '\n';
- 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 ){
- printSchemaLineN(p->out, z, j, "\n");
- j = 0;
- }
- }
- z[j++] = c;
- if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
- if( c=='\n' ) j--;
- printSchemaLineN(p->out, z, j, "\n ");
- j = 0;
- nLine++;
- while( IsSpace(z[i+1]) ){ i++; }
- }
- }
- z[j] = 0;
- }
- printSchemaLine(p->out, z, ";\n");
- sqlite3_free(z);
- break;
- }
- case MODE_List: {
- if( p->cnt++==0 && p->showHeader ){
- for(i=0; i<nArg; i++){
- utf8_printf(p->out,"%s%s",azCol[i],
- i==nArg-1 ? p->rowSeparator : p->colSeparator);
- }
- }
- if( azArg==0 ) break;
- for(i=0; i<nArg; i++){
- char *z = azArg[i];
- if( z==0 ) z = p->nullValue;
- utf8_printf(p->out, "%s", z);
- if( i<nArg-1 ){
- utf8_printf(p->out, "%s", p->colSeparator);
- }else{
- utf8_printf(p->out, "%s", p->rowSeparator);
- }
- }
- break;
- }
- case MODE_Html: {
- if( p->cnt++==0 && p->showHeader ){
- raw_printf(p->out,"<TR>");
- for(i=0; i<nArg; i++){
- raw_printf(p->out,"<TH>");
- output_html_string(p->out, azCol[i]);
- raw_printf(p->out,"</TH>\n");
- }
- raw_printf(p->out,"</TR>\n");
- }
- if( azArg==0 ) break;
- raw_printf(p->out,"<TR>");
- for(i=0; i<nArg; i++){
- raw_printf(p->out,"<TD>");
- output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
- raw_printf(p->out,"</TD>\n");
- }
- raw_printf(p->out,"</TR>\n");
- break;
- }
- case MODE_Tcl: {
- if( p->cnt++==0 && p->showHeader ){
- for(i=0; i<nArg; i++){
- output_c_string(p->out,azCol[i] ? azCol[i] : "");
- if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- }
- if( azArg==0 ) break;
- for(i=0; i<nArg; i++){
- output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
- if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- break;
- }
- case MODE_Csv: {
- 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);
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- }
- if( nArg>0 ){
- for(i=0; i<nArg; i++){
- output_csv(p, azArg[i], i<nArg-1);
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- }
- setTextMode(p->out, 1);
- break;
- }
- case MODE_Insert: {
- if( azArg==0 ) break;
- utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
- if( p->showHeader ){
- raw_printf(p->out,"(");
- for(i=0; i<nArg; i++){
- if( i>0 ) raw_printf(p->out, ",");
- if( quoteChar(azCol[i]) ){
- char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
- utf8_printf(p->out, "%s", z);
- sqlite3_free(z);
- }else{
- raw_printf(p->out, "%s", azCol[i]);
- }
- }
- raw_printf(p->out,")");
- }
- p->cnt++;
- for(i=0; i<nArg; i++){
- raw_printf(p->out, i>0 ? "," : " VALUES(");
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
- utf8_printf(p->out,"NULL");
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
- if( ShellHasFlag(p, SHFLG_Newlines) ){
- output_quoted_string(p->out, azArg[i]);
- }else{
- output_quoted_escaped_string(p->out, azArg[i]);
- }
- }else if( aiType && aiType[i]==SQLITE_INTEGER ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
- char z[50];
- double r = sqlite3_column_double(p->pStmt, i);
- sqlite3_snprintf(50,z,"%!.20g", r);
- raw_printf(p->out, "%s", z);
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
- output_hex_blob(p->out, pBlob, nBlob);
- }else if( isNumber(azArg[i], 0) ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else if( ShellHasFlag(p, SHFLG_Newlines) ){
- output_quoted_string(p->out, azArg[i]);
- }else{
- output_quoted_escaped_string(p->out, azArg[i]);
- }
- }
- raw_printf(p->out,");\n");
- break;
- }
- case MODE_Quote: {
- if( azArg==0 ) break;
- if( p->cnt==0 && p->showHeader ){
- for(i=0; i<nArg; i++){
- if( i>0 ) raw_printf(p->out, ",");
- output_quoted_string(p->out, azCol[i]);
- }
- raw_printf(p->out,"\n");
- }
- p->cnt++;
- for(i=0; i<nArg; i++){
- if( i>0 ) raw_printf(p->out, ",");
- if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
- utf8_printf(p->out,"NULL");
- }else if( aiType && aiType[i]==SQLITE_TEXT ){
- output_quoted_string(p->out, azArg[i]);
- }else if( aiType && aiType[i]==SQLITE_INTEGER ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else if( aiType && aiType[i]==SQLITE_FLOAT ){
- char z[50];
- double r = sqlite3_column_double(p->pStmt, i);
- sqlite3_snprintf(50,z,"%!.20g", r);
- raw_printf(p->out, "%s", z);
- }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
- const void *pBlob = sqlite3_column_blob(p->pStmt, i);
- int nBlob = sqlite3_column_bytes(p->pStmt, i);
- output_hex_blob(p->out, pBlob, nBlob);
- }else if( isNumber(azArg[i], 0) ){
- utf8_printf(p->out,"%s", azArg[i]);
- }else{
- output_quoted_string(p->out, azArg[i]);
- }
- }
- raw_printf(p->out,"\n");
- break;
- }
- case MODE_Ascii: {
- if( p->cnt++==0 && p->showHeader ){
- for(i=0; i<nArg; i++){
- if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
- utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- }
- if( azArg==0 ) break;
- for(i=0; i<nArg; i++){
- if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
- utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
- }
- utf8_printf(p->out, "%s", p->rowSeparator);
- break;
- }
- }
- return 0;
-}
-
-/*
-** This is the callback routine that the SQLite library
-** invokes for each row of a query result.
-*/
-static int callback(void *pArg, int nArg, char **azArg, char **azCol){
- /* since we don't have type info, call the shell_callback with a NULL value */
- return shell_callback(pArg, nArg, azArg, azCol, NULL);
-}
-
-/*
-** This is the callback routine from sqlite3_exec() that appends all
-** output onto the end of a ShellText object.
-*/
-static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
- ShellText *p = (ShellText*)pArg;
- int i;
- UNUSED_PARAMETER(az);
- if( azArg==0 ) return 0;
- if( p->n ) appendText(p, "|", 0);
- for(i=0; i<nArg; i++){
- if( i ) appendText(p, ",", 0);
- if( azArg[i] ) appendText(p, azArg[i], 0);
- }
- return 0;
-}
-
-/*
-** Generate an appropriate SELFTEST table in the main database.
-*/
-static void createSelftestTable(ShellState *p){
- char *zErrMsg = 0;
- sqlite3_exec(p->db,
- "SAVEPOINT selftest_init;\n"
- "CREATE TABLE IF NOT EXISTS selftest(\n"
- " tno INTEGER PRIMARY KEY,\n" /* Test number */
- " op TEXT,\n" /* Operator: memo run */
- " cmd TEXT,\n" /* Command text */
- " ans TEXT\n" /* Desired answer */
- ");"
- "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
- "INSERT INTO [_shell$self](rowid,op,cmd)\n"
- " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
- " 'memo','Tests generated by --init');\n"
- "INSERT INTO [_shell$self]\n"
- " SELECT 'run',\n"
- " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
- "FROM sqlite_master ORDER BY 2'',224))',\n"
- " hex(sha3_query('SELECT type,name,tbl_name,sql "
- "FROM sqlite_master ORDER BY 2',224));\n"
- "INSERT INTO [_shell$self]\n"
- " SELECT 'run',"
- " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
- " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
- " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
- " FROM (\n"
- " SELECT name FROM sqlite_master\n"
- " WHERE type='table'\n"
- " AND name<>'selftest'\n"
- " AND coalesce(rootpage,0)>0\n"
- " )\n"
- " ORDER BY name;\n"
- "INSERT INTO [_shell$self]\n"
- " VALUES('run','PRAGMA integrity_check','ok');\n"
- "INSERT INTO selftest(tno,op,cmd,ans)"
- " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
- "DROP TABLE [_shell$self];"
- ,0,0,&zErrMsg);
- if( zErrMsg ){
- utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
- sqlite3_free(zErrMsg);
- }
- sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
-}
-
-
-/*
-** Set the destination table field of the ShellState structure to
-** the name of the table given. Escape any quote characters in the
-** table name.
-*/
-static void set_table_name(ShellState *p, const char *zName){
- int i, n;
- char cQuote;
- char *z;
-
- if( p->zDestTable ){
- free(p->zDestTable);
- p->zDestTable = 0;
- }
- if( zName==0 ) return;
- cQuote = quoteChar(zName);
- n = strlen30(zName);
- if( cQuote ) n += n+2;
- z = p->zDestTable = malloc( n+1 );
- if( z==0 ){
- raw_printf(stderr,"Error: out of memory\n");
- exit(1);
- }
- n = 0;
- if( cQuote ) z[n++] = cQuote;
- for(i=0; zName[i]; i++){
- z[n++] = zName[i];
- if( zName[i]==cQuote ) z[n++] = cQuote;
- }
- if( cQuote ) z[n++] = cQuote;
- z[n] = 0;
-}
-
-
-/*
-** Execute a query statement that will generate SQL output. Print
-** the result columns, comma-separated, on a line and then add a
-** 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
-** "--" comment occurs at the end of the statement, the comment
-** won't consume the semicolon terminator.
-*/
-static int run_table_dump_query(
- ShellState *p, /* Query context */
- const char *zSelect, /* SELECT statement to extract content */
- const char *zFirstRow /* Print before first row, if not NULL */
-){
- sqlite3_stmt *pSelect;
- int rc;
- int nResult;
- int i;
- const char *z;
- rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
- if( rc!=SQLITE_OK || !pSelect ){
- utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
- sqlite3_errmsg(p->db));
- if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
- return rc;
- }
- rc = sqlite3_step(pSelect);
- nResult = sqlite3_column_count(pSelect);
- while( rc==SQLITE_ROW ){
- if( zFirstRow ){
- utf8_printf(p->out, "%s", zFirstRow);
- zFirstRow = 0;
- }
- z = (const char*)sqlite3_column_text(pSelect, 0);
- utf8_printf(p->out, "%s", z);
- for(i=1; i<nResult; i++){
- utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
- }
- if( z==0 ) z = "";
- while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
- if( z[0] ){
- raw_printf(p->out, "\n;\n");
- }else{
- raw_printf(p->out, ";\n");
- }
- rc = sqlite3_step(pSelect);
- }
- rc = sqlite3_finalize(pSelect);
- if( rc!=SQLITE_OK ){
- utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
- sqlite3_errmsg(p->db));
- if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
- }
- return rc;
-}
-
-/*
-** Allocate space and save off current error string.
-*/
-static char *save_err_msg(
- sqlite3 *db /* Database to query */
-){
- int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
- char *zErrMsg = sqlite3_malloc(nErrMsg);
- if( zErrMsg ){
- memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
- }
- return zErrMsg;
-}
-
-#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 ){
- utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
- break;
- }
- }
- }
- fclose(in);
-}
-#endif
-
-/*
-** Display a single line of status using 64-bit values.
-*/
-static void displayStatLine(
- ShellState *p, /* The shell context */
- char *zLabel, /* Label for this one line */
- char *zFormat, /* Format for the result */
- int iStatusCtrl, /* Which status to display */
- int bReset /* True to reset the stats */
-){
- sqlite3_int64 iCur = -1;
- sqlite3_int64 iHiwtr = -1;
- int i, nPercent;
- char zLine[200];
- sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
- for(i=0, nPercent=0; zFormat[i]; i++){
- if( zFormat[i]=='%' ) nPercent++;
- }
- if( nPercent>1 ){
- sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
- }else{
- sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
- }
- raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
-}
-
-/*
-** Display memory stats.
-*/
-static int display_stats(
- sqlite3 *db, /* Database to query */
- ShellState *pArg, /* Pointer to ShellState */
- int bReset /* True to reset the stats */
-){
- int iCur;
- int iHiwtr;
-
- if( pArg && pArg->out ){
- displayStatLine(pArg, "Memory Used:",
- "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
- displayStatLine(pArg, "Number of Outstanding Allocations:",
- "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
- if( pArg->shellFlgs & SHFLG_Pagecache ){
- displayStatLine(pArg, "Number of Pcache Pages Used:",
- "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
- }
- displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
- "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
- displayStatLine(pArg, "Largest Allocation:",
- "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
- displayStatLine(pArg, "Largest Pcache Allocation:",
- "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
-#ifdef YYTRACKMAXSTACKDEPTH
- displayStatLine(pArg, "Deepest Parser Stack:",
- "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
-#endif
- }
-
- if( pArg && pArg->out && db ){
- if( pArg->shellFlgs & SHFLG_Lookaside ){
- iHiwtr = iCur = -1;
- sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
- &iCur, &iHiwtr, bReset);
- raw_printf(pArg->out,
- "Lookaside Slots Used: %d (max %d)\n",
- iCur, iHiwtr);
- sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
- &iCur, &iHiwtr, bReset);
- raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
- iHiwtr);
- sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
- &iCur, &iHiwtr, bReset);
- raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
- iHiwtr);
- sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
- &iCur, &iHiwtr, bReset);
- raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
- iHiwtr);
- }
- iHiwtr = iCur = -1;
- sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
- raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
- iCur);
- iHiwtr = iCur = -1;
- sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
- 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);
- iHiwtr = iCur = -1;
- sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
- 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);
- 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);
- }
-
- if( pArg && pArg->out && db && pArg->pStmt ){
- iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
- bReset);
- raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
- iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
- raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
- iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
- raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
- iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
- 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;
-}
-
-/*
-** Display scan stats.
-*/
-static void display_scanstats(
- sqlite3 *db, /* Database to query */
- ShellState *pArg /* Pointer to ShellState */
-){
-#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
- UNUSED_PARAMETER(db);
- UNUSED_PARAMETER(pArg);
-#else
- int i, k, n, mx;
- raw_printf(pArg->out, "-------- scanstats --------\n");
- mx = 0;
- for(k=0; k<=mx; k++){
- double rEstLoop = 1.0;
- for(i=n=0; 1; i++){
- sqlite3_stmt *p = pArg->pStmt;
- sqlite3_int64 nLoop, nVisit;
- double rEst;
- int iSid;
- const char *zExplain;
- if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
- break;
- }
- sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
- if( iSid>mx ) mx = iSid;
- if( iSid!=k ) continue;
- if( n==0 ){
- rEstLoop = (double)nLoop;
- if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
- }
- n++;
- sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
- sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
- 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,
- " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
- nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
- );
- }
- }
- raw_printf(pArg->out, "---------------------------\n");
-#endif
-}
-
-/*
-** Parameter azArray points to a zero-terminated array of strings. zStr
-** points to a single nul-terminated string. Return non-zero if zStr
-** is equal, according to strcmp(), to any of the strings in the array.
-** Otherwise, return zero.
-*/
-static int str_in_array(const char *zStr, const char *const *azArray){
- int i;
- for(i=0; azArray[i]; i++){
- if( 0==strcmp(zStr, azArray[i]) ) return 1;
- }
- return 0;
-}
-
-/*
-** 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.
-**
-** The indenting rules are:
-**
-** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
-** all opcodes that occur between the p2 jump destination and the opcode
-** itself by 2 spaces.
-**
-** * For each "Goto", if the jump destination is earlier in the program
-** and ends on one of:
-** Yield SeekGt SeekLt RowSetRead Rewind
-** or if the P1 parameter is one instead of zero,
-** then indent all opcodes between the earlier instruction
-** and "Goto" by 2 spaces.
-*/
-static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
- const char *zSql; /* The text of the SQL statement */
- const char *z; /* Used to check if this is an EXPLAIN */
- int *abYield = 0; /* True if op is an OP_Yield */
- int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
- int iOp; /* Index of operation in p->aiIndent[] */
-
- const char *const azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
- "NextIfOpen", "PrevIfOpen", 0 };
- const char *const azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
- "Rewind", 0 };
- const char *const azGoto[] = { "Goto", 0 };
-
- /* Try to figure out if this is really an EXPLAIN statement. If this
- ** cannot be verified, return early. */
- if( sqlite3_column_count(pSql)!=8 ){
- p->cMode = p->mode;
- return;
- }
- zSql = sqlite3_sql(pSql);
- if( zSql==0 ) return;
- for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
- if( sqlite3_strnicmp(z, "explain", 7) ){
- p->cMode = p->mode;
- return;
- }
-
- for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
- int i;
- int iAddr = sqlite3_column_int(pSql, 0);
- const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
-
- /* Set p2 to the P2 field of the current opcode. Then, assuming that
- ** p2 is an instruction address, set variable p2op to the index of that
- ** instruction in the aiIndent[] array. p2 and p2op may be different if
- ** the current instruction is part of a sub-program generated by an
- ** SQL trigger or foreign key. */
- int p2 = sqlite3_column_int(pSql, 3);
- int p2op = (p2 + (iOp-iAddr));
-
- /* Grow the p->aiIndent array as required */
- if( iOp>=nAlloc ){
- if( iOp==0 ){
- /* Do further verfication that this is explain output. Abort if
- ** it is not */
- static const char *const explainCols[] = {
- "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
- int jj;
- for(jj=0; jj<ArraySize(explainCols); jj++){
- if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
- p->cMode = p->mode;
- sqlite3_reset(pSql);
- return;
- }
- }
- }
- nAlloc += 100;
- p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
- abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
- }
- abYield[iOp] = str_in_array(zOp, azYield);
- p->aiIndent[iOp] = 0;
- p->nIndent = iOp+1;
-
- if( str_in_array(zOp, azNext) ){
- for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
- }
- if( str_in_array(zOp, azGoto) && p2op<p->nIndent
- && (abYield[p2op] || sqlite3_column_int(pSql, 2))
- ){
- for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
- }
- }
-
- p->iIndent = 0;
- sqlite3_free(abYield);
- sqlite3_reset(pSql);
-}
-
-/*
-** Free the array allocated by explain_data_prepare().
-*/
-static void explain_data_delete(ShellState *p){
- sqlite3_free(p->aiIndent);
- p->aiIndent = 0;
- p->nIndent = 0;
- p->iIndent = 0;
-}
-
-/*
-** 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
-** and callback data argument.
-*/
-static int shell_exec(
- sqlite3 *db, /* An open database */
- const char *zSql, /* SQL to be evaluated */
- int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
- /* (not the same as sqlite3_exec) */
- ShellState *pArg, /* Pointer to ShellState */
- char **pzErrMsg /* Error msg written here */
-){
- sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
- int rc = SQLITE_OK; /* Return Code */
- int rc2;
- const char *zLeftover; /* Tail of unprocessed SQL */
-
- if( pzErrMsg ){
- *pzErrMsg = NULL;
- }
-
- while( zSql[0] && (SQLITE_OK == rc) ){
- static const char *zStmtSql;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
- if( SQLITE_OK != rc ){
- if( pzErrMsg ){
- *pzErrMsg = save_err_msg(db);
- }
- }else{
- if( !pStmt ){
- /* this happens for a comment or white-space */
- zSql = zLeftover;
- while( IsSpace(zSql[0]) ) zSql++;
- continue;
- }
- zStmtSql = sqlite3_sql(pStmt);
- if( zStmtSql==0 ) zStmtSql = "";
- while( IsSpace(zStmtSql[0]) ) zStmtSql++;
-
- /* save off the prepared statment handle and reset row count */
- if( pArg ){
- pArg->pStmt = pStmt;
- pArg->cnt = 0;
- }
-
- /* echo the sql statement if echo on */
- if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
- utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
- }
-
- /* Show the EXPLAIN QUERY PLAN if .eqp is on */
- if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
- sqlite3_stmt *pExplain;
- 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 ){
- raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
- raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
- raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
- utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
- }
- }
- 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%", 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 ){
- explain_data_prepare(pArg, pStmt);
- }
- }
-
- exec_prepared_stmt(pArg, pStmt, xCallback);
- explain_data_delete(pArg);
-
- /* print usage stats if stats on */
- if( pArg && pArg->statsOn ){
- display_stats(db, pArg, 0);
- }
-
- /* print loop-counters if required */
- if( pArg && pArg->scanstatsOn ){
- display_scanstats(db, pArg);
- }
-
- /* Finalize the statement just executed. If this fails, save a
- ** copy of the error message. Otherwise, set zSql to point to the
- ** next statement to execute. */
- rc2 = sqlite3_finalize(pStmt);
- if( rc!=SQLITE_NOMEM ) rc = rc2;
- if( rc==SQLITE_OK ){
- zSql = zLeftover;
- while( IsSpace(zSql[0]) ) zSql++;
- }else if( pzErrMsg ){
- *pzErrMsg = save_err_msg(db);
- }
-
- /* clear saved stmt handle */
- if( pArg ){
- pArg->pStmt = NULL;
- }
- }
- } /* end while */
-
- return rc;
-}
-
-/*
-** Release memory previously allocated by tableColumnList().
-*/
-static void freeColumnList(char **azCol){
- int i;
- for(i=1; azCol[i]; i++){
- sqlite3_free(azCol[i]);
- }
- /* azCol[0] is a static string */
- sqlite3_free(azCol);
-}
-
-/*
-** Return a list of pointers to strings which are the names of all
-** columns in table zTab. The memory to hold the names is dynamically
-** allocated and must be released by the caller using a subsequent call
-** to freeColumnList().
-**
-** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
-** value that needs to be preserved, then azCol[0] is filled in with the
-** name of the rowid column.
-**
-** The first regular column in the table is azCol[1]. The list is terminated
-** by an entry with azCol[i]==0.
-*/
-static char **tableColumnList(ShellState *p, const char *zTab){
- char **azCol = 0;
- sqlite3_stmt *pStmt;
- char *zSql;
- int nCol = 0;
- int nAlloc = 0;
- int nPK = 0; /* Number of PRIMARY KEY columns seen */
- int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
- int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
- int rc;
-
- zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc ) return 0;
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- if( nCol>=nAlloc-2 ){
- nAlloc = nAlloc*2 + nCol + 10;
- azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
- if( azCol==0 ){
- raw_printf(stderr, "Error: out of memory\n");
- exit(1);
- }
- }
- azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
- if( sqlite3_column_int(pStmt, 5) ){
- nPK++;
- if( nPK==1
- && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
- "INTEGER")==0
- ){
- isIPK = 1;
- }else{
- isIPK = 0;
- }
- }
- }
- sqlite3_finalize(pStmt);
- if( azCol==0 ) return 0;
- azCol[0] = 0;
- azCol[nCol+1] = 0;
-
- /* The decision of whether or not a rowid really needs to be preserved
- ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
- ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
- ** rowids on tables where the rowid is inaccessible because there are other
- ** columns in the table named "rowid", "_rowid_", and "oid".
- */
- if( preserveRowid && isIPK ){
- /* If a single PRIMARY KEY column with type INTEGER was seen, then it
- ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
- ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
- ** ROWID aliases. To distinguish these cases, check to see if
- ** there is a "pk" entry in "PRAGMA index_list". There will be
- ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
- */
- zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
- " WHERE origin='pk'", zTab);
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc ){
- freeColumnList(azCol);
- return 0;
- }
- rc = sqlite3_step(pStmt);
- sqlite3_finalize(pStmt);
- preserveRowid = rc==SQLITE_ROW;
- }
- if( preserveRowid ){
- /* Only preserve the rowid if we can find a name to use for the
- ** rowid */
- static char *azRowid[] = { "rowid", "_rowid_", "oid" };
- int i, j;
- for(j=0; j<3; j++){
- for(i=1; i<=nCol; i++){
- if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
- }
- if( i>nCol ){
- /* At this point, we know that azRowid[j] is not the name of any
- ** ordinary column in the table. Verify that azRowid[j] is a valid
- ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
- ** tables will fail this last check */
- rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
- if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
- break;
- }
- }
- }
- return azCol;
-}
-
-/*
-** Toggle the reverse_unordered_selects setting.
-*/
-static void toggleSelectOrder(sqlite3 *db){
- sqlite3_stmt *pStmt = 0;
- int iSetting = 0;
- char zStmt[100];
- sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
- iSetting = sqlite3_column_int(pStmt, 0);
- }
- sqlite3_finalize(pStmt);
- sqlite3_snprintf(sizeof(zStmt), zStmt,
- "PRAGMA reverse_unordered_selects(%d)", !iSetting);
- sqlite3_exec(db, zStmt, 0, 0, 0);
-}
-
-/*
-** This is a different callback routine used for dumping the database.
-** Each row received by this callback consists of a table name,
-** the table type ("index" or "table") and SQL to create the table.
-** This routine should print text sufficient to recreate the table.
-*/
-static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
- int rc;
- const char *zTable;
- const char *zType;
- const char *zSql;
- ShellState *p = (ShellState *)pArg;
-
- UNUSED_PARAMETER(azNotUsed);
- if( nArg!=3 || azArg==0 ) return 0;
- zTable = azArg[0];
- zType = azArg[1];
- zSql = azArg[2];
-
- if( strcmp(zTable, "sqlite_sequence")==0 ){
- raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
- }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
- raw_printf(p->out, "ANALYZE sqlite_master;\n");
- }else if( strncmp(zTable, "sqlite_", 7)==0 ){
- return 0;
- }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
- char *zIns;
- if( !p->writableSchema ){
- raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
- p->writableSchema = 1;
- }
- zIns = sqlite3_mprintf(
- "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
- "VALUES('table','%q','%q',0,'%q');",
- zTable, zTable, zSql);
- utf8_printf(p->out, "%s\n", zIns);
- sqlite3_free(zIns);
- return 0;
- }else{
- printSchemaLine(p->out, zSql, ";\n");
- }
-
- if( strcmp(zType, "table")==0 ){
- ShellText sSelect;
- ShellText sTable;
- char **azCol;
- int i;
- char *savedDestTable;
- int savedMode;
-
- azCol = tableColumnList(p, zTable);
- if( azCol==0 ){
- p->nErr++;
- return 0;
- }
-
- /* Always quote the table name, even if it appears to be pure ascii,
- ** in case it is a keyword. Ex: INSERT INTO "table" ... */
- initText(&sTable);
- appendText(&sTable, zTable, quoteChar(zTable));
- /* If preserving the rowid, add a column list after the table name.
- ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
- ** instead of the usual "INSERT INTO tab VALUES(...)".
- */
- if( azCol[0] ){
- appendText(&sTable, "(", 0);
- appendText(&sTable, azCol[0], 0);
- for(i=1; azCol[i]; i++){
- appendText(&sTable, ",", 0);
- appendText(&sTable, azCol[i], quoteChar(azCol[i]));
- }
- appendText(&sTable, ")", 0);
- }
-
- /* Build an appropriate SELECT statement */
- initText(&sSelect);
- appendText(&sSelect, "SELECT ", 0);
- if( azCol[0] ){
- appendText(&sSelect, azCol[0], 0);
- appendText(&sSelect, ",", 0);
- }
- for(i=1; azCol[i]; i++){
- appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
- if( azCol[i+1] ){
- appendText(&sSelect, ",", 0);
- }
- }
- freeColumnList(azCol);
- appendText(&sSelect, " FROM ", 0);
- appendText(&sSelect, zTable, quoteChar(zTable));
-
- savedDestTable = p->zDestTable;
- savedMode = p->mode;
- p->zDestTable = sTable.z;
- p->mode = p->cMode = MODE_Insert;
- rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0);
- if( (rc&0xff)==SQLITE_CORRUPT ){
- raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
- toggleSelectOrder(p->db);
- shell_exec(p->db, sSelect.z, shell_callback, p, 0);
- toggleSelectOrder(p->db);
- }
- p->zDestTable = savedDestTable;
- p->mode = savedMode;
- freeText(&sTable);
- freeText(&sSelect);
- if( rc ) p->nErr++;
- }
- return 0;
-}
-
-/*
-** Run zQuery. Use dump_callback() as the callback routine so that
-** the contents of the query are output as SQL statements.
-**
-** If we get a SQLITE_CORRUPT error, rerun the query after appending
-** "ORDER BY rowid DESC" to the end.
-*/
-static int run_schema_dump_query(
- ShellState *p,
- const char *zQuery
-){
- int rc;
- char *zErr = 0;
- rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
- if( rc==SQLITE_CORRUPT ){
- char *zQ2;
- int len = strlen30(zQuery);
- raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
- if( zErr ){
- utf8_printf(p->out, "/****** %s ******/\n", zErr);
- sqlite3_free(zErr);
- zErr = 0;
- }
- zQ2 = malloc( len+100 );
- if( zQ2==0 ) return rc;
- sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
- rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
- if( rc ){
- utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
- }else{
- rc = SQLITE_CORRUPT;
- }
- sqlite3_free(zErr);
- free(zQ2);
- }
- return rc;
-}
-
-/*
-** Text of a help message
-*/
-static char zHelp[] =
-#ifndef SQLITE_OMIT_AUTHORIZATION
- ".auth ON|OFF Show authorizer callbacks\n"
-#endif
- ".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"
- ".cd DIRECTORY Change the working directory to DIRECTORY\n"
- ".changes on|off Show number of rows changed by SQL\n"
- ".check GLOB Fail if output since .testcase does not match\n"
- ".clone NEWDB Clone data into NEWDB from the existing database\n"
- ".databases List names and files of attached databases\n"
- ".dbinfo ?DB? Show status information about the database\n"
- ".dump ?TABLE? ... Dump the database in an SQL text format\n"
- " If TABLE specified, only dump tables matching\n"
- " LIKE pattern TABLE.\n"
- ".echo on|off Turn command echo on or off\n"
- ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
- ".exit Exit this program\n"
-/* Because explain mode comes on automatically now, the ".explain" mode
-** is removed from the help screen. It is still supported for legacy, however */
-/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\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"
-#ifndef SQLITE_OMIT_TEST_CONTROL
- ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
-#endif
- ".indexes ?TABLE? Show names of all indexes\n"
- " If TABLE specified, only show indexes for tables\n"
- " matching LIKE pattern TABLE.\n"
-#ifdef SQLITE_ENABLE_IOTRACE
- ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
-#endif
- ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
- ".lint OPTIONS Report potential schema issues. Options:\n"
- " fkey-indexes Find missing foreign key indexes\n"
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
- ".load FILE ?ENTRY? Load an extension library\n"
-#endif
- ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
- ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
- " ascii Columns/rows delimited by 0x1F and 0x1E\n"
- " csv Comma-separated values\n"
- " column Left-aligned columns. (See .width)\n"
- " html HTML <table> code\n"
- " insert SQL insert statements for TABLE\n"
- " line One value per line\n"
- " list Values delimited by \"|\"\n"
- " quote Escape answers as for SQL\n"
- " tabs Tab-separated values\n"
- " tcl TCL list elements\n"
- ".nullvalue STRING Use STRING in place of NULL values\n"
- ".once FILENAME Output for the next SQL command only to FILENAME\n"
- ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
- " The --new option starts with an empty file\n"
- ".output ?FILENAME? Send output to FILENAME or stdout\n"
- ".print STRING... Print literal STRING\n"
- ".prompt MAIN CONTINUE Replace the standard prompts\n"
- ".quit Exit this program\n"
- ".read FILENAME Execute SQL in FILENAME\n"
- ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
- ".save FILE Write in-memory database into FILE\n"
- ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
- ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
- " Add --indent for pretty-printing\n"
-#ifdef SQLITE_DEBUG
- ".selftest ?--init? Run tests defined in the SELFTEST table\n"
-#endif
- ".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
- ".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
- ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
- ".show Show the current values for various settings\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"
- " LIKE pattern TABLE.\n"
- ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
- ".timeout MS Try opening locked tables for MS milliseconds\n"
- ".timer on|off Turn SQL timer on or off\n"
- ".trace FILE|off Output each SQL statement as it is run\n"
- ".vfsinfo ?AUX? Information about the top-level VFS\n"
- ".vfslist List all available VFSes\n"
- ".vfsname ?AUX? Print the name of the VFS stack\n"
- ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
- " 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);
-
-/*
-** Read the content of file zName into memory obtained from sqlite3_malloc64()
-** and return a pointer to the buffer. The caller is responsible for freeing
-** the memory.
-**
-** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
-** read.
-**
-** For convenience, a nul-terminator byte is always appended to the data read
-** from the file before the buffer is returned. This byte is not included in
-** the final value of (*pnByte), if applicable.
-**
-** NULL is returned if any error is encountered. The final value of *pnByte
-** is undefined in this case.
-*/
-static char *readFile(const char *zName, size_t *pnByte){
- FILE *in = fopen(zName, "rb");
- size_t nIn;
- size_t nRead;
- char *pBuf;
- if( in==0 ) return 0;
- fseek(in, 0, SEEK_END);
- nIn = ftell(in);
- rewind(in);
- pBuf = sqlite3_malloc( nIn+1 );
- if( pBuf==0 ) return 0;
- nRead = fread(pBuf, nIn, 1, in);
- fclose(in);
- if( nRead!=1 ){
- sqlite3_free(pBuf);
- return 0;
- }
- pBuf[nIn] = 0;
- if( pnByte ) *pnByte = nIn;
- return pBuf;
-}
-
-#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.
-*/
-static void open_db(ShellState *p, int keepAlive){
- if( p->db==0 ){
- sqlite3_initialize();
- sqlite3_open(p->zDbFilename, &p->db);
- globalDb = p->db;
- if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
- utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
- p->zDbFilename, sqlite3_errmsg(p->db));
- if( keepAlive ) return;
- exit(1);
- }
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
- sqlite3_enable_load_extension(p->db, 1);
-#endif
- sqlite3_fileio_init(p->db, 0, 0);
- sqlite3_shathree_init(p->db, 0, 0);
- sqlite3_completion_init(p->db, 0, 0);
- sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
- shellAddSchemaName, 0, 0);
- }
-}
-
-#if HAVE_READLINE || HAVE_EDITLINE
-/*
-** Readline completion callbacks
-*/
-static char *readline_completion_generator(const char *text, int state){
- static sqlite3_stmt *pStmt = 0;
- char *zRet;
- if( state==0 ){
- char *zSql;
- sqlite3_finalize(pStmt);
- zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
- " FROM completion(%Q) ORDER BY 1", text);
- sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- }
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
- zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
- }else{
- sqlite3_finalize(pStmt);
- pStmt = 0;
- zRet = 0;
- }
- return zRet;
-}
-static char **readline_completion(const char *zText, int iStart, int iEnd){
- rl_attempted_completion_over = 1;
- return rl_completion_matches(zText, readline_completion_generator);
-}
-
-#elif HAVE_LINENOISE
-/*
-** Linenoise completion callback
-*/
-static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
- int nLine = (int)strlen(zLine);
- int i, iStart;
- sqlite3_stmt *pStmt = 0;
- char *zSql;
- char zBuf[1000];
-
- if( nLine>sizeof(zBuf)-30 ) return;
- if( zLine[0]=='.' ) return;
- for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
- if( i==nLine-1 ) return;
- iStart = i+1;
- memcpy(zBuf, zLine, iStart);
- zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
- " FROM completion(%Q,%Q) ORDER BY 1",
- &zLine[iStart], zLine);
- sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
- int nCompletion = sqlite3_column_bytes(pStmt, 0);
- if( iStart+nCompletion < sizeof(zBuf)-1 ){
- memcpy(zBuf+iStart, zCompletion, nCompletion+1);
- linenoiseAddCompletion(lc, zBuf);
- }
- }
- sqlite3_finalize(pStmt);
-}
-#endif
-
-/*
-** Do C-language style dequoting.
-**
-** \a -> alarm
-** \b -> backspace
-** \t -> tab
-** \n -> newline
-** \v -> vertical tab
-** \f -> form feed
-** \r -> carriage return
-** \s -> space
-** \" -> "
-** \' -> '
-** \\ -> backslash
-** \NNN -> ascii character NNN in octal
-*/
-static void resolve_backslashes(char *z){
- int i, j;
- char c;
- while( *z && *z!='\\' ) z++;
- for(i=j=0; (c = z[i])!=0; i++, j++){
- if( c=='\\' && z[i+1]!=0 ){
- c = z[++i];
- if( c=='a' ){
- c = '\a';
- }else if( c=='b' ){
- c = '\b';
- }else if( c=='t' ){
- c = '\t';
- }else if( c=='n' ){
- c = '\n';
- }else if( c=='v' ){
- c = '\v';
- }else if( c=='f' ){
- c = '\f';
- }else if( c=='r' ){
- c = '\r';
- }else if( c=='"' ){
- c = '"';
- }else if( c=='\'' ){
- c = '\'';
- }else if( c=='\\' ){
- c = '\\';
- }else if( c>='0' && c<='7' ){
- c -= '0';
- if( z[i+1]>='0' && z[i+1]<='7' ){
- i++;
- c = (c<<3) + z[i] - '0';
- if( z[i+1]>='0' && z[i+1]<='7' ){
- i++;
- c = (c<<3) + z[i] - '0';
- }
- }
- }
- }
- z[j] = c;
- }
- if( j<i ) z[j] = 0;
-}
-
-/*
-** Return the value of a hexadecimal digit. Return -1 if the input
-** is not a hex digit.
-*/
-static int hexDigitValue(char c){
- if( c>='0' && c<='9' ) return c - '0';
- if( c>='a' && c<='f' ) return c - 'a' + 10;
- if( c>='A' && c<='F' ) return c - 'A' + 10;
- return -1;
-}
-
-/*
-** Interpret zArg as an integer value, possibly with suffixes.
-*/
-static sqlite3_int64 integerValue(const char *zArg){
- sqlite3_int64 v = 0;
- static const struct { char zSuffix[4]; int iMult; } aMult[] = {
- { "KiB", 1024 },
- { "MiB", 1024*1024 },
- { "GiB", 1024*1024*1024 },
- { "KB", 1000 },
- { "MB", 1000000 },
- { "GB", 1000000000 },
- { "K", 1000 },
- { "M", 1000000 },
- { "G", 1000000000 },
- };
- int i;
- int isNeg = 0;
- if( zArg[0]=='-' ){
- isNeg = 1;
- zArg++;
- }else if( zArg[0]=='+' ){
- zArg++;
- }
- if( zArg[0]=='0' && zArg[1]=='x' ){
- int x;
- zArg += 2;
- while( (x = hexDigitValue(zArg[0]))>=0 ){
- v = (v<<4) + x;
- zArg++;
- }
- }else{
- while( IsDigit(zArg[0]) ){
- v = v*10 + zArg[0] - '0';
- zArg++;
- }
- }
- for(i=0; i<ArraySize(aMult); i++){
- if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
- v *= aMult[i].iMult;
- break;
- }
- }
- return isNeg? -v : v;
-}
-
-/*
-** 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(const char *zArg){
- int i;
- if( zArg[0]=='0' && zArg[1]=='x' ){
- for(i=2; hexDigitValue(zArg[i])>=0; i++){}
- }else{
- for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
- }
- if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
- if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
- return 1;
- }
- if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
- return 0;
- }
- utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
- zArg);
- return 0;
-}
-
-/*
-** Set or clear a shell flag according to a boolean value.
-*/
-static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
- if( booleanValue(zArg) ){
- ShellSetFlag(p, mFlag);
- }else{
- ShellClearFlag(p, mFlag);
- }
-}
-
-/*
-** Close an output file, assuming it is not stderr or stdout
-*/
-static void output_file_close(FILE *f){
- if( f && f!=stdout && f!=stderr ) fclose(f);
-}
-
-/*
-** Try to open an output file. The names "stdout" and "stderr" are
-** recognized and do the right thing. NULL is returned if the output
-** filename is "off".
-*/
-static FILE *output_file_open(const char *zFile){
- FILE *f;
- if( strcmp(zFile,"stdout")==0 ){
- f = stdout;
- }else if( strcmp(zFile, "stderr")==0 ){
- f = stderr;
- }else if( strcmp(zFile, "off")==0 ){
- f = 0;
- }else{
- f = fopen(zFile, "wb");
- if( f==0 ){
- utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
- }
- }
- return f;
-}
-
-#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
-/*
-** A routine for handling output from sqlite3_trace().
-*/
-static int sql_trace_callback(
- unsigned mType,
- void *pArg,
- void *pP,
- void *pX
-){
- FILE *f = (FILE*)pArg;
- UNUSED_PARAMETER(mType);
- UNUSED_PARAMETER(pP);
- if( f ){
- const char *z = (const char*)pX;
- int i = (int)strlen(z);
- while( i>0 && z[i-1]==';' ){ i--; }
- utf8_printf(f, "%.*s;\n", i, z);
- }
- return 0;
-}
-#endif
-
-/*
-** A no-op routine that runs with the ".breakpoint" doc-command. This is
-** a useful spot to set a debugger breakpoint.
-*/
-static void test_breakpoint(void){
- static int nCall = 0;
- nCall++;
-}
-
-/*
-** An object used to read a CSV and other files for import.
-*/
-typedef struct ImportCtx ImportCtx;
-struct ImportCtx {
- const char *zFile; /* Name of the input file */
- FILE *in; /* Read the CSV text from this input stream */
- char *z; /* Accumulated text for a field */
- int n; /* Number of bytes in z */
- int nAlloc; /* Space allocated for z[] */
- int nLine; /* Current line number */
- int bNotFirst; /* True if one or more bytes already read */
- int cTerm; /* Character that terminated the most recent field */
- int cColSep; /* The column separator character. (Usually ",") */
- int cRowSep; /* The row separator character. (Usually "\n") */
-};
-
-/* Append a single byte to z[] */
-static void import_append_char(ImportCtx *p, int c){
- if( p->n+1>=p->nAlloc ){
- p->nAlloc += p->nAlloc + 100;
- p->z = sqlite3_realloc(p->z, p->nAlloc);
- if( p->z==0 ){
- raw_printf(stderr, "out of memory\n");
- exit(1);
- }
- }
- p->z[p->n++] = (char)c;
-}
-
-/* Read a single field of CSV text. Compatible with rfc4180 and extended
-** with the option of having a separator other than ",".
-**
-** + Input comes from p->in.
-** + Store results in p->z of length p->n. Space to hold p->z comes
-** from sqlite3_malloc64().
-** + Use p->cSep as the column separator. The default is ",".
-** + Use p->rSep as the row separator. The default is "\n".
-** + Keep track of the line number in p->nLine.
-** + Store the character that terminates the field in p->cTerm. Store
-** EOF on end-of-file.
-** + Report syntax errors on stderr
-*/
-static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
- int c;
- int cSep = p->cColSep;
- int rSep = p->cRowSep;
- p->n = 0;
- c = fgetc(p->in);
- if( c==EOF || seenInterrupt ){
- p->cTerm = EOF;
- return 0;
- }
- if( c=='"' ){
- int pc, ppc;
- int startLine = p->nLine;
- int cQuote = c;
- pc = ppc = 0;
- while( 1 ){
- c = fgetc(p->in);
- if( c==rSep ) p->nLine++;
- if( c==cQuote ){
- if( pc==cQuote ){
- pc = 0;
- continue;
- }
- }
- if( (c==cSep && pc==cQuote)
- || (c==rSep && pc==cQuote)
- || (c==rSep && pc=='\r' && ppc==cQuote)
- || (c==EOF && pc==cQuote)
- ){
- do{ p->n--; }while( p->z[p->n]!=cQuote );
- p->cTerm = c;
- break;
- }
- if( pc==cQuote && c!='\r' ){
- utf8_printf(stderr, "%s:%d: unescaped %c character\n",
- p->zFile, p->nLine, cQuote);
- }
- if( c==EOF ){
- utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
- p->zFile, startLine, cQuote);
- p->cTerm = c;
- break;
- }
- import_append_char(p, c);
- ppc = pc;
- pc = c;
- }
- }else{
- /* If this is the first field being parsed and it begins with the
- ** UTF-8 BOM (0xEF BB BF) then skip the BOM */
- if( (c&0xff)==0xef && p->bNotFirst==0 ){
- import_append_char(p, c);
- c = fgetc(p->in);
- if( (c&0xff)==0xbb ){
- import_append_char(p, c);
- c = fgetc(p->in);
- if( (c&0xff)==0xbf ){
- p->bNotFirst = 1;
- p->n = 0;
- return csv_read_one_field(p);
- }
- }
- }
- while( c!=EOF && c!=cSep && c!=rSep ){
- import_append_char(p, c);
- c = fgetc(p->in);
- }
- if( c==rSep ){
- p->nLine++;
- if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
- }
- p->cTerm = c;
- }
- if( p->z ) p->z[p->n] = 0;
- p->bNotFirst = 1;
- return p->z;
-}
-
-/* Read a single field of ASCII delimited text.
-**
-** + Input comes from p->in.
-** + Store results in p->z of length p->n. Space to hold p->z comes
-** from sqlite3_malloc64().
-** + Use p->cSep as the column separator. The default is "\x1F".
-** + Use p->rSep as the row separator. The default is "\x1E".
-** + Keep track of the row number in p->nLine.
-** + Store the character that terminates the field in p->cTerm. Store
-** EOF on end-of-file.
-** + Report syntax errors on stderr
-*/
-static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
- int c;
- int cSep = p->cColSep;
- int rSep = p->cRowSep;
- p->n = 0;
- c = fgetc(p->in);
- if( c==EOF || seenInterrupt ){
- p->cTerm = EOF;
- return 0;
- }
- while( c!=EOF && c!=cSep && c!=rSep ){
- import_append_char(p, c);
- c = fgetc(p->in);
- }
- if( c==rSep ){
- p->nLine++;
- }
- p->cTerm = c;
- if( p->z ) p->z[p->n] = 0;
- return p->z;
-}
-
-/*
-** Try to transfer data for table zTable. If an error is seen while
-** moving forward, try to go backwards. The backwards movement won't
-** work for WITHOUT ROWID tables.
-*/
-static void tryToCloneData(
- ShellState *p,
- sqlite3 *newDb,
- const char *zTable
-){
- sqlite3_stmt *pQuery = 0;
- sqlite3_stmt *pInsert = 0;
- char *zQuery = 0;
- char *zInsert = 0;
- int rc;
- int i, j, n;
- int nTable = (int)strlen(zTable);
- int k = 0;
- int cnt = 0;
- const int spinRate = 10000;
-
- zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
- rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
- if( rc ){
- utf8_printf(stderr, "Error %d: %s on [%s]\n",
- sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
- zQuery);
- goto end_data_xfer;
- }
- n = sqlite3_column_count(pQuery);
- zInsert = sqlite3_malloc(200 + nTable + n*3);
- if( zInsert==0 ){
- raw_printf(stderr, "out of memory\n");
- goto end_data_xfer;
- }
- sqlite3_snprintf(200+nTable,zInsert,
- "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
- i = (int)strlen(zInsert);
- for(j=1; j<n; j++){
- memcpy(zInsert+i, ",?", 2);
- i += 2;
- }
- memcpy(zInsert+i, ");", 3);
- rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
- if( rc ){
- utf8_printf(stderr, "Error %d: %s on [%s]\n",
- sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
- zQuery);
- goto end_data_xfer;
- }
- for(k=0; k<2; k++){
- while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
- for(i=0; i<n; i++){
- switch( sqlite3_column_type(pQuery, i) ){
- case SQLITE_NULL: {
- sqlite3_bind_null(pInsert, i+1);
- break;
- }
- case SQLITE_INTEGER: {
- sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
- break;
- }
- case SQLITE_FLOAT: {
- sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
- break;
- }
- case SQLITE_TEXT: {
- sqlite3_bind_text(pInsert, i+1,
- (const char*)sqlite3_column_text(pQuery,i),
- -1, SQLITE_STATIC);
- break;
- }
- case SQLITE_BLOB: {
- sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
- sqlite3_column_bytes(pQuery,i),
- SQLITE_STATIC);
- break;
- }
- }
- } /* End for */
- rc = sqlite3_step(pInsert);
- if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
- utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
- sqlite3_errmsg(newDb));
- }
- sqlite3_reset(pInsert);
- cnt++;
- if( (cnt%spinRate)==0 ){
- printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
- fflush(stdout);
- }
- } /* End while */
- if( rc==SQLITE_DONE ) break;
- sqlite3_finalize(pQuery);
- sqlite3_free(zQuery);
- zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
- zTable);
- rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
- if( rc ){
- utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
- break;
- }
- } /* End for(k=0...) */
-
-end_data_xfer:
- sqlite3_finalize(pQuery);
- sqlite3_finalize(pInsert);
- sqlite3_free(zQuery);
- sqlite3_free(zInsert);
-}
-
-
-/*
-** Try to transfer all rows of the schema that match zWhere. For
-** each row, invoke xForEach() on the object defined by that row.
-** If an error is encountered while moving forward through the
-** sqlite_master table, try again moving backwards.
-*/
-static void tryToCloneSchema(
- ShellState *p,
- sqlite3 *newDb,
- const char *zWhere,
- void (*xForEach)(ShellState*,sqlite3*,const char*)
-){
- sqlite3_stmt *pQuery = 0;
- char *zQuery = 0;
- int rc;
- const unsigned char *zName;
- const unsigned char *zSql;
- char *zErrMsg = 0;
-
- zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
- " WHERE %s", zWhere);
- rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
- if( rc ){
- utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
- sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
- zQuery);
- goto end_schema_xfer;
- }
- while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
- zName = sqlite3_column_text(pQuery, 0);
- zSql = sqlite3_column_text(pQuery, 1);
- printf("%s... ", zName); fflush(stdout);
- sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
- if( zErrMsg ){
- utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
- sqlite3_free(zErrMsg);
- zErrMsg = 0;
- }
- if( xForEach ){
- xForEach(p, newDb, (const char*)zName);
- }
- printf("done\n");
- }
- if( rc!=SQLITE_DONE ){
- sqlite3_finalize(pQuery);
- sqlite3_free(zQuery);
- zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
- " WHERE %s ORDER BY rowid DESC", zWhere);
- rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
- if( rc ){
- utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
- sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
- zQuery);
- goto end_schema_xfer;
- }
- while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
- zName = sqlite3_column_text(pQuery, 0);
- zSql = sqlite3_column_text(pQuery, 1);
- printf("%s... ", zName); fflush(stdout);
- sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
- if( zErrMsg ){
- utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
- sqlite3_free(zErrMsg);
- zErrMsg = 0;
- }
- if( xForEach ){
- xForEach(p, newDb, (const char*)zName);
- }
- printf("done\n");
- }
- }
-end_schema_xfer:
- sqlite3_finalize(pQuery);
- sqlite3_free(zQuery);
-}
-
-/*
-** Open a new database file named "zNewDb". Try to recover as much information
-** as possible out of the main database (which might be corrupt) and write it
-** into zNewDb.
-*/
-static void tryToClone(ShellState *p, const char *zNewDb){
- int rc;
- sqlite3 *newDb = 0;
- if( access(zNewDb,0)==0 ){
- utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
- return;
- }
- rc = sqlite3_open(zNewDb, &newDb);
- if( rc ){
- utf8_printf(stderr, "Cannot create output database: %s\n",
- sqlite3_errmsg(newDb));
- }else{
- sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
- sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
- tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
- tryToCloneSchema(p, newDb, "type!='table'", 0);
- sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
- sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
- }
- sqlite3_close(newDb);
-}
-
-/*
-** Change the output file back to stdout
-*/
-static void output_reset(ShellState *p){
- if( p->outfile[0]=='|' ){
-#ifndef SQLITE_OMIT_POPEN
- pclose(p->out);
-#endif
- }else{
- output_file_close(p->out);
- }
- p->outfile[0] = 0;
- p->out = stdout;
-}
-
-/*
-** Run an SQL command and return the single integer result.
-*/
-static int db_int(ShellState *p, const char *zSql){
- sqlite3_stmt *pStmt;
- int res = 0;
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
- res = sqlite3_column_int(pStmt,0);
- }
- sqlite3_finalize(pStmt);
- return res;
-}
-
-/*
-** Convert a 2-byte or 4-byte big-endian integer into a native integer
-*/
-static unsigned int get2byteInt(unsigned char *a){
- return (a[0]<<8) + a[1];
-}
-static unsigned int get4byteInt(unsigned char *a){
- return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
-}
-
-/*
-** Implementation of the ".info" command.
-**
-** Return 1 on error, 2 to exit, and 0 otherwise.
-*/
-static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
- static const struct { const char *zName; int ofst; } aField[] = {
- { "file change counter:", 24 },
- { "database page count:", 28 },
- { "freelist page count:", 36 },
- { "schema cookie:", 40 },
- { "schema format:", 44 },
- { "default cache size:", 48 },
- { "autovacuum top root:", 52 },
- { "incremental vacuum:", 64 },
- { "text encoding:", 56 },
- { "user version:", 60 },
- { "application id:", 68 },
- { "software version:", 96 },
- };
- static const struct { const char *zName; const char *zSql; } aQuery[] = {
- { "number of tables:",
- "SELECT count(*) FROM %s WHERE type='table'" },
- { "number of indexes:",
- "SELECT count(*) FROM %s WHERE type='index'" },
- { "number of triggers:",
- "SELECT count(*) FROM %s WHERE type='trigger'" },
- { "number of views:",
- "SELECT count(*) FROM %s WHERE type='view'" },
- { "schema size:",
- "SELECT total(length(sql)) FROM %s" },
- };
- int i;
- char *zSchemaTab;
- char *zDb = nArg>=2 ? azArg[1] : "main";
- sqlite3_stmt *pStmt = 0;
- unsigned char aHdr[100];
- open_db(p, 0);
- if( p->db==0 ) return 1;
- sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
- -1, &pStmt, 0);
- sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
- if( sqlite3_step(pStmt)==SQLITE_ROW
- && sqlite3_column_bytes(pStmt,0)>100
- ){
- memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
- sqlite3_finalize(pStmt);
- }else{
- raw_printf(stderr, "unable to read database header\n");
- sqlite3_finalize(pStmt);
- return 1;
- }
- i = get2byteInt(aHdr+16);
- if( i==1 ) i = 65536;
- utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
- utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
- utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
- utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
- for(i=0; i<ArraySize(aField); i++){
- int ofst = aField[i].ofst;
- unsigned int val = get4byteInt(aHdr + ofst);
- 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)");
- }
- }
- raw_printf(p->out, "\n");
- }
- if( zDb==0 ){
- zSchemaTab = sqlite3_mprintf("main.sqlite_master");
- }else if( strcmp(zDb,"temp")==0 ){
- zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
- }else{
- zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
- }
- for(i=0; i<ArraySize(aQuery); i++){
- char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
- int val = db_int(p, zSql);
- sqlite3_free(zSql);
- utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
- }
- sqlite3_free(zSchemaTab);
- return 0;
-}
-
-/*
-** Print the current sqlite3_errmsg() value to stderr and return 1.
-*/
-static int shellDatabaseError(sqlite3 *db){
- const char *zErr = sqlite3_errmsg(db);
- utf8_printf(stderr, "Error: %s\n", zErr);
- return 1;
-}
-
-/*
-** Print an out-of-memory message to stderr and return 1.
-*/
-static int shellNomemError(void){
- raw_printf(stderr, "Error: out of memory\n");
- return 1;
-}
-
-/*
-** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
-** if they match and FALSE (0) if they do not match.
-**
-** Globbing rules:
-**
-** '*' Matches any sequence of zero or more characters.
-**
-** '?' Matches exactly one character.
-**
-** [...] Matches one character from the enclosed list of
-** characters.
-**
-** [^...] Matches one character not in the enclosed list.
-**
-** '#' Matches any sequence of one or more digits with an
-** optional + or - sign in front
-**
-** ' ' Any span of whitespace matches any other span of
-** whitespace.
-**
-** Extra whitespace at the end of z[] is ignored.
-*/
-static int testcase_glob(const char *zGlob, const char *z){
- int c, c2;
- int invert;
- int seen;
-
- while( (c = (*(zGlob++)))!=0 ){
- if( IsSpace(c) ){
- if( !IsSpace(*z) ) return 0;
- while( IsSpace(*zGlob) ) zGlob++;
- while( IsSpace(*z) ) z++;
- }else if( c=='*' ){
- while( (c=(*(zGlob++))) == '*' || c=='?' ){
- if( c=='?' && (*(z++))==0 ) return 0;
- }
- if( c==0 ){
- return 1;
- }else if( c=='[' ){
- while( *z && testcase_glob(zGlob-1,z)==0 ){
- z++;
- }
- return (*z)!=0;
- }
- while( (c2 = (*(z++)))!=0 ){
- while( c2!=c ){
- c2 = *(z++);
- if( c2==0 ) return 0;
- }
- if( testcase_glob(zGlob,z) ) return 1;
- }
- return 0;
- }else if( c=='?' ){
- if( (*(z++))==0 ) return 0;
- }else if( c=='[' ){
- int prior_c = 0;
- seen = 0;
- invert = 0;
- c = *(z++);
- if( c==0 ) return 0;
- c2 = *(zGlob++);
- if( c2=='^' ){
- invert = 1;
- c2 = *(zGlob++);
- }
- if( c2==']' ){
- if( c==']' ) seen = 1;
- c2 = *(zGlob++);
- }
- while( c2 && c2!=']' ){
- if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
- c2 = *(zGlob++);
- if( c>=prior_c && c<=c2 ) seen = 1;
- prior_c = 0;
- }else{
- if( c==c2 ){
- seen = 1;
- }
- prior_c = c2;
- }
- c2 = *(zGlob++);
- }
- if( c2==0 || (seen ^ invert)==0 ) return 0;
- }else if( c=='#' ){
- if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
- if( !IsDigit(z[0]) ) return 0;
- z++;
- while( IsDigit(z[0]) ){ z++; }
- }else{
- if( c!=(*(z++)) ) return 0;
- }
- }
- while( IsSpace(*z) ){ z++; }
- return *z==0;
-}
-
-
-/*
-** 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;
-}
-
-/*
-** Delete a file.
-*/
-int shellDeleteFile(const char *zFilename){
- int rc;
-#ifdef _WIN32
- wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
- rc = _wunlink(z);
- sqlite3_free(z);
-#else
- rc = unlink(zFilename);
-#endif
- return rc;
-}
-
-
-/*
-** The implementation of SQL scalar function fkey_collate_clause(), used
-** by the ".lint fkey-indexes" command. This scalar function is always
-** called with four arguments - the parent table name, the parent column name,
-** the child table name and the child column name.
-**
-** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
-**
-** If either of the named tables or columns do not exist, this function
-** returns an empty string. An empty string is also returned if both tables
-** and columns exist but have the same default collation sequence. Or,
-** if both exist but the default collation sequences are different, this
-** function returns the string " COLLATE <parent-collation>", where
-** <parent-collation> is the default collation sequence of the parent column.
-*/
-static void shellFkeyCollateClause(
- sqlite3_context *pCtx,
- int nVal,
- sqlite3_value **apVal
-){
- sqlite3 *db = sqlite3_context_db_handle(pCtx);
- const char *zParent;
- const char *zParentCol;
- const char *zParentSeq;
- const char *zChild;
- const char *zChildCol;
- const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
- int rc;
-
- assert( nVal==4 );
- zParent = (const char*)sqlite3_value_text(apVal[0]);
- zParentCol = (const char*)sqlite3_value_text(apVal[1]);
- zChild = (const char*)sqlite3_value_text(apVal[2]);
- zChildCol = (const char*)sqlite3_value_text(apVal[3]);
-
- sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
- rc = sqlite3_table_column_metadata(
- db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
- );
- if( rc==SQLITE_OK ){
- rc = sqlite3_table_column_metadata(
- db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
- );
- }
-
- if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
- char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
- sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
- sqlite3_free(z);
- }
-}
-
-
-/*
-** The implementation of dot-command ".lint fkey-indexes".
-*/
-static int lintFkeyIndexes(
- ShellState *pState, /* Current shell tool state */
- char **azArg, /* Array of arguments passed to dot command */
- int nArg /* Number of entries in azArg[] */
-){
- sqlite3 *db = pState->db; /* Database handle to query "main" db of */
- FILE *out = pState->out; /* Stream to write non-error output to */
- int bVerbose = 0; /* If -verbose is present */
- int bGroupByParent = 0; /* If -groupbyparent is present */
- int i; /* To iterate through azArg[] */
- const char *zIndent = ""; /* How much to indent CREATE INDEX by */
- int rc; /* Return code */
- sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
-
- /*
- ** This SELECT statement returns one row for each foreign key constraint
- ** in the schema of the main database. The column values are:
- **
- ** 0. The text of an SQL statement similar to:
- **
- ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?"
- **
- ** This is the same SELECT that the foreign keys implementation needs
- ** to run internally on child tables. If there is an index that can
- ** be used to optimize this query, then it can also be used by the FK
- ** implementation to optimize DELETE or UPDATE statements on the parent
- ** table.
- **
- ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
- ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
- ** contains an index that can be used to optimize the query.
- **
- ** 2. Human readable text that describes the child table and columns. e.g.
- **
- ** "child_table(child_key1, child_key2)"
- **
- ** 3. Human readable text that describes the parent table and columns. e.g.
- **
- ** "parent_table(parent_key1, parent_key2)"
- **
- ** 4. A full CREATE INDEX statement for an index that could be used to
- ** optimize DELETE or UPDATE statements on the parent table. e.g.
- **
- ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
- **
- ** 5. The name of the parent table.
- **
- ** These six values are used by the C logic below to generate the report.
- */
- const char *zSql =
- "SELECT "
- " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
- " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
- " || fkey_collate_clause("
- " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
- ", "
- " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
- " || group_concat('*=?', ' AND ') || ')'"
- ", "
- " s.name || '(' || group_concat(f.[from], ', ') || ')'"
- ", "
- " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
- ", "
- " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
- " || ' ON ' || quote(s.name) || '('"
- " || group_concat(quote(f.[from]) ||"
- " fkey_collate_clause("
- " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
- " || ');'"
- ", "
- " f.[table] "
- "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
- "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
- "GROUP BY s.name, f.id "
- "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
- ;
- const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
-
- for(i=2; i<nArg; i++){
- int n = (int)strlen(azArg[i]);
- if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
- bVerbose = 1;
- }
- else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
- bGroupByParent = 1;
- zIndent = " ";
- }
- else{
- raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
- azArg[0], azArg[1]
- );
- return SQLITE_ERROR;
- }
- }
-
- /* Register the fkey_collate_clause() SQL function */
- rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
- 0, shellFkeyCollateClause, 0, 0
- );
-
-
- if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
- }
- if( rc==SQLITE_OK ){
- sqlite3_bind_int(pSql, 1, bGroupByParent);
- }
-
- if( rc==SQLITE_OK ){
- int rc2;
- char *zPrev = 0;
- while( SQLITE_ROW==sqlite3_step(pSql) ){
- int res = -1;
- sqlite3_stmt *pExplain = 0;
- const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
- const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
- const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
- const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
- const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
- const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
-
- rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
- if( rc!=SQLITE_OK ) break;
- if( SQLITE_ROW==sqlite3_step(pExplain) ){
- const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
- res = (
- 0==sqlite3_strglob(zGlob, zPlan)
- || 0==sqlite3_strglob(zGlobIPK, zPlan)
- );
- }
- rc = sqlite3_finalize(pExplain);
- if( rc!=SQLITE_OK ) break;
-
- if( res<0 ){
- raw_printf(stderr, "Error: internal error");
- break;
- }else{
- if( bGroupByParent
- && (bVerbose || res==0)
- && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
- ){
- raw_printf(out, "-- Parent table %s\n", zParent);
- sqlite3_free(zPrev);
- zPrev = sqlite3_mprintf("%s", zParent);
- }
-
- if( res==0 ){
- raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
- }else if( bVerbose ){
- raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
- zIndent, zFrom, zTarget
- );
- }
- }
- }
- sqlite3_free(zPrev);
-
- if( rc!=SQLITE_OK ){
- raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
- }
-
- rc2 = sqlite3_finalize(pSql);
- if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
- rc = rc2;
- raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
- }
- }else{
- raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
- }
-
- return rc;
-}
-
-/*
-** Implementation of ".lint" dot command.
-*/
-static int lintDotCommand(
- ShellState *pState, /* Current shell tool state */
- char **azArg, /* Array of arguments passed to dot command */
- int nArg /* Number of entries in azArg[] */
-){
- int n;
- n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
- if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
- return lintFkeyIndexes(pState, azArg, nArg);
-
- usage:
- raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
- raw_printf(stderr, "Where sub-commands are:\n");
- raw_printf(stderr, " fkey-indexes\n");
- return SQLITE_ERROR;
-}
-
-
-/*
-** If an input line begins with "." then invoke this routine to
-** process that line.
-**
-** Return 1 on error, 2 to exit, and 0 otherwise.
-*/
-static int do_meta_command(char *zLine, ShellState *p){
- int h = 1;
- int nArg = 0;
- int n, c;
- int rc = 0;
- char *azArg[50];
-
- /* Parse the input line into tokens.
- */
- while( zLine[h] && nArg<ArraySize(azArg) ){
- while( IsSpace(zLine[h]) ){ h++; }
- if( zLine[h]==0 ) break;
- if( zLine[h]=='\'' || zLine[h]=='"' ){
- int delim = zLine[h++];
- azArg[nArg++] = &zLine[h];
- while( zLine[h] && zLine[h]!=delim ){
- if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
- h++;
- }
- if( zLine[h]==delim ){
- zLine[h++] = 0;
- }
- if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
- }else{
- azArg[nArg++] = &zLine[h];
- while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
- if( zLine[h] ) zLine[h++] = 0;
- resolve_backslashes(azArg[nArg-1]);
- }
- }
-
- /* Process the input line.
- */
- if( nArg==0 ) return 0; /* no tokens, no error */
- n = strlen30(azArg[0]);
- c = azArg[0][0];
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- 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
-#endif
-
- if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
- || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
- ){
- const char *zDestFile = 0;
- const char *zDb = 0;
- sqlite3 *pDest;
- sqlite3_backup *pBackup;
- int j;
- for(j=1; j<nArg; j++){
- const char *z = azArg[j];
- if( z[0]=='-' ){
- while( z[0]=='-' ) z++;
- /* No options to process at this time */
- {
- utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
- return 1;
- }
- }else if( zDestFile==0 ){
- zDestFile = azArg[j];
- }else if( zDb==0 ){
- zDb = zDestFile;
- zDestFile = azArg[j];
- }else{
- raw_printf(stderr, "too many arguments to .backup\n");
- return 1;
- }
- }
- if( zDestFile==0 ){
- raw_printf(stderr, "missing FILENAME argument on .backup\n");
- return 1;
- }
- if( zDb==0 ) zDb = "main";
- rc = sqlite3_open(zDestFile, &pDest);
- if( rc!=SQLITE_OK ){
- utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
- sqlite3_close(pDest);
- return 1;
- }
- open_db(p, 0);
- pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
- if( pBackup==0 ){
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
- sqlite3_close(pDest);
- return 1;
- }
- while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
- sqlite3_backup_finish(pBackup);
- if( rc==SQLITE_DONE ){
- rc = 0;
- }else{
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
- rc = 1;
- }
- sqlite3_close(pDest);
- }else
-
- if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
- if( nArg==2 ){
- bail_on_error = booleanValue(azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .bail on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
- if( nArg==2 ){
- if( booleanValue(azArg[1]) ){
- setBinaryMode(p->out, 1);
- }else{
- setTextMode(p->out, 1);
- }
- }else{
- raw_printf(stderr, "Usage: .binary on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='c' && strcmp(azArg[0],"cd")==0 ){
- if( nArg==2 ){
-#if defined(_WIN32) || defined(WIN32)
- wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
- rc = !SetCurrentDirectoryW(z);
- sqlite3_free(z);
-#else
- rc = chdir(azArg[1]);
-#endif
- if( rc ){
- utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
- rc = 1;
- }
- }else{
- raw_printf(stderr, "Usage: .cd DIRECTORY\n");
- rc = 1;
- }
- }else
-
- /* The undocumented ".breakpoint" command causes a call to the no-op
- ** routine named test_breakpoint().
- */
- if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
- test_breakpoint();
- }else
-
- if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
- if( nArg==2 ){
- setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .changes on|off\n");
- rc = 1;
- }
- }else
-
- /* Cancel output redirection, if it is currently set (by .testcase)
- ** Then read the content of the testcase-out.txt file and compare against
- ** azArg[1]. If there are differences, report an error and exit.
- */
- if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
- char *zRes = 0;
- output_reset(p);
- if( nArg!=2 ){
- raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
- rc = 2;
- }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
- raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
- rc = 2;
- }else if( testcase_glob(azArg[1],zRes)==0 ){
- utf8_printf(stderr,
- "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
- p->zTestcase, azArg[1], zRes);
- rc = 1;
- }else{
- utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
- p->nCheck++;
- }
- sqlite3_free(zRes);
- }else
-
- if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
- if( nArg==2 ){
- tryToClone(p, azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .clone FILENAME\n");
- rc = 1;
- }
- }else
-
- if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
- ShellState data;
- char *zErrMsg = 0;
- open_db(p, 0);
- memcpy(&data, p, sizeof(data));
- data.showHeader = 0;
- data.cMode = data.mode = MODE_List;
- sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
- data.cnt = 0;
- sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
- callback, &data, &zErrMsg);
- if( zErrMsg ){
- utf8_printf(stderr,"Error: %s\n", zErrMsg);
- sqlite3_free(zErrMsg);
- rc = 1;
- }
- }else
-
- if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
- rc = shell_dbinfo_command(p, nArg, azArg);
- }else
-
- if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
- const char *zLike = 0;
- int i;
- int savedShowHeader = p->showHeader;
- ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines);
- for(i=1; i<nArg; i++){
- if( azArg[i][0]=='-' ){
- const char *z = azArg[i]+1;
- if( z[0]=='-' ) z++;
- if( strcmp(z,"preserve-rowids")==0 ){
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- raw_printf(stderr, "The --preserve-rowids option is not compatible"
- " with SQLITE_OMIT_VIRTUALTABLE\n");
- rc = 1;
- goto meta_command_exit;
-#else
- ShellSetFlag(p, SHFLG_PreserveRowid);
-#endif
- }else
- if( strcmp(z,"newlines")==0 ){
- ShellSetFlag(p, SHFLG_Newlines);
- }else
- {
- raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
- rc = 1;
- goto meta_command_exit;
- }
- }else if( zLike ){
- raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
- "?--newlines? ?LIKE-PATTERN?\n");
- rc = 1;
- goto meta_command_exit;
- }else{
- zLike = azArg[i];
- }
- }
- open_db(p, 0);
- /* When playing back a "dump", the content might appear in an order
- ** which causes immediate foreign key constraints to be violated.
- ** So disable foreign-key constraint enforcement to prevent problems. */
- raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
- raw_printf(p->out, "BEGIN TRANSACTION;\n");
- p->writableSchema = 0;
- p->showHeader = 0;
- /* Set writable_schema=ON since doing so forces SQLite to initialize
- ** as much of the schema as it can even if the sqlite_master table is
- ** corrupt. */
- sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
- p->nErr = 0;
- if( zLike==0 ){
- run_schema_dump_query(p,
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
- );
- run_schema_dump_query(p,
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE name=='sqlite_sequence'"
- );
- run_table_dump_query(p,
- "SELECT sql FROM sqlite_master "
- "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
- );
- }else{
- char *zSql;
- zSql = sqlite3_mprintf(
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE tbl_name LIKE %Q AND type=='table'"
- " AND sql NOT NULL", zLike);
- run_schema_dump_query(p,zSql);
- sqlite3_free(zSql);
- zSql = sqlite3_mprintf(
- "SELECT sql FROM sqlite_master "
- "WHERE sql NOT NULL"
- " AND type IN ('index','trigger','view')"
- " AND tbl_name LIKE %Q", zLike);
- run_table_dump_query(p, zSql, 0);
- sqlite3_free(zSql);
- }
- if( p->writableSchema ){
- raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
- p->writableSchema = 0;
- }
- sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
- sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
- raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
- p->showHeader = savedShowHeader;
- }else
-
- if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
- if( nArg==2 ){
- setOrClearFlag(p, SHFLG_Echo, azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .echo on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
- if( nArg==2 ){
- if( strcmp(azArg[1],"full")==0 ){
- p->autoEQP = 2;
- }else{
- p->autoEQP = booleanValue(azArg[1]);
- }
- }else{
- raw_printf(stderr, "Usage: .eqp on|off|full\n");
- rc = 1;
- }
- }else
-
- if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
- if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
- rc = 2;
- }else
-
- /* The ".explain" command is automatic now. It is largely pointless. It
- ** retained purely for backwards compatibility */
- if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
- int val = 1;
- if( nArg>=2 ){
- if( strcmp(azArg[1],"auto")==0 ){
- val = 99;
- }else{
- val = booleanValue(azArg[1]);
- }
- }
- if( val==1 && p->mode!=MODE_Explain ){
- p->normalMode = p->mode;
- p->mode = MODE_Explain;
- p->autoExplain = 0;
- }else if( val==0 ){
- if( p->mode==MODE_Explain ) p->mode = p->normalMode;
- p->autoExplain = 0;
- }else if( val==99 ){
- if( p->mode==MODE_Explain ) p->mode = p->normalMode;
- p->autoExplain = 1;
- }
- }else
-
- if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
- 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 ?--indent?\n");
- rc = 1;
- goto meta_command_exit;
- }
- open_db(p, 0);
- rc = sqlite3_exec(p->db,
- "SELECT sql FROM"
- " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
- " FROM sqlite_master UNION ALL"
- " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
- "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
- "ORDER BY rowid",
- callback, &data, &zErrMsg
- );
- if( rc==SQLITE_OK ){
- sqlite3_stmt *pStmt;
- rc = sqlite3_prepare_v2(p->db,
- "SELECT rowid FROM sqlite_master"
- " WHERE name GLOB 'sqlite_stat[134]'",
- -1, &pStmt, 0);
- doStats = sqlite3_step(pStmt)==SQLITE_ROW;
- sqlite3_finalize(pStmt);
- }
- if( doStats==0 ){
- raw_printf(p->out, "/* No STAT tables available */\n");
- }else{
- raw_printf(p->out, "ANALYZE sqlite_master;\n");
- sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
- callback, &data, &zErrMsg);
- data.cMode = data.mode = MODE_Insert;
- data.zDestTable = "sqlite_stat1";
- shell_exec(p->db, "SELECT * FROM sqlite_stat1",
- shell_callback, &data,&zErrMsg);
- data.zDestTable = "sqlite_stat3";
- shell_exec(p->db, "SELECT * FROM sqlite_stat3",
- shell_callback, &data,&zErrMsg);
- data.zDestTable = "sqlite_stat4";
- shell_exec(p->db, "SELECT * FROM sqlite_stat4",
- shell_callback, &data, &zErrMsg);
- raw_printf(p->out, "ANALYZE sqlite_master;\n");
- }
- }else
-
- if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
- if( nArg==2 ){
- p->showHeader = booleanValue(azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .headers on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
- utf8_printf(p->out, "%s", zHelp);
- }else
-
- if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
- char *zTable; /* Insert data into this table */
- char *zFile; /* Name of file to extra content from */
- sqlite3_stmt *pStmt = NULL; /* A statement */
- int nCol; /* Number of columns in the table */
- int nByte; /* Number of bytes in an SQL string */
- int i, j; /* Loop counters */
- int needCommit; /* True to COMMIT or ROLLBACK at end */
- int nSep; /* Number of bytes in p->colSeparator[] */
- char *zSql; /* An SQL statement */
- ImportCtx sCtx; /* Reader context */
- char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
- int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
-
- if( nArg!=3 ){
- raw_printf(stderr, "Usage: .import FILE TABLE\n");
- goto meta_command_exit;
- }
- zFile = azArg[1];
- zTable = azArg[2];
- seenInterrupt = 0;
- memset(&sCtx, 0, sizeof(sCtx));
- open_db(p, 0);
- nSep = strlen30(p->colSeparator);
- if( nSep==0 ){
- raw_printf(stderr,
- "Error: non-null column separator required for import\n");
- return 1;
- }
- if( nSep>1 ){
- raw_printf(stderr, "Error: multi-character column separators not allowed"
- " for import\n");
- return 1;
- }
- nSep = strlen30(p->rowSeparator);
- if( nSep==0 ){
- raw_printf(stderr, "Error: non-null row separator required for import\n");
- return 1;
- }
- if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
- /* When importing CSV (only), if the row separator is set to the
- ** default output row separator, change it to the default input
- ** row separator. This avoids having to maintain different input
- ** and output row separators. */
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
- nSep = strlen30(p->rowSeparator);
- }
- if( nSep>1 ){
- raw_printf(stderr, "Error: multi-character row separators not allowed"
- " for import\n");
- return 1;
- }
- sCtx.zFile = zFile;
- sCtx.nLine = 1;
- if( sCtx.zFile[0]=='|' ){
-#ifdef SQLITE_OMIT_POPEN
- raw_printf(stderr, "Error: pipes are not supported in this OS\n");
- return 1;
-#else
- sCtx.in = popen(sCtx.zFile+1, "r");
- sCtx.zFile = "<pipe>";
- xCloser = pclose;
-#endif
- }else{
- sCtx.in = fopen(sCtx.zFile, "rb");
- xCloser = fclose;
- }
- if( p->mode==MODE_Ascii ){
- xRead = ascii_read_one_field;
- }else{
- xRead = csv_read_one_field;
- }
- if( sCtx.in==0 ){
- utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
- return 1;
- }
- sCtx.cColSep = p->colSeparator[0];
- sCtx.cRowSep = p->rowSeparator[0];
- zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
- if( zSql==0 ){
- raw_printf(stderr, "Error: out of memory\n");
- xCloser(sCtx.in);
- return 1;
- }
- nByte = strlen30(zSql);
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
- if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
- char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
- char cSep = '(';
- while( xRead(&sCtx) ){
- zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
- cSep = ',';
- if( sCtx.cTerm!=sCtx.cColSep ) break;
- }
- if( cSep=='(' ){
- sqlite3_free(zCreate);
- sqlite3_free(sCtx.z);
- xCloser(sCtx.in);
- utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
- return 1;
- }
- zCreate = sqlite3_mprintf("%z\n)", zCreate);
- rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
- sqlite3_free(zCreate);
- if( rc ){
- utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
- sqlite3_errmsg(p->db));
- sqlite3_free(sCtx.z);
- xCloser(sCtx.in);
- return 1;
- }
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- }
- sqlite3_free(zSql);
- if( rc ){
- if (pStmt) sqlite3_finalize(pStmt);
- utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
- xCloser(sCtx.in);
- return 1;
- }
- nCol = sqlite3_column_count(pStmt);
- sqlite3_finalize(pStmt);
- pStmt = 0;
- if( nCol==0 ) return 0; /* no columns, no error */
- zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
- if( zSql==0 ){
- raw_printf(stderr, "Error: out of memory\n");
- xCloser(sCtx.in);
- return 1;
- }
- sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
- j = strlen30(zSql);
- for(i=1; i<nCol; i++){
- zSql[j++] = ',';
- zSql[j++] = '?';
- }
- zSql[j++] = ')';
- zSql[j] = 0;
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( rc ){
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
- if (pStmt) sqlite3_finalize(pStmt);
- xCloser(sCtx.in);
- return 1;
- }
- needCommit = sqlite3_get_autocommit(p->db);
- if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
- do{
- int startLine = sCtx.nLine;
- for(i=0; i<nCol; i++){
- char *z = xRead(&sCtx);
- /*
- ** Did we reach end-of-file before finding any columns?
- ** If so, stop instead of NULL filling the remaining columns.
- */
- if( z==0 && i==0 ) break;
- /*
- ** Did we reach end-of-file OR end-of-line before finding any
- ** columns in ASCII mode? If so, stop instead of NULL filling
- ** the remaining columns.
- */
- if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
- sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
- if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
- utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
- "filling the rest with NULL\n",
- sCtx.zFile, startLine, nCol, i+1);
- i += 2;
- while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
- }
- }
- if( sCtx.cTerm==sCtx.cColSep ){
- do{
- xRead(&sCtx);
- i++;
- }while( sCtx.cTerm==sCtx.cColSep );
- utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
- "extras ignored\n",
- sCtx.zFile, startLine, nCol, i);
- }
- if( i>=nCol ){
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- if( rc!=SQLITE_OK ){
- utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
- startLine, sqlite3_errmsg(p->db));
- }
- }
- }while( sCtx.cTerm!=EOF );
-
- xCloser(sCtx.in);
- sqlite3_free(sCtx.z);
- sqlite3_finalize(pStmt);
- if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
- }else
-
-#ifndef SQLITE_UNTESTABLE
- if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
- char *zSql;
- char *zCollist = 0;
- sqlite3_stmt *pStmt;
- int tnum = 0;
- int i;
- if( nArg!=3 ){
- utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
- rc = 1;
- goto meta_command_exit;
- }
- open_db(p, 0);
- zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
- " WHERE name='%q' AND type='index'", azArg[1]);
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
- tnum = sqlite3_column_int(pStmt, 0);
- }
- sqlite3_finalize(pStmt);
- if( tnum==0 ){
- utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
- rc = 1;
- goto meta_command_exit;
- }
- zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- i = 0;
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- char zLabel[20];
- const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
- i++;
- if( zCol==0 ){
- if( sqlite3_column_int(pStmt,1)==-1 ){
- zCol = "_ROWID_";
- }else{
- sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
- zCol = zLabel;
- }
- }
- if( zCollist==0 ){
- zCollist = sqlite3_mprintf("\"%w\"", zCol);
- }else{
- zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
- }
- }
- sqlite3_finalize(pStmt);
- zSql = sqlite3_mprintf(
- "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
- azArg[2], zCollist, zCollist);
- sqlite3_free(zCollist);
- rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
- if( rc==SQLITE_OK ){
- rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
- sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
- if( rc ){
- utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
- }else{
- utf8_printf(stdout, "%s;\n", zSql);
- raw_printf(stdout,
- "WARNING: writing to an imposter table will corrupt the index!\n"
- );
- }
- }else{
- raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
- rc = 1;
- }
- sqlite3_free(zSql);
- }else
-#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
-
-#ifdef SQLITE_ENABLE_IOTRACE
- if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
- SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
- if( iotrace && iotrace!=stdout ) fclose(iotrace);
- iotrace = 0;
- if( nArg<2 ){
- sqlite3IoTrace = 0;
- }else if( strcmp(azArg[1], "-")==0 ){
- sqlite3IoTrace = iotracePrintf;
- iotrace = stdout;
- }else{
- iotrace = fopen(azArg[1], "w");
- if( iotrace==0 ){
- utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
- sqlite3IoTrace = 0;
- rc = 1;
- }else{
- sqlite3IoTrace = iotracePrintf;
- }
- }
- }else
-#endif
-
- if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
- static const struct {
- const char *zLimitName; /* Name of a limit */
- int limitCode; /* Integer code for that limit */
- } aLimit[] = {
- { "length", SQLITE_LIMIT_LENGTH },
- { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
- { "column", SQLITE_LIMIT_COLUMN },
- { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
- { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
- { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
- { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
- { "attached", SQLITE_LIMIT_ATTACHED },
- { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
- { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
- { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
- { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
- };
- int i, n2;
- open_db(p, 0);
- if( nArg==1 ){
- for(i=0; i<ArraySize(aLimit); i++){
- printf("%20s %d\n", aLimit[i].zLimitName,
- sqlite3_limit(p->db, aLimit[i].limitCode, -1));
- }
- }else if( nArg>3 ){
- raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
- rc = 1;
- goto meta_command_exit;
- }else{
- int iLimit = -1;
- n2 = strlen30(azArg[1]);
- for(i=0; i<ArraySize(aLimit); i++){
- if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
- if( iLimit<0 ){
- iLimit = i;
- }else{
- utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
- rc = 1;
- goto meta_command_exit;
- }
- }
- }
- if( iLimit<0 ){
- utf8_printf(stderr, "unknown limit: \"%s\"\n"
- "enter \".limits\" with no arguments for a list.\n",
- azArg[1]);
- rc = 1;
- goto meta_command_exit;
- }
- if( nArg==3 ){
- sqlite3_limit(p->db, aLimit[iLimit].limitCode,
- (int)integerValue(azArg[2]));
- }
- printf("%20s %d\n", aLimit[iLimit].zLimitName,
- sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
- }
- }else
-
- if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
- open_db(p, 0);
- lintDotCommand(p, azArg, nArg);
- }else
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
- if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
- const char *zFile, *zProc;
- char *zErrMsg = 0;
- if( nArg<2 ){
- raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
- rc = 1;
- goto meta_command_exit;
- }
- zFile = azArg[1];
- zProc = nArg>=3 ? azArg[2] : 0;
- open_db(p, 0);
- rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
- if( rc!=SQLITE_OK ){
- utf8_printf(stderr, "Error: %s\n", zErrMsg);
- sqlite3_free(zErrMsg);
- rc = 1;
- }
- }else
-#endif
-
- if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
- if( nArg!=2 ){
- raw_printf(stderr, "Usage: .log FILENAME\n");
- rc = 1;
- }else{
- const char *zFile = azArg[1];
- output_file_close(p->pLog);
- p->pLog = output_file_open(zFile);
- }
- }else
-
- if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
- const char *zMode = nArg>=2 ? azArg[1] : "";
- int n2 = (int)strlen(zMode);
- int c2 = zMode[0];
- if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
- p->mode = MODE_Line;
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
- }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
- p->mode = MODE_Column;
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
- }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
- p->mode = MODE_List;
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
- }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
- p->mode = MODE_Html;
- }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
- p->mode = MODE_Tcl;
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
- }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
- p->mode = MODE_Csv;
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
- }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
- p->mode = MODE_List;
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
- }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
- p->mode = MODE_Insert;
- set_table_name(p, nArg>=3 ? azArg[2] : "table");
- }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
- p->mode = MODE_Quote;
- }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
- p->mode = MODE_Ascii;
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
- }else if( nArg==1 ){
- raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
- }else{
- raw_printf(stderr, "Error: mode should be one of: "
- "ascii column csv html insert line list quote tabs tcl\n");
- rc = 1;
- }
- p->cMode = p->mode;
- }else
-
- if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
- if( nArg==2 ){
- sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
- "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
- }else{
- raw_printf(stderr, "Usage: .nullvalue STRING\n");
- rc = 1;
- }
- }else
-
- if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
- char *zNewFilename; /* Name of the database file to open */
- int iName = 1; /* Index in azArg[] of the filename */
- int newFlag = 0; /* True to delete file before opening */
- /* Close the existing database */
- session_close_all(p);
- sqlite3_close(p->db);
- p->db = 0;
- p->zDbFilename = 0;
- sqlite3_free(p->zFreeOnClose);
- p->zFreeOnClose = 0;
- /* Check for command-line arguments */
- for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
- const char *z = azArg[iName];
- if( optionMatch(z,"new") ){
- newFlag = 1;
- }else if( z[0]=='-' ){
- utf8_printf(stderr, "unknown option: %s\n", z);
- rc = 1;
- goto meta_command_exit;
- }
- }
- /* If a filename is specified, try to open it first */
- zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
- if( zNewFilename ){
- if( newFlag ) shellDeleteFile(zNewFilename);
- p->zDbFilename = zNewFilename;
- open_db(p, 1);
- if( p->db==0 ){
- utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
- sqlite3_free(zNewFilename);
- }else{
- p->zFreeOnClose = zNewFilename;
- }
- }
- if( p->db==0 ){
- /* As a fall-back open a TEMP database */
- p->zDbFilename = 0;
- open_db(p, 0);
- }
- }else
-
- if( c=='o'
- && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
- ){
- const char *zFile = nArg>=2 ? azArg[1] : "stdout";
- if( nArg>2 ){
- utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
- rc = 1;
- goto meta_command_exit;
- }
- if( n>1 && strncmp(azArg[0], "once", n)==0 ){
- if( nArg<2 ){
- raw_printf(stderr, "Usage: .once FILE\n");
- rc = 1;
- goto meta_command_exit;
- }
- p->outCount = 2;
- }else{
- p->outCount = 0;
- }
- output_reset(p);
- if( zFile[0]=='|' ){
-#ifdef SQLITE_OMIT_POPEN
- raw_printf(stderr, "Error: pipes are not supported in this OS\n");
- rc = 1;
- p->out = stdout;
-#else
- p->out = popen(zFile + 1, "w");
- if( p->out==0 ){
- utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
- p->out = stdout;
- rc = 1;
- }else{
- sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
- }
-#endif
- }else{
- p->out = output_file_open(zFile);
- if( p->out==0 ){
- if( strcmp(zFile,"off")!=0 ){
- utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
- }
- p->out = stdout;
- rc = 1;
- } else {
- sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
- }
- }
- }else
-
- if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
- int i;
- for(i=1; i<nArg; i++){
- if( i>1 ) raw_printf(p->out, " ");
- utf8_printf(p->out, "%s", azArg[i]);
- }
- raw_printf(p->out, "\n");
- }else
-
- if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
- if( nArg >= 2) {
- strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
- }
- if( nArg >= 3) {
- strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
- }
- }else
-
- if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
- rc = 2;
- }else
-
- if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
- FILE *alt;
- if( nArg!=2 ){
- raw_printf(stderr, "Usage: .read FILE\n");
- rc = 1;
- goto meta_command_exit;
- }
- alt = fopen(azArg[1], "rb");
- if( alt==0 ){
- utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
- rc = 1;
- }else{
- rc = process_input(p, alt);
- fclose(alt);
- }
- }else
-
- if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
- const char *zSrcFile;
- const char *zDb;
- sqlite3 *pSrc;
- sqlite3_backup *pBackup;
- int nTimeout = 0;
-
- if( nArg==2 ){
- zSrcFile = azArg[1];
- zDb = "main";
- }else if( nArg==3 ){
- zSrcFile = azArg[2];
- zDb = azArg[1];
- }else{
- raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
- rc = 1;
- goto meta_command_exit;
- }
- rc = sqlite3_open(zSrcFile, &pSrc);
- if( rc!=SQLITE_OK ){
- utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
- sqlite3_close(pSrc);
- return 1;
- }
- open_db(p, 0);
- pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
- if( pBackup==0 ){
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
- sqlite3_close(pSrc);
- return 1;
- }
- while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
- || rc==SQLITE_BUSY ){
- if( rc==SQLITE_BUSY ){
- if( nTimeout++ >= 3 ) break;
- sqlite3_sleep(100);
- }
- }
- sqlite3_backup_finish(pBackup);
- if( rc==SQLITE_DONE ){
- rc = 0;
- }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
- raw_printf(stderr, "Error: source database is busy\n");
- rc = 1;
- }else{
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
- rc = 1;
- }
- sqlite3_close(pSrc);
- }else
-
-
- if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
- if( nArg==2 ){
- p->scanstatsOn = booleanValue(azArg[1]);
-#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
- raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
-#endif
- }else{
- raw_printf(stderr, "Usage: .scanstats on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
- ShellText sSelect;
- ShellState data;
- char *zErrMsg = 0;
- const char *zDiv = 0;
- int iSchema = 0;
-
- open_db(p, 0);
- memcpy(&data, p, sizeof(data));
- data.showHeader = 0;
- data.cMode = data.mode = MODE_Semi;
- initText(&sSelect);
- 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 ){
- char *new_argv[2], *new_colv[2];
- new_argv[0] = "CREATE TABLE sqlite_master (\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")";
- new_argv[1] = 0;
- new_colv[0] = "sql";
- new_colv[1] = 0;
- callback(&data, 1, new_argv, new_colv);
- rc = SQLITE_OK;
- }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
- char *new_argv[2], *new_colv[2];
- new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")";
- new_argv[1] = 0;
- new_colv[0] = "sql";
- new_colv[1] = 0;
- callback(&data, 1, new_argv, new_colv);
- rc = SQLITE_OK;
- }else{
- zDiv = "(";
- }
- }else if( nArg==1 ){
- zDiv = "(";
- }else{
- raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
- rc = 1;
- goto meta_command_exit;
- }
- if( zDiv ){
- sqlite3_stmt *pStmt = 0;
- rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
- -1, &pStmt, 0);
- if( rc ){
- utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
- sqlite3_finalize(pStmt);
- rc = 1;
- goto meta_command_exit;
- }
- appendText(&sSelect, "SELECT sql FROM", 0);
- iSchema = 0;
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
- char zScNum[30];
- sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
- appendText(&sSelect, zDiv, 0);
- zDiv = " UNION ALL ";
- if( strcmp(zDb, "main")!=0 ){
- appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
- appendText(&sSelect, zDb, '"');
- appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0);
- appendText(&sSelect, zScNum, 0);
- appendText(&sSelect, " AS snum, ", 0);
- appendText(&sSelect, zDb, '\'');
- appendText(&sSelect, " AS sname FROM ", 0);
- appendText(&sSelect, zDb, '"');
- appendText(&sSelect, ".sqlite_master", 0);
- }else{
- appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0);
- appendText(&sSelect, zScNum, 0);
- appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0);
- }
- }
- sqlite3_finalize(pStmt);
- appendText(&sSelect, ") WHERE ", 0);
- if( nArg>1 ){
- char *zQarg = sqlite3_mprintf("%Q", azArg[1]);
- if( strchr(azArg[1], '.') ){
- appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
- }else{
- appendText(&sSelect, "lower(tbl_name)", 0);
- }
- appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0);
- appendText(&sSelect, zQarg, 0);
- appendText(&sSelect, " AND ", 0);
- sqlite3_free(zQarg);
- }
- appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
- " ORDER BY snum, rowid", 0);
- rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
- freeText(&sSelect);
- }
- if( zErrMsg ){
- utf8_printf(stderr,"Error: %s\n", zErrMsg);
- sqlite3_free(zErrMsg);
- rc = 1;
- }else if( rc != SQLITE_OK ){
- raw_printf(stderr,"Error: querying schema information\n");
- rc = 1;
- }else{
- rc = 0;
- }
- }else
-
-#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
- if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
- sqlite3SelectTrace = (int)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
- ** without notice. */
- if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
- if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
- int i, v;
- for(i=1; i<nArg; i++){
- v = booleanValue(azArg[i]);
- utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
- }
- }
- if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
- int i; sqlite3_int64 v;
- for(i=1; i<nArg; i++){
- char zBuf[200];
- v = integerValue(azArg[i]);
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
- utf8_printf(p->out, "%s", zBuf);
- }
- }
- }else
-#endif
-
- if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
- int bIsInit = 0; /* True to initialize the SELFTEST table */
- int bVerbose = 0; /* Verbose output */
- int bSelftestExists; /* True if SELFTEST already exists */
- int i, k; /* Loop counters */
- int nTest = 0; /* Number of tests runs */
- int nErr = 0; /* Number of errors seen */
- ShellText str; /* Answer for a query */
- sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
-
- open_db(p,0);
- for(i=1; i<nArg; i++){
- const char *z = azArg[i];
- if( z[0]=='-' && z[1]=='-' ) z++;
- if( strcmp(z,"-init")==0 ){
- bIsInit = 1;
- }else
- if( strcmp(z,"-v")==0 ){
- bVerbose++;
- }else
- {
- utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
- azArg[i], azArg[0]);
- raw_printf(stderr, "Should be one of: --init -v\n");
- rc = 1;
- goto meta_command_exit;
- }
- }
- if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
- != SQLITE_OK ){
- bSelftestExists = 0;
- }else{
- bSelftestExists = 1;
- }
- if( bIsInit ){
- createSelftestTable(p);
- bSelftestExists = 1;
- }
- initText(&str);
- appendText(&str, "x", 0);
- for(k=bSelftestExists; k>=0; k--){
- if( k==1 ){
- rc = sqlite3_prepare_v2(p->db,
- "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
- -1, &pStmt, 0);
- }else{
- rc = sqlite3_prepare_v2(p->db,
- "VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
- " (1,'run','PRAGMA integrity_check','ok')",
- -1, &pStmt, 0);
- }
- if( rc ){
- raw_printf(stderr, "Error querying the selftest table\n");
- rc = 1;
- sqlite3_finalize(pStmt);
- goto meta_command_exit;
- }
- for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
- int tno = sqlite3_column_int(pStmt, 0);
- const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
- const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
- const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
-
- k = 0;
- if( bVerbose>0 ){
- char *zQuote = sqlite3_mprintf("%q", zSql);
- printf("%d: %s %s\n", tno, zOp, zSql);
- sqlite3_free(zQuote);
- }
- if( strcmp(zOp,"memo")==0 ){
- utf8_printf(p->out, "%s\n", zSql);
- }else
- if( strcmp(zOp,"run")==0 ){
- char *zErrMsg = 0;
- str.n = 0;
- str.z[0] = 0;
- rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
- nTest++;
- if( bVerbose ){
- utf8_printf(p->out, "Result: %s\n", str.z);
- }
- if( rc || zErrMsg ){
- nErr++;
- rc = 1;
- utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
- sqlite3_free(zErrMsg);
- }else if( strcmp(zAns,str.z)!=0 ){
- nErr++;
- rc = 1;
- utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
- utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
- }
- }else
- {
- utf8_printf(stderr,
- "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
- rc = 1;
- break;
- }
- } /* End loop over rows of content from SELFTEST */
- sqlite3_finalize(pStmt);
- } /* End loop over k */
- freeText(&str);
- utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
- }else
-
- if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
- if( nArg<2 || nArg>3 ){
- raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
- rc = 1;
- }
- if( nArg>=2 ){
- sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
- "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
- }
- if( nArg>=3 ){
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
- "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
- }
- }else
-
- if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
- const char *zLike = 0; /* Which table to checksum. 0 means everything */
- int i; /* Loop counter */
- int bSchema = 0; /* Also hash the schema */
- int bSeparate = 0; /* Hash each table separately */
- int iSize = 224; /* Hash algorithm to use */
- int bDebug = 0; /* Only show the query that would have run */
- sqlite3_stmt *pStmt; /* For querying tables names */
- char *zSql; /* SQL to be run */
- char *zSep; /* Separator */
- ShellText sSql; /* Complete SQL for the query to run the hash */
- ShellText sQuery; /* Set of queries used to read all content */
- open_db(p, 0);
- for(i=1; i<nArg; i++){
- const char *z = azArg[i];
- if( z[0]=='-' ){
- z++;
- if( z[0]=='-' ) z++;
- if( strcmp(z,"schema")==0 ){
- bSchema = 1;
- }else
- if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
- || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
- ){
- iSize = atoi(&z[5]);
- }else
- if( strcmp(z,"debug")==0 ){
- bDebug = 1;
- }else
- {
- utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
- azArg[i], azArg[0]);
- raw_printf(stderr, "Should be one of: --schema"
- " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n");
- rc = 1;
- goto meta_command_exit;
- }
- }else if( zLike ){
- raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
- rc = 1;
- goto meta_command_exit;
- }else{
- zLike = z;
- bSeparate = 1;
- if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1;
- }
- }
- if( bSchema ){
- zSql = "SELECT lower(name) FROM sqlite_master"
- " WHERE type='table' AND coalesce(rootpage,0)>1"
- " UNION ALL SELECT 'sqlite_master'"
- " ORDER BY 1 collate nocase";
- }else{
- zSql = "SELECT lower(name) FROM sqlite_master"
- " WHERE type='table' AND coalesce(rootpage,0)>1"
- " AND name NOT LIKE 'sqlite_%'"
- " ORDER BY 1 collate nocase";
- }
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- initText(&sQuery);
- initText(&sSql);
- appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
- zSep = "VALUES(";
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
- if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
- if( strncmp(zTab, "sqlite_",7)!=0 ){
- appendText(&sQuery,"SELECT * FROM ", 0);
- appendText(&sQuery,zTab,'"');
- appendText(&sQuery," NOT INDEXED;", 0);
- }else if( strcmp(zTab, "sqlite_master")==0 ){
- appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master"
- " ORDER BY name;", 0);
- }else if( strcmp(zTab, "sqlite_sequence")==0 ){
- appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
- " ORDER BY name;", 0);
- }else if( strcmp(zTab, "sqlite_stat1")==0 ){
- appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
- " ORDER BY tbl,idx;", 0);
- }else if( strcmp(zTab, "sqlite_stat3")==0
- || strcmp(zTab, "sqlite_stat4")==0 ){
- appendText(&sQuery, "SELECT * FROM ", 0);
- appendText(&sQuery, zTab, 0);
- appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
- }
- appendText(&sSql, zSep, 0);
- appendText(&sSql, sQuery.z, '\'');
- sQuery.n = 0;
- appendText(&sSql, ",", 0);
- appendText(&sSql, zTab, '\'');
- zSep = "),(";
- }
- sqlite3_finalize(pStmt);
- if( bSeparate ){
- zSql = sqlite3_mprintf(
- "%s))"
- " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
- " FROM [sha3sum$query]",
- sSql.z, iSize);
- }else{
- zSql = sqlite3_mprintf(
- "%s))"
- " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
- " FROM [sha3sum$query]",
- sSql.z, iSize);
- }
- freeText(&sQuery);
- freeText(&sSql);
- if( bDebug ){
- utf8_printf(p->out, "%s\n", zSql);
- }else{
- shell_exec(p->db, zSql, shell_callback, p, 0);
- }
- sqlite3_free(zSql);
- }else
-
- if( c=='s'
- && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
- ){
- char *zCmd;
- int i, x;
- if( nArg<2 ){
- raw_printf(stderr, "Usage: .system COMMAND\n");
- rc = 1;
- goto meta_command_exit;
- }
- zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
- for(i=2; i<nArg; i++){
- zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
- zCmd, azArg[i]);
- }
- x = system(zCmd);
- sqlite3_free(zCmd);
- if( x ) raw_printf(stderr, "System command returns %d\n", x);
- }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",
- azBool[ShellHasFlag(p, SHFLG_Echo)]);
- 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", 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);
- raw_printf(p->out, "\n");
- utf8_printf(p->out,"%12.12s: %s\n","output",
- strlen30(p->outfile) ? p->outfile : "stdout");
- utf8_printf(p->out,"%12.12s: ", "colseparator");
- output_c_string(p->out, p->colSeparator);
- raw_printf(p->out, "\n");
- 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", 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]);
- }
- raw_printf(p->out, "\n");
- utf8_printf(p->out, "%12.12s: %s\n", "filename",
- p->zDbFilename ? p->zDbFilename : "");
- }else
-
- 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");
- rc = 1;
- }
- }else
-
- if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
- || (c=='i' && (strncmp(azArg[0], "indices", n)==0
- || strncmp(azArg[0], "indexes", n)==0) )
- ){
- sqlite3_stmt *pStmt;
- char **azResult;
- int nRow, nAlloc;
- int ii;
- ShellText s;
- initText(&s);
- open_db(p, 0);
- rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
- if( rc ) return shellDatabaseError(p->db);
-
- if( nArg>2 && c=='i' ){
- /* It is an historical accident that the .indexes command shows an error
- ** when called with the wrong number of arguments whereas the .tables
- ** command does not. */
- raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
- rc = 1;
- goto meta_command_exit;
- }
- for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
- const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
- if( zDbName==0 ) continue;
- if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
- if( sqlite3_stricmp(zDbName, "main")==0 ){
- appendText(&s, "SELECT name FROM ", 0);
- }else{
- appendText(&s, "SELECT ", 0);
- appendText(&s, zDbName, '\'');
- appendText(&s, "||'.'||name FROM ", 0);
- }
- appendText(&s, zDbName, '"');
- appendText(&s, ".sqlite_master ", 0);
- if( c=='t' ){
- appendText(&s," WHERE type IN ('table','view')"
- " AND name NOT LIKE 'sqlite_%'"
- " AND name LIKE ?1", 0);
- }else{
- appendText(&s," WHERE type='index'"
- " AND tbl_name LIKE ?1", 0);
- }
- }
- rc = sqlite3_finalize(pStmt);
- appendText(&s, " ORDER BY 1", 0);
- rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
- freeText(&s);
- if( rc ) return shellDatabaseError(p->db);
-
- /* Run the SQL statement prepared by the above block. Store the results
- ** as an array of nul-terminated strings in azResult[]. */
- nRow = nAlloc = 0;
- azResult = 0;
- if( nArg>1 ){
- sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
- }else{
- sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
- }
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- if( nRow>=nAlloc ){
- char **azNew;
- int n2 = nAlloc*2 + 10;
- azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n2);
- if( azNew==0 ){
- rc = shellNomemError();
- break;
- }
- nAlloc = n2;
- azResult = azNew;
- }
- azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
- if( 0==azResult[nRow] ){
- rc = shellNomemError();
- break;
- }
- nRow++;
- }
- if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
- rc = shellDatabaseError(p->db);
- }
-
- /* Pretty-print the contents of array azResult[] to the output */
- if( rc==0 && nRow>0 ){
- int len, maxlen = 0;
- int i, j;
- int nPrintCol, nPrintRow;
- for(i=0; i<nRow; i++){
- len = strlen30(azResult[i]);
- if( len>maxlen ) maxlen = len;
- }
- nPrintCol = 80/(maxlen+2);
- if( nPrintCol<1 ) nPrintCol = 1;
- nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
- for(i=0; i<nPrintRow; i++){
- for(j=i; j<nRow; j+=nPrintRow){
- char *zSp = j<nPrintRow ? "" : " ";
- utf8_printf(p->out, "%s%-*s", zSp, maxlen,
- azResult[j] ? azResult[j]:"");
- }
- raw_printf(p->out, "\n");
- }
- }
-
- for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
- sqlite3_free(azResult);
- }else
-
- /* Begin redirecting output to the file "testcase-out.txt" */
- if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
- output_reset(p);
- p->out = output_file_open("testcase-out.txt");
- if( p->out==0 ){
- raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
- }
- if( nArg>=2 ){
- sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
- }else{
- sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
- }
- }else
-
-#ifndef SQLITE_UNTESTABLE
- if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
- static const struct {
- const char *zCtrlName; /* Name of a test-control option */
- int ctrlCode; /* Integer code for that option */
- } aCtrl[] = {
- { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
- { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
- { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
- { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
- { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
- { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
- { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
- { "assert", SQLITE_TESTCTRL_ASSERT },
- { "always", SQLITE_TESTCTRL_ALWAYS },
- { "reserve", SQLITE_TESTCTRL_RESERVE },
- { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
- { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
- { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
- { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
- { "imposter", SQLITE_TESTCTRL_IMPOSTER },
- };
- int testctrl = -1;
- int rc2 = 0;
- int i, n2;
- open_db(p, 0);
-
- /* convert testctrl text option to value. allow any unique prefix
- ** of the option name, or a numerical value. */
- n2 = strlen30(azArg[1]);
- for(i=0; i<ArraySize(aCtrl); i++){
- if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
- if( testctrl<0 ){
- testctrl = aCtrl[i].ctrlCode;
- }else{
- utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
- testctrl = -1;
- break;
- }
- }
- }
- if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
- if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
- utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
- }else{
- switch(testctrl){
-
- /* sqlite3_test_control(int, db, int) */
- case SQLITE_TESTCTRL_OPTIMIZATIONS:
- case SQLITE_TESTCTRL_RESERVE:
- if( nArg==3 ){
- int opt = (int)strtol(azArg[2], 0, 0);
- rc2 = sqlite3_test_control(testctrl, p->db, opt);
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- } else {
- utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
- azArg[1]);
- }
- break;
-
- /* sqlite3_test_control(int) */
- case SQLITE_TESTCTRL_PRNG_SAVE:
- case SQLITE_TESTCTRL_PRNG_RESTORE:
- case SQLITE_TESTCTRL_PRNG_RESET:
- case SQLITE_TESTCTRL_BYTEORDER:
- if( nArg==2 ){
- rc2 = sqlite3_test_control(testctrl);
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- } else {
- utf8_printf(stderr,"Error: testctrl %s takes no options\n",
- azArg[1]);
- }
- break;
-
- /* sqlite3_test_control(int, uint) */
- case SQLITE_TESTCTRL_PENDING_BYTE:
- if( nArg==3 ){
- unsigned int opt = (unsigned int)integerValue(azArg[2]);
- rc2 = sqlite3_test_control(testctrl, opt);
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- } else {
- utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
- " int option\n", azArg[1]);
- }
- break;
-
- /* sqlite3_test_control(int, int) */
- case SQLITE_TESTCTRL_ASSERT:
- case SQLITE_TESTCTRL_ALWAYS:
- case SQLITE_TESTCTRL_NEVER_CORRUPT:
- if( nArg==3 ){
- int opt = booleanValue(azArg[2]);
- rc2 = sqlite3_test_control(testctrl, opt);
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- } else {
- utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
- azArg[1]);
- }
- break;
-
- /* sqlite3_test_control(int, char *) */
-#ifdef SQLITE_N_KEYWORD
- case SQLITE_TESTCTRL_ISKEYWORD:
- if( nArg==3 ){
- const char *opt = azArg[2];
- rc2 = sqlite3_test_control(testctrl, opt);
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- } else {
- utf8_printf(stderr,
- "Error: testctrl %s takes a single char * option\n",
- azArg[1]);
- }
- break;
-#endif
-
- case SQLITE_TESTCTRL_IMPOSTER:
- if( nArg==5 ){
- rc2 = sqlite3_test_control(testctrl, p->db,
- azArg[2],
- integerValue(azArg[3]),
- integerValue(azArg[4]));
- raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
- }else{
- raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
- }
- break;
-
- case SQLITE_TESTCTRL_BITVEC_TEST:
- case SQLITE_TESTCTRL_FAULT_INSTALL:
- case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
- default:
- utf8_printf(stderr,
- "Error: CLI support for testctrl %s not implemented\n",
- azArg[1]);
- break;
- }
- }
- }else
-#endif /* !defined(SQLITE_UNTESTABLE) */
-
- if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
- 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]);
- if( enableTimer && !HAS_TIMER ){
- raw_printf(stderr, "Error: timer not available on this system.\n");
- enableTimer = 0;
- }
- }else{
- raw_printf(stderr, "Usage: .timer on|off\n");
- rc = 1;
- }
- }else
-
- if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
- open_db(p, 0);
- if( nArg!=2 ){
- raw_printf(stderr, "Usage: .trace FILE|off\n");
- rc = 1;
- goto meta_command_exit;
- }
- output_file_close(p->traceOut);
- p->traceOut = output_file_open(azArg[1]);
-#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
- if( p->traceOut==0 ){
- sqlite3_trace_v2(p->db, 0, 0, 0);
- }else{
- sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
- }
-#endif
- }else
-
-#if SQLITE_USER_AUTHENTICATION
- if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
- if( nArg<2 ){
- raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
- rc = 1;
- goto meta_command_exit;
- }
- open_db(p, 0);
- if( strcmp(azArg[1],"login")==0 ){
- if( nArg!=4 ){
- raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
- rc = 1;
- goto meta_command_exit;
- }
- rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
- (int)strlen(azArg[3]));
- if( rc ){
- utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
- rc = 1;
- }
- }else if( strcmp(azArg[1],"add")==0 ){
- if( nArg!=5 ){
- raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
- rc = 1;
- goto meta_command_exit;
- }
- rc = sqlite3_user_add(p->db, azArg[2],
- azArg[3], (int)strlen(azArg[3]),
- booleanValue(azArg[4]));
- if( rc ){
- raw_printf(stderr, "User-Add failed: %d\n", rc);
- rc = 1;
- }
- }else if( strcmp(azArg[1],"edit")==0 ){
- if( nArg!=5 ){
- raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
- rc = 1;
- goto meta_command_exit;
- }
- rc = sqlite3_user_change(p->db, azArg[2],
- azArg[3], (int)strlen(azArg[3]),
- booleanValue(azArg[4]));
- if( rc ){
- raw_printf(stderr, "User-Edit failed: %d\n", rc);
- rc = 1;
- }
- }else if( strcmp(azArg[1],"delete")==0 ){
- if( nArg!=3 ){
- raw_printf(stderr, "Usage: .user delete USER\n");
- rc = 1;
- goto meta_command_exit;
- }
- rc = sqlite3_user_delete(p->db, azArg[2]);
- if( rc ){
- raw_printf(stderr, "User-Delete failed: %d\n", rc);
- rc = 1;
- }
- }else{
- raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
- rc = 1;
- goto meta_command_exit;
- }
- }else
-#endif /* SQLITE_USER_AUTHENTICATION */
-
- if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
- utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
- sqlite3_libversion(), sqlite3_sourceid());
- }else
-
- if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
- const char *zDbName = nArg==2 ? azArg[1] : "main";
- sqlite3_vfs *pVfs = 0;
- if( p->db ){
- sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
- if( pVfs ){
- utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
- raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
- raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
- raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
- }
- }
- }else
-
- if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
- sqlite3_vfs *pVfs;
- sqlite3_vfs *pCurrent = 0;
- if( p->db ){
- sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
- }
- for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
- utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
- pVfs==pCurrent ? " <--- CURRENT" : "");
- raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
- raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
- raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
- if( pVfs->pNext ){
- raw_printf(p->out, "-----------------------------------\n");
- }
- }
- }else
-
- if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
- const char *zDbName = nArg==2 ? azArg[1] : "main";
- char *zVfsName = 0;
- if( p->db ){
- sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
- if( zVfsName ){
- utf8_printf(p->out, "%s\n", zVfsName);
- sqlite3_free(zVfsName);
- }
- }
- }else
-
-#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
- if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
- sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
- }else
-#endif
-
- if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
- int j;
- assert( nArg<=ArraySize(azArg) );
- for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
- p->colWidth[j-1] = (int)integerValue(azArg[j]);
- }
- }else
-
- {
- utf8_printf(stderr, "Error: unknown command or invalid arguments: "
- " \"%s\". Enter \".help\" for help\n", azArg[0]);
- rc = 1;
- }
-
-meta_command_exit:
- if( p->outCount ){
- p->outCount--;
- if( p->outCount==0 ) output_reset(p);
- }
- return rc;
-}
-
-/*
-** Return TRUE if a semicolon occurs anywhere in the first N characters
-** of string z[].
-*/
-static int line_contains_semicolon(const char *z, int N){
- int i;
- for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
- return 0;
-}
-
-/*
-** Test to see if a line consists entirely of whitespace.
-*/
-static int _all_whitespace(const char *z){
- for(; *z; z++){
- if( IsSpace(z[0]) ) continue;
- if( *z=='/' && z[1]=='*' ){
- z += 2;
- while( *z && (*z!='*' || z[1]!='/') ){ z++; }
- if( *z==0 ) return 0;
- z++;
- continue;
- }
- if( *z=='-' && z[1]=='-' ){
- z += 2;
- while( *z && *z!='\n' ){ z++; }
- if( *z==0 ) return 1;
- continue;
- }
- return 0;
- }
- return 1;
-}
-
-/*
-** Return TRUE if the line typed in is an SQL command terminator other
-** than a semi-colon. The SQL Server style "go" command is understood
-** as is the Oracle "/".
-*/
-static int line_is_command_terminator(const char *zLine){
- while( IsSpace(zLine[0]) ){ zLine++; };
- if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
- return 1; /* Oracle */
- }
- if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
- && _all_whitespace(&zLine[2]) ){
- return 1; /* SQL Server */
- }
- return 0;
-}
-
-/*
-** Return true if zSql is a complete SQL statement. Return false if it
-** ends in the middle of a string literal or C-style comment.
-*/
-static int line_is_complete(char *zSql, int nSql){
- int rc;
- if( zSql==0 ) return 1;
- zSql[nSql] = ';';
- zSql[nSql+1] = 0;
- rc = sqlite3_complete(zSql);
- zSql[nSql] = 0;
- return rc;
-}
-
-/*
-** Run a single line of SQL
-*/
-static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
- int rc;
- char *zErrMsg = 0;
-
- open_db(p, 0);
- if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
- BEGIN_TIMER;
- rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
- END_TIMER;
- if( rc || zErrMsg ){
- char zPrefix[100];
- if( in!=0 || !stdin_is_interactive ){
- sqlite3_snprintf(sizeof(zPrefix), zPrefix,
- "Error: near line %d:", startline);
- }else{
- sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
- }
- if( zErrMsg!=0 ){
- utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
- sqlite3_free(zErrMsg);
- zErrMsg = 0;
- }else{
- utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
- }
- return 1;
- }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
- raw_printf(p->out, "changes: %3d total_changes: %d\n",
- sqlite3_changes(p->db), sqlite3_total_changes(p->db));
- }
- return 0;
-}
-
-
-/*
-** Read input from *in and process it. If *in==0 then input
-** is interactive - the user is typing it it. Otherwise, input
-** is coming from a file or device. A prompt is issued and history
-** is saved only if input is interactive. An interrupt signal will
-** cause this routine to exit immediately, unless input is interactive.
-**
-** Return the number of errors.
-*/
-static int process_input(ShellState *p, FILE *in){
- char *zLine = 0; /* A single input line */
- char *zSql = 0; /* Accumulated SQL text */
- int nLine; /* Length of current line */
- int nSql = 0; /* Bytes of zSql[] used */
- int nAlloc = 0; /* Allocated zSql[] space */
- int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
- int rc; /* Error code */
- int errCnt = 0; /* Number of errors seen */
- int lineno = 0; /* Current line number */
- int startline = 0; /* Line number for start of current input */
-
- while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
- fflush(p->out);
- zLine = one_input_line(in, zLine, nSql>0);
- if( zLine==0 ){
- /* End of input */
- if( in==0 && stdin_is_interactive ) printf("\n");
- break;
- }
- if( seenInterrupt ){
- if( in!=0 ) break;
- seenInterrupt = 0;
- }
- lineno++;
- if( nSql==0 && _all_whitespace(zLine) ){
- if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
- continue;
- }
- if( zLine && zLine[0]=='.' && nSql==0 ){
- if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
- rc = do_meta_command(zLine, p);
- if( rc==2 ){ /* exit requested */
- break;
- }else if( rc ){
- errCnt++;
- }
- continue;
- }
- if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
- memcpy(zLine,";",2);
- }
- nLine = strlen30(zLine);
- if( nSql+nLine+2>=nAlloc ){
- nAlloc = nSql+nLine+100;
- zSql = realloc(zSql, nAlloc);
- if( zSql==0 ){
- raw_printf(stderr, "Error: out of memory\n");
- exit(1);
- }
- }
- nSqlPrior = nSql;
- if( nSql==0 ){
- int i;
- for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
- assert( nAlloc>0 && zSql!=0 );
- memcpy(zSql, zLine+i, nLine+1-i);
- startline = lineno;
- nSql = nLine-i;
- }else{
- zSql[nSql++] = '\n';
- memcpy(zSql+nSql, zLine, nLine+1);
- nSql += nLine;
- }
- if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
- && sqlite3_complete(zSql) ){
- errCnt += runOneSqlLine(p, zSql, in, startline);
- nSql = 0;
- if( p->outCount ){
- output_reset(p);
- p->outCount = 0;
- }
- }else if( nSql && _all_whitespace(zSql) ){
- if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
- nSql = 0;
- }
- }
- if( nSql && !_all_whitespace(zSql) ){
- runOneSqlLine(p, zSql, in, startline);
- }
- free(zSql);
- free(zLine);
- return errCnt>0;
-}
-
-/*
-** Return a pathname which is the user's home directory. A
-** 0 return indicates an error of some kind.
-*/
-static char *find_home_dir(int clearFlag){
- static char *home_dir = NULL;
- if( clearFlag ){
- free(home_dir);
- home_dir = 0;
- return 0;
- }
- if( home_dir ) return home_dir;
-
-#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
- && !defined(__RTP__) && !defined(_WRS_KERNEL)
- {
- struct passwd *pwent;
- uid_t uid = getuid();
- if( (pwent=getpwuid(uid)) != NULL) {
- home_dir = pwent->pw_dir;
- }
- }
-#endif
-
-#if defined(_WIN32_WCE)
- /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
- */
- home_dir = "/";
-#else
-
-#if defined(_WIN32) || defined(WIN32)
- if (!home_dir) {
- home_dir = getenv("USERPROFILE");
- }
-#endif
-
- if (!home_dir) {
- home_dir = getenv("HOME");
- }
-
-#if defined(_WIN32) || defined(WIN32)
- if (!home_dir) {
- char *zDrive, *zPath;
- int n;
- zDrive = getenv("HOMEDRIVE");
- zPath = getenv("HOMEPATH");
- if( zDrive && zPath ){
- n = strlen30(zDrive) + strlen30(zPath) + 1;
- home_dir = malloc( n );
- if( home_dir==0 ) return 0;
- sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
- return home_dir;
- }
- home_dir = "c:\\";
- }
-#endif
-
-#endif /* !_WIN32_WCE */
-
- if( home_dir ){
- int n = strlen30(home_dir) + 1;
- char *z = malloc( n );
- if( z ) memcpy(z, home_dir, n);
- home_dir = z;
- }
-
- return home_dir;
-}
-
-/*
-** Read input from the file given by sqliterc_override. Or if that
-** parameter is NULL, take input from ~/.sqliterc
-**
-** Returns the number of errors.
-*/
-static void process_sqliterc(
- ShellState *p, /* Configuration data */
- const char *sqliterc_override /* Name of config file. NULL to use default */
-){
- char *home_dir = NULL;
- const char *sqliterc = sqliterc_override;
- char *zBuf = 0;
- FILE *in = NULL;
-
- if (sqliterc == NULL) {
- home_dir = find_home_dir(0);
- if( home_dir==0 ){
- raw_printf(stderr, "-- warning: cannot find home directory;"
- " cannot read ~/.sqliterc\n");
- return;
- }
- sqlite3_initialize();
- zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
- sqliterc = zBuf;
- }
- in = fopen(sqliterc,"rb");
- if( in ){
- if( stdin_is_interactive ){
- utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
- }
- process_input(p,in);
- fclose(in);
- }
- sqlite3_free(zBuf);
-}
-
-/*
-** Show available command line options
-*/
-static const char zOptions[] =
- " -ascii set output mode to 'ascii'\n"
- " -bail stop after hitting an error\n"
- " -batch force batch I/O\n"
- " -column set output mode to 'column'\n"
- " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
- " -csv set output mode to 'csv'\n"
- " -echo print commands before execution\n"
- " -init FILENAME read/process named file\n"
- " -[no]header turn headers on or off\n"
-#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
- " -heap SIZE Size of heap for memsys3 or memsys5\n"
-#endif
- " -help show this message\n"
- " -html set output mode to HTML\n"
- " -interactive force interactive I/O\n"
- " -line set output mode to 'line'\n"
- " -list set output mode to 'list'\n"
-#ifndef SQLITE_OMIT_LOOKASIDE
- " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
-#endif
- " -mmap N default mmap size set to N\n"
-#ifdef SQLITE_ENABLE_MULTIPLEX
- " -multiplex enable the multiplexor VFS\n"
-#endif
- " -newline SEP set output row separator. Default: '\\n'\n"
- " -nullvalue TEXT set text string for NULL values. Default ''\n"
- " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
- " -quote set output mode to 'quote'\n"
- " -scanstats print scan stats before each finalize\n"
- " -separator SEP set output column separator. Default: '|'\n"
- " -stats print memory stats before each finalize\n"
- " -version show SQLite version\n"
- " -vfs NAME use NAME as the default VFS\n"
-#ifdef SQLITE_ENABLE_VFSTRACE
- " -vfstrace enable tracing of all VFS calls\n"
-#endif
-;
-static void usage(int showDetail){
- utf8_printf(stderr,
- "Usage: %s [OPTIONS] FILENAME [SQL]\n"
- "FILENAME is the name of an SQLite database. A new database is created\n"
- "if the file does not previously exist.\n", Argv0);
- if( showDetail ){
- utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
- }else{
- raw_printf(stderr, "Use the -help option for additional information\n");
- }
- exit(1);
-}
-
-/*
-** Initialize the state information in data
-*/
-static void main_init(ShellState *data) {
- memset(data, 0, sizeof(*data));
- data->normalMode = data->cMode = data->mode = MODE_List;
- data->autoExplain = 1;
- memcpy(data->colSeparator,SEP_Column, 2);
- memcpy(data->rowSeparator,SEP_Row, 2);
- data->showHeader = 0;
- data->shellFlgs = SHFLG_Lookaside;
- sqlite3_config(SQLITE_CONFIG_URI, 1);
- sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
- sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
- sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
- sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
-}
-
-/*
-** Output text to the console in a font that attracts extra attention.
-*/
-#ifdef _WIN32
-static void printBold(const char *zText){
- HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
- GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
- SetConsoleTextAttribute(out,
- FOREGROUND_RED|FOREGROUND_INTENSITY
- );
- printf("%s", zText);
- SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
-}
-#else
-static void printBold(const char *zText){
- printf("\033[1m%s\033[0m", zText);
-}
-#endif
-
-/*
-** Get the argument to an --option. Throw an error and die if no argument
-** is available.
-*/
-static char *cmdline_option_value(int argc, char **argv, int i){
- if( i==argc ){
- utf8_printf(stderr, "%s: Error: missing argument to %s\n",
- argv[0], argv[argc-1]);
- exit(1);
- }
- return argv[i];
-}
-
-#if defined(_WIN32) && defined(__MSVCRT__) && !defined(main)
-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;
- int i;
- int rc = 0;
- int warnInmemoryDb = 0;
- int readStdin = 1;
- 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( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
- utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
- sqlite3_sourceid(), SQLITE_SOURCE_ID);
- exit(1);
- }
-#endif
- main_init(&data);
-#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.
- */
-#if defined(WIN32) || defined(_WIN32)
- SetConsoleCtrlHandler(CtrlHandler, TRUE);
-#elif defined(SIGINT)
- signal(SIGINT, interrupt_handler);
-#endif
-
-#ifdef SQLITE_SHELL_DBNAME_PROC
- {
- /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
- ** of a C-function that will provide the name of the database file. Use
- ** this compile-time option to embed this shell program in larger
- ** applications. */
- extern void SQLITE_SHELL_DBNAME_PROC(const char**);
- SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
- warnInmemoryDb = 0;
- }
-#endif
-
- /* Do an initial pass through the command-line argument to locate
- ** the name of the database file, the name of the initialization file,
- ** the size of the alternative malloc heap,
- ** and the first command to execute.
- */
- for(i=1; i<argc; i++){
- char *z;
- z = argv[i];
- if( z[0]!='-' ){
- if( data.zDbFilename==0 ){
- data.zDbFilename = z;
- }else{
- /* Excesss arguments are interpreted as SQL (or dot-commands) and
- ** mean that nothing is read from stdin */
- readStdin = 0;
- nCmd++;
- azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
- if( azCmd==0 ){
- raw_printf(stderr, "out of memory\n");
- exit(1);
- }
- azCmd[nCmd-1] = z;
- }
- }
- if( z[1]=='-' ) z++;
- if( strcmp(z,"-separator")==0
- || strcmp(z,"-nullvalue")==0
- || strcmp(z,"-newline")==0
- || strcmp(z,"-cmd")==0
- ){
- (void)cmdline_option_value(argc, argv, ++i);
- }else if( strcmp(z,"-init")==0 ){
- 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
- ** we do the actual processing of arguments later in a second pass.
- */
- stdin_is_interactive = 0;
- }else if( strcmp(z,"-heap")==0 ){
-#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
- const char *zSize;
- sqlite3_int64 szHeap;
-
- zSize = cmdline_option_value(argc, argv, ++i);
- szHeap = integerValue(zSize);
- if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
- sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
-#else
- (void)cmdline_option_value(argc, argv, ++i);
-#endif
- }else if( strcmp(z,"-pagecache")==0 ){
- int n, sz;
- sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
- if( sz>70000 ) sz = 70000;
- if( sz<0 ) sz = 0;
- n = (int)integerValue(cmdline_option_value(argc,argv,++i));
- sqlite3_config(SQLITE_CONFIG_PAGECACHE,
- (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
- data.shellFlgs |= SHFLG_Pagecache;
- }else if( strcmp(z,"-lookaside")==0 ){
- int n, sz;
- sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
- if( sz<0 ) sz = 0;
- n = (int)integerValue(cmdline_option_value(argc,argv,++i));
- if( n<0 ) n = 0;
- sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
- if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
-#ifdef SQLITE_ENABLE_VFSTRACE
- }else if( strcmp(z,"-vfstrace")==0 ){
- extern int vfstrace_register(
- const char *zTraceName,
- const char *zOldVfsName,
- int (*xOut)(const char*,void*),
- void *pOutArg,
- int makeDefault
- );
- vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
-#endif
-#ifdef SQLITE_ENABLE_MULTIPLEX
- }else if( strcmp(z,"-multiplex")==0 ){
- extern int sqlite3_multiple_initialize(const char*,int);
- sqlite3_multiplex_initialize(0, 1);
-#endif
- }else if( strcmp(z,"-mmap")==0 ){
- sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
- sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
- }else if( strcmp(z,"-vfs")==0 ){
- sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
- if( pVfs ){
- sqlite3_vfs_register(pVfs, 1);
- }else{
- utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
- exit(1);
- }
- }
- }
- if( data.zDbFilename==0 ){
-#ifndef SQLITE_OMIT_MEMORYDB
- data.zDbFilename = ":memory:";
- warnInmemoryDb = argc==1;
-#else
- utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
- return 1;
-#endif
- }
- data.out = stdout;
-
- /* Go ahead and open the database file if it already exists. If the
- ** file does not exist, delay opening it. This prevents empty database
- ** files from being created if a user mistypes the database name argument
- ** to the sqlite command-line tool.
- */
- if( access(data.zDbFilename, 0)==0 ){
- open_db(&data, 0);
- }
-
- /* Process the initialization file if there is one. If no -init option
- ** is given on the command line, look for a file named ~/.sqliterc and
- ** try to process it.
- */
- process_sqliterc(&data,zInitFile);
-
- /* Make a second pass through the command-line argument and set
- ** options. This second pass is delayed until after the initialization
- ** file is processed so that the command-line arguments will override
- ** settings in the initialization file.
- */
- for(i=1; i<argc; i++){
- char *z = argv[i];
- if( z[0]!='-' ) continue;
- if( z[1]=='-' ){ z++; }
- if( strcmp(z,"-init")==0 ){
- i++;
- }else if( strcmp(z,"-html")==0 ){
- data.mode = MODE_Html;
- }else if( strcmp(z,"-list")==0 ){
- data.mode = MODE_List;
- }else if( strcmp(z,"-quote")==0 ){
- data.mode = MODE_Quote;
- }else if( strcmp(z,"-line")==0 ){
- data.mode = MODE_Line;
- }else if( strcmp(z,"-column")==0 ){
- data.mode = MODE_Column;
- }else if( strcmp(z,"-csv")==0 ){
- data.mode = MODE_Csv;
- memcpy(data.colSeparator,",",2);
- }else if( strcmp(z,"-ascii")==0 ){
- data.mode = MODE_Ascii;
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
- SEP_Unit);
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
- SEP_Record);
- }else if( strcmp(z,"-separator")==0 ){
- sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
- "%s",cmdline_option_value(argc,argv,++i));
- }else if( strcmp(z,"-newline")==0 ){
- sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
- "%s",cmdline_option_value(argc,argv,++i));
- }else if( strcmp(z,"-nullvalue")==0 ){
- sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
- "%s",cmdline_option_value(argc,argv,++i));
- }else if( strcmp(z,"-header")==0 ){
- data.showHeader = 1;
- }else if( strcmp(z,"-noheader")==0 ){
- data.showHeader = 0;
- }else if( strcmp(z,"-echo")==0 ){
- ShellSetFlag(&data, SHFLG_Echo);
- }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 ){
- data.scanstatsOn = 1;
- }else if( strcmp(z,"-backslash")==0 ){
- /* Undocumented command-line option: -backslash
- ** Causes C-style backslash escapes to be evaluated in SQL statements
- ** prior to sending the SQL into SQLite. Useful for injecting
- ** crazy bytes in the middle of SQL statements for testing and debugging.
- */
- ShellSetFlag(&data, SHFLG_Backslash);
- }else if( strcmp(z,"-bail")==0 ){
- bail_on_error = 1;
- }else if( strcmp(z,"-version")==0 ){
- printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
- return 0;
- }else if( strcmp(z,"-interactive")==0 ){
- stdin_is_interactive = 1;
- }else if( strcmp(z,"-batch")==0 ){
- stdin_is_interactive = 0;
- }else if( strcmp(z,"-heap")==0 ){
- i++;
- }else if( strcmp(z,"-pagecache")==0 ){
- i+=2;
- }else if( strcmp(z,"-lookaside")==0 ){
- i+=2;
- }else if( strcmp(z,"-mmap")==0 ){
- i++;
- }else if( strcmp(z,"-vfs")==0 ){
- i++;
-#ifdef SQLITE_ENABLE_VFSTRACE
- }else if( strcmp(z,"-vfstrace")==0 ){
- i++;
-#endif
-#ifdef SQLITE_ENABLE_MULTIPLEX
- }else if( strcmp(z,"-multiplex")==0 ){
- i++;
-#endif
- }else if( strcmp(z,"-help")==0 ){
- usage(1);
- }else if( strcmp(z,"-cmd")==0 ){
- /* Run commands that follow -cmd first and separately from commands
- ** that simply appear on the command-line. This seems goofy. It would
- ** be better if all commands ran in the order that they appear. But
- ** we retain the goofy behavior for historical compatibility. */
- if( i==argc-1 ) break;
- z = cmdline_option_value(argc,argv,++i);
- if( z[0]=='.' ){
- rc = do_meta_command(z, &data);
- if( rc && bail_on_error ) return rc==2 ? 0 : rc;
- }else{
- open_db(&data, 0);
- rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
- if( zErrMsg!=0 ){
- utf8_printf(stderr,"Error: %s\n", zErrMsg);
- if( bail_on_error ) return rc!=0 ? rc : 1;
- }else if( rc!=0 ){
- utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
- if( bail_on_error ) return rc;
- }
- }
- }else{
- utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
- raw_printf(stderr,"Use -help for a list of options.\n");
- return 1;
- }
- data.cMode = data.mode;
- }
-
- if( !readStdin ){
- /* Run all arguments that do not begin with '-' as if they were separate
- ** command-line inputs, except for the argToSkip argument which contains
- ** the database filename.
- */
- for(i=0; i<nCmd; i++){
- if( azCmd[i][0]=='.' ){
- rc = do_meta_command(azCmd[i], &data);
- if( rc ) return rc==2 ? 0 : rc;
- }else{
- open_db(&data, 0);
- rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
- if( zErrMsg!=0 ){
- utf8_printf(stderr,"Error: %s\n", zErrMsg);
- return rc!=0 ? rc : 1;
- }else if( rc!=0 ){
- utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
- return rc;
- }
- }
- }
- free(azCmd);
- }else{
- /* Run commands received from standard input
- */
- if( stdin_is_interactive ){
- char *zHome;
- char *zHistory = 0;
- int nHistory;
- printf(
- "SQLite version %s %.19s\n" /*extra-version-info*/
- "Enter \".help\" for usage hints.\n",
- sqlite3_libversion(), sqlite3_sourceid()
- );
- if( warnInmemoryDb ){
- printf("Connected to a ");
- printBold("transient in-memory database");
- printf(".\nUse \".open FILENAME\" to reopen on a "
- "persistent database.\n");
- }
- zHome = find_home_dir(0);
- if( zHome ){
- nHistory = strlen30(zHome) + 20;
- if( (zHistory = malloc(nHistory))!=0 ){
- sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
- }
- }
- if( zHistory ){ shell_read_history(zHistory); }
-#if HAVE_READLINE || HAVE_EDITLINE
- rl_attempted_completion_function = readline_completion;
-#elif HAVE_LINENOISE
- linenoiseSetCompletionCallback(linenoise_completion);
-#endif
- rc = process_input(&data, 0);
- if( zHistory ){
- shell_stifle_history(2000);
- shell_write_history(zHistory);
- free(zHistory);
- }
- }else{
- rc = process_input(&data, stdin);
- }
- }
- set_table_name(&data, 0);
- if( data.db ){
- session_close_all(&data);
- sqlite3_close(data.db);
- }
- sqlite3_free(data.zFreeOnClose);
- find_home_dir(1);
-#if !SQLITE_SHELL_IS_UTF8
- for(i=0; i<argc; i++) sqlite3_free(argv[i]);
- sqlite3_free(argv);
-#endif
- return rc;
-}
diff --git a/tcl8.6/pkgs/sqlite3.21.0/tclconfig/tcl.m4 b/tcl8.6/pkgs/sqlite3.21.0/tclconfig/tcl.m4
deleted file mode 100644
index 203a05d..0000000
--- a/tcl8.6/pkgs/sqlite3.21.0/tclconfig/tcl.m4
+++ /dev/null
@@ -1,4241 +0,0 @@
-# tcl.m4 --
-#
-# This file provides a set of autoconf macros to help TEA-enable
-# a Tcl extension.
-#
-# Copyright (c) 1999-2000 Ajuba Solutions.
-# Copyright (c) 2002-2005 ActiveState Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-
-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.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
-#
-
-#------------------------------------------------------------------------
-# TEA_PATH_TCLCONFIG --
-#
-# Locate the tclConfig.sh file and perform a sanity check on
-# the Tcl compile flags
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tcl=...
-#
-# Defines the following vars:
-# TCL_BIN_DIR Full path to the directory containing
-# the tclConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TCLCONFIG], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
- #
- # Ok, lets find the tcl configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tcl
- #
-
- if test x"${no_tcl}" = x ; then
- # we reset no_tcl in case something fails here
- no_tcl=true
- AC_ARG_WITH(tcl,
- AC_HELP_STRING([--with-tcl],
- [directory containing tcl configuration (tclConfig.sh)]),
- with_tclconfig="${withval}")
- AC_MSG_CHECKING([for Tcl configuration])
- AC_CACHE_VAL(ac_cv_c_tclconfig,[
-
- # First check to see if --with-tcl was specified.
- if test x"${with_tclconfig}" != x ; then
- case "${with_tclconfig}" in
- */tclConfig.sh )
- if test -f "${with_tclconfig}"; then
- AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
- with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tclconfig}/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
- fi
- fi
-
- # then check for a private Tcl installation
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in \
- ../tcl \
- `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tcl \
- `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tcl \
- `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tcl.framework/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `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
- ])
-
- if test x"${ac_cv_c_tclconfig}" = x ; then
- TCL_BIN_DIR="# no Tcl configs found"
- AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
- else
- no_tcl=
- TCL_BIN_DIR="${ac_cv_c_tclconfig}"
- AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_TKCONFIG --
-#
-# Locate the tkConfig.sh file
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tk=...
-#
-# Defines the following vars:
-# TK_BIN_DIR Full path to the directory containing
-# the tkConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TKCONFIG], [
- #
- # Ok, lets find the tk configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tk
- #
-
- if test x"${no_tk}" = x ; then
- # we reset no_tk in case something fails here
- no_tk=true
- AC_ARG_WITH(tk,
- AC_HELP_STRING([--with-tk],
- [directory containing tk configuration (tkConfig.sh)]),
- with_tkconfig="${withval}")
- AC_MSG_CHECKING([for Tk configuration])
- AC_CACHE_VAL(ac_cv_c_tkconfig,[
-
- # First check to see if --with-tkconfig was specified.
- if test x"${with_tkconfig}" != x ; then
- case "${with_tkconfig}" in
- */tkConfig.sh )
- if test -f "${with_tkconfig}"; then
- AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
- with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tkconfig}/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
- fi
- fi
-
- # then check for a private Tk library
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ../tk \
- `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tk \
- `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tk \
- `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tk.framework/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few other private locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_tkconfig}" = x ; then
- TK_BIN_DIR="# no Tk configs found"
- AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
- else
- no_tk=
- TK_BIN_DIR="${ac_cv_c_tkconfig}"
- AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TCLCONFIG --
-#
-# Load the tclConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TCL_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_BIN_DIR
-# TCL_SRC_DIR
-# TCL_LIB_FILE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TCLCONFIG], [
- AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
-
- if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TCL_BIN_DIR}/tclConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
- eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
-
- # If the TCL_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TCL_LIB_SPEC will be set to the value
- # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
- # instead of TCL_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
- TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
- TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tcl.framework installed in an arbitrary location.
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
- for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
- "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
- TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
- TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
- TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
- eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
- eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
- eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
-
- AC_SUBST(TCL_VERSION)
- AC_SUBST(TCL_PATCH_LEVEL)
- AC_SUBST(TCL_BIN_DIR)
- AC_SUBST(TCL_SRC_DIR)
-
- AC_SUBST(TCL_LIB_FILE)
- AC_SUBST(TCL_LIB_FLAG)
- AC_SUBST(TCL_LIB_SPEC)
-
- AC_SUBST(TCL_STUB_LIB_FILE)
- AC_SUBST(TCL_STUB_LIB_FLAG)
- AC_SUBST(TCL_STUB_LIB_SPEC)
-
- AC_MSG_CHECKING([platform])
- hold_cc=$CC; CC="$TCL_CC"
- AC_TRY_COMPILE(,[
- #ifdef _WIN32
- #error win32
- #endif
- ], [
- TEA_PLATFORM="unix"
- CYGPATH=echo
- ], [
- TEA_PLATFORM="windows"
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
- )
- CC=$hold_cc
- AC_MSG_RESULT($TEA_PLATFORM)
-
- # The BUILD_$pkg is to define the correct extern storage class
- # handling when making this package
- AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
- [Building extension source?])
- # 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:
- AC_SUBST(CLEANFILES)
- AC_SUBST(TCL_LIBS)
- AC_SUBST(TCL_DEFS)
- AC_SUBST(TCL_EXTRA_CFLAGS)
- AC_SUBST(TCL_LD_FLAGS)
- AC_SUBST(TCL_SHLIB_LD_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TKCONFIG --
-#
-# Load the tkConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TK_BIN_DIR
-#
-# Results:
-#
-# Sets the following vars that should be in tkConfig.sh:
-# TK_BIN_DIR
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TKCONFIG], [
- AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
-
- if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TK_BIN_DIR}/tkConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
- eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
-
- # If the TK_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TK_LIB_SPEC will be set to the value
- # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
- # instead of TK_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
- TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
- TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tk.framework installed in an arbitrary location.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
- for i in "`cd "${TK_BIN_DIR}"; pwd`" \
- "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
- TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
- TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
- TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
- eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
- eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
- eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
-
- # TEA specific: Ensure windowingsystem is defined
- if test "${TEA_PLATFORM}" = "unix" ; then
- case ${TK_DEFS} in
- *MAC_OSX_TK*)
- AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
- TEA_WINDOWINGSYSTEM="aqua"
- ;;
- *)
- TEA_WINDOWINGSYSTEM="x11"
- ;;
- esac
- elif test "${TEA_PLATFORM}" = "windows" ; then
- TEA_WINDOWINGSYSTEM="win32"
- fi
-
- AC_SUBST(TK_VERSION)
- AC_SUBST(TK_BIN_DIR)
- AC_SUBST(TK_SRC_DIR)
-
- AC_SUBST(TK_LIB_FILE)
- AC_SUBST(TK_LIB_FLAG)
- AC_SUBST(TK_LIB_SPEC)
-
- AC_SUBST(TK_STUB_LIB_FILE)
- AC_SUBST(TK_STUB_LIB_FLAG)
- AC_SUBST(TK_STUB_LIB_SPEC)
-
- # TEA specific:
- AC_SUBST(TK_LIBS)
- AC_SUBST(TK_XINCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_TCLSH
-# Determine the fully qualified path name of the tclsh executable
-# in the Tcl build directory or the tclsh installed in a bin
-# directory. This macro will correctly determine the name
-# of the tclsh executable even if tclsh has not yet been
-# built in the build directory. The tclsh found is always
-# associated with a tclConfig.sh file. This tclsh should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCLSH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_TCLSH], [
- AC_MSG_CHECKING([for tclsh])
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- # tclConfig.sh is in Tcl build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- AC_MSG_RESULT([${TCLSH_PROG}])
- AC_SUBST(TCLSH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_WISH
-# Determine the fully qualified path name of the wish executable
-# in the Tk build directory or the wish installed in a bin
-# directory. This macro will correctly determine the name
-# of the wish executable even if wish has not yet been
-# built in the build directory. The wish found is always
-# associated with a tkConfig.sh file. This wish should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# WISH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_WISH], [
- AC_MSG_CHECKING([for wish])
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- # tkConfig.sh is in Tk build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- else
- # tkConfig.sh is in install location
- if test "${TEA_PLATFORM}" = "windows"; then
- WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
- else
- WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
- fi
- list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
- `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
- for i in $list ; do
- if test -f "$i/${WISH_PROG}" ; then
- REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
- break
- fi
- done
- WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
- fi
- AC_MSG_RESULT([${WISH_PROG}])
- AC_SUBST(WISH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SHARED --
-#
-# Allows the building of shared libraries
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-shared=yes|no
-# --enable-stubs=yes|no
-#
-# Defines the following vars:
-# STATIC_BUILD Used for building import/export libraries
-# on Windows.
-#
-# Sets the following vars:
-# SHARED_BUILD Value of 1 or 0
-# 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)]),
- [shared_ok=$enableval], [shared_ok=yes])
-
- if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
- shared_ok=$enableval
- else
- 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
-
- # 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, [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)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_THREADS --
-#
-# Specify if thread support should be enabled. If "yes" is specified
-# as an arg (optional), threads are enabled by default, "no" means
-# threads are disabled. "yes" is the default.
-#
-# TCL_THREADS is checked so that if you are compiling an extension
-# against a threaded core, your extension must be compiled threaded
-# as well.
-#
-# Note that it is legal to have a thread enabled extension run in a
-# threaded or non-threaded Tcl core, but a non-threaded extension may
-# only run in a non-threaded Tcl core.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-threads
-#
-# Sets the following vars:
-# THREADS_LIBS Thread library(s)
-#
-# Defines the following vars:
-# TCL_THREADS
-# _REENTRANT
-# _THREAD_SAFE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_THREADS], [
- AC_ARG_ENABLE(threads,
- AC_HELP_STRING([--enable-threads],
- [build with threads]),
- [tcl_ok=$enableval], [tcl_ok=yes])
-
- if test "${enable_threads+set}" = set; then
- enableval="$enable_threads"
- tcl_ok=$enableval
- else
- tcl_ok=yes
- fi
-
- if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
- TCL_THREADS=1
-
- if test "${TEA_PLATFORM}" != "windows" ; then
- # We are always OK on Windows, so check what this platform wants:
-
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- AC_DEFINE(USE_THREAD_ALLOC, 1,
- [Do we want to use the threaded memory allocator?])
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- if test "`uname -s`" = "SunOS" ; then
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
- fi
- AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
- AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- # Check a little harder for __pthread_mutex_init in the same
- # library, as some systems hide it there until pthread.h is
- # defined. We could alternatively do an AC_TRY_COMPILE with
- # pthread.h, but that will work with libpthread really doesn't
- # exist, like AIX 4.2. [Bug: 4359]
- AC_CHECK_LIB(pthread, __pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- fi
-
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthread"
- else
- AC_CHECK_LIB(pthreads, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthreads"
- else
- AC_CHECK_LIB(c, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- AC_CHECK_LIB(c_r, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -pthread"
- else
- TCL_THREADS=0
- AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
- fi
- fi
- fi
- fi
- fi
- else
- TCL_THREADS=0
- fi
- # Do checking message here to not mess up interleaved configure output
- AC_MSG_CHECKING([for building with threads])
- if test "${TCL_THREADS}" = 1; then
- AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
- AC_MSG_RESULT([yes (default)])
- else
- AC_MSG_RESULT([no])
- fi
- # TCL_THREADS sanity checking. See if our request for building with
- # threads is the same as the way Tcl was built. If not, warn the user.
- case ${TCL_DEFS} in
- *THREADS=1*)
- if test "${TCL_THREADS}" = "0"; then
- AC_MSG_WARN([
- Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
- that IS thread-enabled. It is recommended to use --enable-threads.])
- fi
- ;;
- *)
- if test "${TCL_THREADS}" = "1"; then
- AC_MSG_WARN([
- --enable-threads requested, but building against a Tcl that is NOT
- thread-enabled. This is an OK configuration that will also run in
- a thread-enabled core.])
- fi
- ;;
- esac
- AC_SUBST(TCL_THREADS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SYMBOLS --
-#
-# Specify if debugging symbols should be used.
-# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
-#
-# Arguments:
-# none
-#
-# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
-# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
-# Requires the following vars to be set in the Makefile:
-# CFLAGS_DEFAULT
-# LDFLAGS_DEFAULT
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-symbols
-#
-# Defines the following vars:
-# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
-# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
-# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
-# Sets to $(LDFLAGS_OPTIMIZE) if false
-# DBGX Formerly used as debug library extension;
-# always blank now.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_SYMBOLS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_CONFIG_CFLAGS])
- AC_MSG_CHECKING([for build with symbols])
- AC_ARG_ENABLE(symbols,
- AC_HELP_STRING([--enable-symbols],
- [build with debugging symbols (default: off)]),
- [tcl_ok=$enableval], [tcl_ok=no])
- DBGX=""
- if test "$tcl_ok" = "no"; then
- CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
- LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
- AC_MSG_RESULT([no])
- else
- CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
- LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
- if test "$tcl_ok" = "yes"; then
- AC_MSG_RESULT([yes (standard debugging)])
- fi
- fi
- # TEA specific:
- if test "${TEA_PLATFORM}" != "windows" ; then
- LDFLAGS_DEFAULT="${LDFLAGS}"
- fi
- AC_SUBST(CFLAGS_DEFAULT)
- AC_SUBST(LDFLAGS_DEFAULT)
- AC_SUBST(TCL_DBGX)
-
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
- fi
-
- if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
- if test "$tcl_ok" = "all"; then
- AC_MSG_RESULT([enabled symbols mem debugging])
- else
- AC_MSG_RESULT([enabled $tcl_ok debugging])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_LANGINFO --
-#
-# Allows use of modern nl_langinfo check for better l10n.
-# This is only relevant for Unix.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-langinfo=yes|no (default is yes)
-#
-# Defines the following vars:
-# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_LANGINFO], [
- AC_ARG_ENABLE(langinfo,
- AC_HELP_STRING([--enable-langinfo],
- [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
- [langinfo_ok=$enableval], [langinfo_ok=yes])
-
- HAVE_LANGINFO=0
- if test "$langinfo_ok" = "yes"; then
- AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
- fi
- AC_MSG_CHECKING([whether to use nl_langinfo])
- if test "$langinfo_ok" = "yes"; then
- AC_CACHE_VAL(tcl_cv_langinfo_h, [
- AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
- [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
- AC_MSG_RESULT([$tcl_cv_langinfo_h])
- if test $tcl_cv_langinfo_h = yes; then
- AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
- fi
- else
- AC_MSG_RESULT([$langinfo_ok])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_SYSTEM
-#
-# Determine what the system is (some things cannot be easily checked
-# on a feature-driven basis, alas). This can usually be done via the
-# "uname" command.
-#
-# Arguments:
-# none
-#
-# Results:
-# Defines the following var:
-#
-# system - System/platform/version identification code.
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_SYSTEM], [
- AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
- # TEA specific:
- if test "${TEA_PLATFORM}" = "windows" ; then
- tcl_cv_sys_version=windows
- else
- tcl_cv_sys_version=`uname -s`-`uname -r`
- if test "$?" -ne 0 ; then
- AC_MSG_WARN([can't find uname command])
- tcl_cv_sys_version=unknown
- else
- if test "`uname -s`" = "AIX" ; then
- tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
- fi
- fi
- fi
- ])
- system=$tcl_cv_sys_version
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_CFLAGS
-#
-# Try to determine the proper flags to pass to the compiler
-# for building shared libraries and other such nonsense.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substitutes the following vars:
-#
-# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
-# LDFLAGS - Flags to pass to the compiler when linking object
-# files into an executable application binary such
-# as tclsh.
-# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile. Could
-# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
-# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile.
-# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
-# of a shared library (may request position-independent
-# code, among other things).
-# SHLIB_LD - Base command to use for combining object files
-# into a shared library.
-# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
-# creating shared libraries. This symbol typically
-# goes at the end of the "ld" commands that build
-# shared libraries. The value of the symbol defaults to
-# "${LIBS}" if all of the dependent libraries should
-# be specified when creating a shared library. If
-# dependent libraries should not be specified (as on
-# SunOS 4.x, where they cause the link to fail, or in
-# general if Tcl and Tk aren't themselves shared
-# libraries), then this symbol has an empty string
-# as its value.
-# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
-# extensions. An empty string means we don't know how
-# to use shared libraries on this platform.
-# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
-# in a static or shared library name, using the $PACKAGE_VERSION variable
-# to put the version in the right place. This is used
-# by platforms that need non-standard library names.
-# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
-# to have a version after the .so, and ${PACKAGE_VERSION}.a
-# on AIX, since a shared library needs to have
-# a .a extension whereas shared objects for loadable
-# extensions have a .so extension. Defaults to
-# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
-# CFLAGS_DEBUG -
-# Flags used when running the compiler in debug mode
-# CFLAGS_OPTIMIZE -
-# Flags used when running the compiler in optimize mode
-# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_CFLAGS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
-
- # Step 0.a: Enable 64 bit support?
-
- AC_MSG_CHECKING([if 64bit support is requested])
- AC_ARG_ENABLE(64bit,
- AC_HELP_STRING([--enable-64bit],
- [enable 64bit support (default: off)]),
- [do64bit=$enableval], [do64bit=no])
- AC_MSG_RESULT([$do64bit])
-
- # Step 0.b: Enable Solaris 64 bit VIS support?
-
- AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
- AC_ARG_ENABLE(64bit-vis,
- AC_HELP_STRING([--enable-64bit-vis],
- [enable 64bit Sparc VIS support (default: off)]),
- [do64bitVIS=$enableval], [do64bitVIS=no])
- AC_MSG_RESULT([$do64bitVIS])
- # Force 64bit on with VIS
- AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
-
- # Step 0.c: Check if visibility support is available. Do this here so
- # that platform specific alternatives can be used below if this fails.
-
- AC_CACHE_CHECK([if compiler supports visibility "hidden"],
- tcl_cv_cc_visibility_hidden, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- AC_TRY_LINK([
- extern __attribute__((__visibility__("hidden"))) void f(void);
- void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
- tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- AC_DEFINE(MODULE_SCOPE,
- [extern __attribute__((__visibility__("hidden")))],
- [Compiler support for module scope symbols])
- AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
- ])
-
- # Step 0.d: Disable -rpath support?
-
- AC_MSG_CHECKING([if rpath support is requested])
- AC_ARG_ENABLE(rpath,
- AC_HELP_STRING([--disable-rpath],
- [disable rpath support (default: on)]),
- [doRpath=$enableval], [doRpath=yes])
- AC_MSG_RESULT([$doRpath])
-
- # TEA specific: Cross-compiling options for Windows/CE builds?
-
- AS_IF([test "${TEA_PLATFORM}" = windows], [
- AC_MSG_CHECKING([if Windows/CE build is requested])
- AC_ARG_ENABLE(wince,
- AC_HELP_STRING([--enable-wince],
- [enable Win/CE support (where applicable)]),
- [doWince=$enableval], [doWince=no])
- AC_MSG_RESULT([$doWince])
- ])
-
- # Set the variable "system" to hold the name and version number
- # for the system.
-
- TEA_CONFIG_SYSTEM
-
- # Require ranlib early so we can override it in special cases below.
-
- AC_REQUIRE([AC_PROG_RANLIB])
-
- # 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
- AS_IF([test "$GCC" = yes], [
- CFLAGS_OPTIMIZE=-O2
- CFLAGS_WARNING="-Wall"
- ], [
- CFLAGS_OPTIMIZE=-O
- CFLAGS_WARNING=""
- ])
- AC_CHECK_TOOL(AR, ar)
- STLIB_LD='${AR} cr'
- LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
- AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
- 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
- AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
- AC_MSG_WARN([Ensure latest Platform SDK is installed])
- do64bit="no"
- else
- AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
- do64bit_ok="yes"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- if test "$do64bit" != "no" ; then
- AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
- fi
- if test "$GCC" = "yes" ; then
- AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
- fi
- TEA_PATH_CELIB
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F, '{ \
- if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
- if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
- if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
- if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
- if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
- -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
- doWince="no"
- else
- # We could PATH_NOSPACE these, but that's not important,
- # as long as we quote them when used.
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$GCC" != "yes" ; then
- if test "${SHARED_BUILD}" = "0" ; then
- runtime=-MT
- else
- runtime=-MD
- fi
- case "x`echo \${VisualStudioVersion}`" in
- x1[[4-9]]*)
- lflags="${lflags} -nodefaultlib:libucrt.lib"
- TEA_ADD_LIBS([ucrt.lib])
- ;;
- *)
- ;;
- 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
- TEA_ADD_LIBS([bufferoverflowU.lib])
- elif test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="\"${CEBINROOT}/cl.exe\""
- else
- CC="\"${CEBINROOT}/cl${ARCH}.exe\""
- fi
- CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
- defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
- if test "${SHARED_BUILD}" = "1" ; then
- # Static CE builds require static celib as well
- defs="${defs} _DLL"
- fi
- for i in $defs ; do
- AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
- done
- AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
- AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
- CFLAGS_DEBUG="-nologo -Zi -Od"
- CFLAGS_OPTIMIZE="-nologo -Ox"
- lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
- lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
- LINKBIN="\"${CEBINROOT}/link.exe\""
- AC_SUBST(CELIB_DIR)
- 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
- AC_CHECK_TOOL(RC, windres)
- CFLAGS_DEBUG="-g"
- CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- SHLIB_LD='${CC} -shared'
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
- LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
-
- AC_CACHE_CHECK(for cross-compile version of gcc,
- ac_cv_cross,
- AC_TRY_COMPILE([
- #ifdef _WIN32
- #error cross-compiler
- #endif
- ], [],
- ac_cv_cross=yes,
- ac_cv_cross=no)
- )
- 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-*)
- AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
- # AIX requires the _r compiler when gcc isn't being used
- case "${CC}" in
- *_r|*_r\ *)
- # ok ...
- ;;
- *)
- # Make sure only first arg gets _r
- CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
- ;;
- esac
- AC_MSG_RESULT([Using $CC for compiling with threads])
- ])
- LIBS="$LIBS -lc"
- SHLIB_CFLAGS=""
- SHLIB_SUFFIX=".so"
-
- LD_LIBRARY_PATH_VAR="LIBPATH"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -q64"
- LDFLAGS_ARCH="-q64"
- RANLIB="${RANLIB} -X64"
- AR="${AR} -X64"
- SHLIB_LD_FLAGS="-b64"
- ])
- ])
-
- AS_IF([test "`uname -m`" = ia64], [
- # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- AS_IF([test "$GCC" = yes], [
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- ], [
- CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
- ])
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ], [
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared -Wl,-bexpall'
- ], [
- SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
- LDFLAGS="$LDFLAGS -brtl"
- ])
- SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
- CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- 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.
- #-----------------------------------------------------------
- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
- ;;
- 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}'
- AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
- ;;
- HP-UX-*.11.*)
- # Use updated header definitions where possible
- AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
- # TEA specific: Needed by Tcl, but not most extensions
- #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
- #LIBS="$LIBS -lxnet" # Use the XOPEN network library
-
- AS_IF([test "`uname -m`" = ia64], [
- SHLIB_SUFFIX=".so"
- # Use newer C++ library for C++ extensions
- #if test "$GCC" != "yes" ; then
- # CPPFLAGS="-AA"
- #fi
- ], [
- SHLIB_SUFFIX=".sl"
- ])
- AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
- AS_IF([test "$tcl_ok" = yes], [
- LDFLAGS="$LDFLAGS -Wl,-E"
- CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
- LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
- LD_LIBRARY_PATH_VAR="SHLIB_PATH"
- ])
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- CFLAGS="$CFLAGS -z"
- # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
- #CFLAGS="$CFLAGS +DAportable"
- SHLIB_CFLAGS="+z"
- SHLIB_LD="ld -b"
- ])
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = "yes"], [
- AS_IF([test "$GCC" = yes], [
- case `${CC} -dumpmachine` in
- hppa64*)
- # 64-bit gcc in use. Fix flags for GNU ld.
- do64bit_ok=yes
- SHLIB_LD='${CC} -shared'
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ;;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ;;
- esac
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS +DD64"
- LDFLAGS_ARCH="+DD64"
- ])
- ]) ;;
- IRIX-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [
- CFLAGS="$CFLAGS -mabi=n32"
- LDFLAGS="$LDFLAGS -mabi=n32"
- ], [
- case $system in
- IRIX-6.3)
- # Use to build 6.2 compatible binaries on 6.3.
- CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
- ;;
- *)
- CFLAGS="$CFLAGS -n32"
- ;;
- esac
- LDFLAGS="$LDFLAGS -n32"
- ])
- ;;
- IRIX64-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
-
- # Check to enable 64-bit flags for compiler/linker
-
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported by gcc])
- ], [
- do64bit_ok=yes
- SHLIB_LD="ld -64 -shared -rdata_shared"
- CFLAGS="$CFLAGS -64"
- LDFLAGS_ARCH="-64"
- ])
- ])
- ;;
- Linux*|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"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
- AS_IF([test $do64bit = yes], [
- AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -m64"
- AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_m64 = yes], [
- CFLAGS="$CFLAGS -m64"
- do64bit_ok=yes
- ])
- ])
-
- # The combo of gcc + glibc has a bug related to inlining of
- # functions like strtod(). The -fno-builtin flag should address
- # this problem but it does not work. The -fno-inline flag is kind
- # of overkill but it works. Disable inlining only when one of the
- # files in compat/*.c is being linked in.
-
- AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
- ;;
- Lynx*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
- CFLAGS_OPTIMIZE=-02
- SHLIB_LD='${CC} -shared'
- LD_FLAGS="-Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- ;;
- 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"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
- LDFLAGS="-Wl,-export-dynamic"
- ;;
- esac
- case "$arch" in
- vax)
- CFLAGS_OPTIMIZE="-O1"
- ;;
- *)
- CFLAGS_OPTIMIZE="-O2"
- ;;
- esac
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # On OpenBSD: Compile with -pthread
- # Don't link with -lpthread
- LIBS=`echo $LIBS | sed s/-lpthread//`
- CFLAGS="$CFLAGS -pthread"
- ])
- # 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"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the CFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ;;
- 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=""
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the LDFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
- 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}'`"
- AS_IF([test $do64bit = yes], [
- case `arch` in
- ppc)
- AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
- tcl_cv_cc_arch_ppc64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
- tcl_cv_cc_arch_ppc64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- do64bit_ok=yes
- ]);;
- i386)
- AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
- tcl_cv_cc_arch_x86_64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch x86_64"
- AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
- tcl_cv_cc_arch_x86_64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
- CFLAGS="$CFLAGS -arch x86_64"
- do64bit_ok=yes
- ]);;
- *)
- AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
- esac
- ], [
- # Check for combined 32-bit and 64-bit fat build
- AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
- && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
- fat_32_64=yes])
- ])
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
- AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_single_module = yes], [
- SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
- ])
- # TEA specific: link shlib with current and 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:
- AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
- "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
- LDFLAGS="$LDFLAGS -prebind"])
- LDFLAGS="$LDFLAGS -headerpad_max_install_names"
- AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
- tcl_cv_ld_search_paths_first, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
- tcl_cv_ld_search_paths_first=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- ])
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [__private_extern__],
- [Compiler support for module scope symbols])
- tcl_cv_cc_visibility_hidden=yes
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
- # TEA specific: for combined 32 & 64 bit fat builds of Tk
- # extensions, verify that 64-bit build is possible.
- AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
- AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
- LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
- AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
- tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
- AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
- LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
- AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
- tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- # remove 64-bit arch flags from CFLAGS et al. if configuration
- # does not support 64-bit.
- AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
- AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
- done])
- ])
- ;;
- OS/390-*)
- CFLAGS_OPTIMIZE="" # Optimizer is buggy
- AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
- [Should OS/390 do the right thing with sockets?])
- ;;
- OSF1-V*)
- # Digital OSF/1
- SHLIB_CFLAGS=""
- AS_IF([test "$SHARED_BUILD" = 1], [
- SHLIB_LD='ld -shared -expect_unresolved "*"'
- ], [
- SHLIB_LD='ld -non_shared -expect_unresolved "*"'
- ])
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
- CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
- # see pthread_intro(3) for pthread support on osf1, k.furukawa
- AS_IF([test "${TCL_THREADS}" = 1], [
- CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
- CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
- LIBS=`echo $LIBS | sed s/-lpthreads//`
- AS_IF([test "$GCC" = yes], [
- LIBS="$LIBS -lpthread -lmach -lexc"
- ], [
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ])
- ;;
- QNX-6*)
- # QNX RTP
- # This may work for all QNX, but it was only reported for v6.
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- SCO_SV-3.2*)
- AS_IF([test "$GCC" = yes], [
- SHLIB_CFLAGS="-fPIC -melf"
- LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
- ], [
- SHLIB_CFLAGS="-Kpic -belf"
- LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
- ])
- SHLIB_LD="ld -G"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- 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.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- SunOS-5*)
- # Note: If _REENTRANT isn't defined, then Solaris
- # won't define thread-safe library routines.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- arch=`isainfo`
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- AS_IF([test "$GCC" = yes], [
- AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
- AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64 -mcpu=v9"
- LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
- SHLIB_CFLAGS="-fPIC"
- ])
- ], [
- do64bit_ok=yes
- AS_IF([test "$do64bitVIS" = yes], [
- CFLAGS="$CFLAGS -xarch=v9a"
- LDFLAGS_ARCH="-xarch=v9a"
- ], [
- CFLAGS="$CFLAGS -xarch=v9"
- LDFLAGS_ARCH="-xarch=v9"
- ])
- # Solaris 64 uses this as well
- #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
- ])
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- AS_IF([test "$GCC" = yes], [
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
- esac
- ], [
- do64bit_ok=yes
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- CFLAGS="$CFLAGS -xarch=amd64"
- LDFLAGS="$LDFLAGS -xarch=amd64";;
- esac
- ])
- ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
- ])
-
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "$do64bit_ok" = yes], [
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- # We need to specify -static-libgcc or we need to
- # add the path to the sparv9 libgcc.
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
- # for finding sparcv9 libgcc, get the regular libgcc
- # path, remove so name and append 'sparcv9'
- #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
- #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
- ])])
- ])
- ], [
- case $system in
- SunOS-5.[[1-9]][[0-9]]*)
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
- *)
- SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
- esac
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ])
- ;;
- UNIX_SV* | UnixWare-5*)
- SHLIB_CFLAGS="-KPIC"
- SHLIB_LD='${CC} -G'
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
- # that don't grok the -Bexport option. Test that it does.
- AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_Bexport = yes], [
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- esac
-
- AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
- AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
- ])
-
-dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
-dnl # until the end of configure, as configure's compile and link tests use
-dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
-dnl # preprocessing tests use only CPPFLAGS.
- AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
-
- # 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.
-
- AS_IF([test "$GCC" = yes], [
- case $system in
- AIX-*) ;;
- BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
- IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
- Darwin-*) ;;
- SCO_SV-3.2*) ;;
- windows) ;;
- *) SHLIB_CFLAGS="-fPIC" ;;
- esac])
-
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [extern],
- [No Compiler support for module scope symbols])
- ])
-
- AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
- AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
-
- if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
- AC_CACHE_CHECK(for SEH support in compiler,
- tcl_cv_seh,
- AC_TRY_RUN([
-#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;
- }
- ],
- tcl_cv_seh=yes,
- tcl_cv_seh=no,
- tcl_cv_seh=no)
- )
- if test "$tcl_cv_seh" = "no" ; then
- AC_DEFINE(HAVE_NO_SEH, 1,
- [Defined when mingw does not support SEH])
- 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.
- #
- AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
- tcl_cv_eh_disposition,
- AC_TRY_COMPILE([
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# undef WIN32_LEAN_AND_MEAN
- ],[
- EXCEPTION_DISPOSITION x;
- ],
- tcl_cv_eh_disposition=yes,
- tcl_cv_eh_disposition=no)
- )
- if test "$tcl_cv_eh_disposition" = "no" ; then
- AC_DEFINE(EXCEPTION_DISPOSITION, int,
- [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
- 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.
-
- AC_CACHE_CHECK(for winnt.h that ignores VOID define,
- tcl_cv_winnt_ignore_void,
- AC_TRY_COMPILE([
-#define VOID void
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
- ], [
- CHAR c;
- SHORT s;
- LONG l;
- ],
- tcl_cv_winnt_ignore_void=yes,
- tcl_cv_winnt_ignore_void=no)
- )
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
- AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
- [Defined when cygwin/mingw ignores VOID define in winnt.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.
-
- AC_CACHE_CHECK(for cast to union support,
- tcl_cv_cast_to_union,
- AC_TRY_COMPILE([],
- [
- union foo { int i; double d; };
- union foo f = (union foo) (int) 0;
- ],
- tcl_cv_cast_to_union=yes,
- tcl_cv_cast_to_union=no)
- )
- if test "$tcl_cv_cast_to_union" = "yes"; then
- AC_DEFINE(HAVE_CAST_TO_UNION, 1,
- [Defined when compiler supports casting to union type.])
- fi
-
- AC_SUBST(CFLAGS_DEBUG)
- AC_SUBST(CFLAGS_OPTIMIZE)
- AC_SUBST(CFLAGS_WARNING)
-
- AC_SUBST(STLIB_LD)
- AC_SUBST(SHLIB_LD)
-
- AC_SUBST(SHLIB_LD_LIBS)
- AC_SUBST(SHLIB_CFLAGS)
-
- AC_SUBST(LD_LIBRARY_PATH_VAR)
-
- # These must be called after we do the basic CFLAGS checks and
- # verify any possible 64-bit or similar switches are necessary
- TEA_TCL_EARLY_FLAGS
- TEA_TCL_64BIT_FLAGS
-])
-
-#--------------------------------------------------------------------
-# TEA_SERIAL_PORT
-#
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives,
-# and some build environments have stdin not pointing at a
-# pseudo-terminal (usually /dev/null instead.)
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines only one of the following vars:
-# HAVE_SYS_MODEM_H
-# USE_TERMIOS
-# USE_TERMIO
-# USE_SGTTY
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_SERIAL_PORT], [
- AC_CHECK_HEADERS(sys/modem.h)
- AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
- AC_TRY_RUN([
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termios.h>
-#include <errno.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
- fi])
- case $tcl_cv_api_serial in
- termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
- termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
- sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
-# TEA_PATH_X
-#
-# Locate the X11 header files and the X11 library archive. Try
-# the ac_path_x macro first, but if it doesn't find the X stuff
-# (e.g. because there's no xmkmf program) then check through
-# a list of possible directories. Under some conditions the
-# autoconf macro will return an include directory that contains
-# no include files, so double-check its result just to be safe.
-#
-# This should be called after TEA_CONFIG_CFLAGS as setting the
-# LIBS line can confuse some configure macro magic.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets the following vars:
-# XINCLUDES
-# XLIBSW
-# PKG_LIBS (appends to)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_X], [
- if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
- TEA_PATH_UNIX_X
- fi
-])
-
-AC_DEFUN([TEA_PATH_UNIX_X], [
- AC_PATH_X
- not_really_there=""
- if test "$no_x" = ""; then
- if test "$x_includes" = ""; then
- AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
- else
- if test ! -r $x_includes/X11/Xlib.h; then
- not_really_there="yes"
- fi
- fi
- fi
- if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
- AC_MSG_CHECKING([for X11 header files])
- found_xincludes="no"
- AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
- if test "$found_xincludes" = "no"; then
- dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
- for i in $dirs ; do
- if test -r $i/X11/Xlib.h; then
- AC_MSG_RESULT([$i])
- XINCLUDES=" -I$i"
- found_xincludes="yes"
- break
- fi
- done
- fi
- else
- if test "$x_includes" != ""; then
- XINCLUDES="-I$x_includes"
- found_xincludes="yes"
- fi
- fi
- if test "$found_xincludes" = "no"; then
- AC_MSG_RESULT([couldn't find any!])
- fi
-
- if test "$no_x" = yes; then
- AC_MSG_CHECKING([for X11 libraries])
- XLIBSW=nope
- dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
- for i in $dirs ; do
- if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
- AC_MSG_RESULT([$i])
- XLIBSW="-L$i -lX11"
- x_libraries="$i"
- break
- fi
- done
- else
- if test "$x_libraries" = ""; then
- XLIBSW=-lX11
- else
- XLIBSW="-L$x_libraries -lX11"
- fi
- fi
- if test "$XLIBSW" = nope ; then
- AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
- fi
- if test "$XLIBSW" = nope ; then
- AC_MSG_RESULT([could not find any! Using -lX11.])
- XLIBSW=-lX11
- fi
- # TEA specific:
- if test x"${XLIBSW}" != x ; then
- PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BLOCKING_STYLE
-#
-# The statements below check for systems where POSIX-style
-# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
-# On these systems (mostly older ones), use the old BSD-style
-# FIONBIO approach instead.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# HAVE_SYS_IOCTL_H
-# HAVE_SYS_FILIO_H
-# USE_FIONBIO
-# O_NONBLOCK
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BLOCKING_STYLE], [
- AC_CHECK_HEADERS(sys/ioctl.h)
- AC_CHECK_HEADERS(sys/filio.h)
- TEA_CONFIG_SYSTEM
- AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
- case $system in
- OSF*)
- AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
- AC_MSG_RESULT([FIONBIO])
- ;;
- *)
- AC_MSG_RESULT([O_NONBLOCK])
- ;;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_TIME_HANDLER
-#
-# Checks how the system deals with time.h, what time structures
-# are used on the system, and what fields the structures have.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# USE_DELTA_FOR_TZ
-# HAVE_TM_GMTOFF
-# HAVE_TM_TZADJ
-# HAVE_TIMEZONE_VAR
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TIME_HANDLER], [
- AC_CHECK_HEADERS(sys/time.h)
- AC_HEADER_TIME
- AC_STRUCT_TIMEZONE
-
- AC_CHECK_FUNCS(gmtime_r localtime_r)
-
- AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
- tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
- if test $tcl_cv_member_tm_tzadj = yes ; then
- AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
- fi
-
- AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
- tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
- if test $tcl_cv_member_tm_gmtoff = yes ; then
- AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
- fi
-
- #
- # Its important to include time.h in this check, as some systems
- # (like convex) have timezone functions, etc.
- #
- AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern long timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
- if test $tcl_cv_timezone_long = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- else
- #
- # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
- #
- AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern time_t timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
- if test $tcl_cv_timezone_time = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BUGGY_STRTOD
-#
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" (provided by Tcl) that corrects the error.
-# Also, on Compaq's Tru64 Unix 5.0,
-# strtod(" ") returns 0.0 instead of a failure to convert.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Might defines some of the following vars:
-# strtod (=fixstrtod)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BUGGY_STRTOD], [
- AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
- if test "$tcl_strtod" = 1; then
- AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
- AC_TRY_RUN([
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
- tcl_cv_strtod_buggy=buggy)])
- if test "$tcl_cv_strtod_buggy" = buggy; then
- AC_LIBOBJ([fixstrtod])
- USE_COMPAT=1
- AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_EARLY_FLAGS
-#
-# Check for what flags are needed to be passed so the correct OS
-# features are available.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# _ISOC99_SOURCE
-# _LARGEFILE64_SOURCE
-# _LARGEFILE_SOURCE64
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_EARLY_FLAG],[
- AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
- AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
- AC_TRY_COMPILE([[#define ]$1[ 1
-]$2], $3,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
- if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
- AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
- tcl_flags="$tcl_flags $1"
- fi
-])
-
-AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
- AC_MSG_CHECKING([for required early compiler flags])
- tcl_flags=""
- TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
- [char *p = (char *)strtoll; char *q = (char *)strtoull;])
- TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
- [struct stat64 buf; int i = stat64("/", &buf);])
- TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
- [char *p = (char *)open64;])
- if test "x${tcl_flags}" = "x" ; then
- AC_MSG_RESULT([none])
- else
- AC_MSG_RESULT([${tcl_flags}])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_64BIT_FLAGS
-#
-# Check for what is defined in the way of 64-bit features.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# TCL_WIDE_INT_IS_LONG
-# TCL_WIDE_INT_TYPE
-# HAVE_STRUCT_DIRENT64
-# HAVE_STRUCT_STAT64
-# HAVE_TYPE_OFF64_T
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
- AC_MSG_CHECKING([for 64-bit integer type])
- AC_CACHE_VAL(tcl_cv_type_64bit,[
- tcl_cv_type_64bit=none
- # See if the compiler knows natively about __int64
- AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
- tcl_type_64bit=__int64, tcl_type_64bit="long long")
- # See if we should use long anyway Note that we substitute in the
- # type that is our current guess for a 64-bit type inside this check
- # program, so it should be modified only carefully...
- AC_TRY_COMPILE(,[switch (0) {
- case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
- }],tcl_cv_type_64bit=${tcl_type_64bit})])
- if test "${tcl_cv_type_64bit}" = none ; then
- AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
- AC_MSG_RESULT([using long])
- elif test "${tcl_cv_type_64bit}" = "__int64" \
- -a "${TEA_PLATFORM}" = "windows" ; then
- # TEA specific: We actually want to use the default tcl.h checks in
- # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
- AC_MSG_RESULT([using Tcl header defaults])
- else
- AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
- [What type should be used to define wide integers?])
- AC_MSG_RESULT([${tcl_cv_type_64bit}])
-
- # Now check for auxiliary declarations
- AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <dirent.h>],[struct dirent64 p;],
- tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
- if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
- fi
-
- AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
- AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
-],
- tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
- fi
-
- AC_CHECK_FUNCS(open64 lseek64)
- AC_MSG_CHECKING([for off64_t])
- AC_CACHE_VAL(tcl_cv_type_off64_t,[
- AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
-],
- tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
- dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
- dnl functions lseek64 and open64 are defined.
- if test "x${tcl_cv_type_off64_t}" = "xyes" && \
- test "x${ac_cv_func_lseek64}" = "xyes" && \
- test "x${ac_cv_func_open64}" = "xyes" ; then
- AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- fi
-])
-
-##
-## Here ends the standard Tcl configuration bits and starts the
-## TEA specific functions
-##
-
-#------------------------------------------------------------------------
-# TEA_INIT --
-#
-# Init various Tcl Extension Architecture (TEA) variables.
-# This should be the first called TEA_* macro.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substs the following vars:
-# CYGPATH
-# EXEEXT
-# Defines only:
-# TEA_VERSION
-# TEA_INITED
-# TEA_PLATFORM (windows or unix)
-#
-# "cygpath" is used on windows to generate native path names for include
-# files. These variables should only be used with the compiler and linker
-# since they generate native path names.
-#
-# EXEEXT
-# Select the executable extension based on the host type. This
-# is a lightweight replacement for AC_EXEEXT that doesn't require
-# a compiler.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_INIT], [
- # TEA extensions pass this us the version of TEA they think they
- # are compatible with.
- TEA_VERSION="3.10"
-
- AC_MSG_CHECKING([for correct TEA configuration])
- if test x"${PACKAGE_NAME}" = x ; then
- AC_MSG_ERROR([
-The PACKAGE_NAME variable must be defined by your TEA configure.ac])
- fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
-
- # 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_*)
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
- 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
-
- AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
-
- AC_SUBST(EXEEXT)
- AC_SUBST(CYGPATH)
-
- # This package name must be replaced statically for AC_SUBST to work
- AC_SUBST(PKG_LIB_FILE)
- # Substitute STUB_LIB_FILE in case package creates a stub library too.
- AC_SUBST(PKG_STUB_LIB_FILE)
-
- # We AC_SUBST these here to ensure they are subst'ed,
- # in case the user doesn't call TEA_ADD_...
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
- AC_SUBST(PKG_TCL_SOURCES)
- AC_SUBST(PKG_HEADERS)
- AC_SUBST(PKG_INCLUDES)
- AC_SUBST(PKG_LIBS)
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_SOURCES
-# PKG_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_SOURCES], [
- vars="$@"
- for i in $vars; do
- case $i in
- [\$]*)
- # allow $-var names
- PKG_SOURCES="$PKG_SOURCES $i"
- PKG_OBJECTS="$PKG_OBJECTS $i"
- ;;
- *)
- # check for existence - allows for generic/win/unix VPATH
- # To add more dirs here (like 'src'), you have to update VPATH
- # in Makefile.in as well
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find source file '$i'])
- fi
- PKG_SOURCES="$PKG_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_OBJECTS="$PKG_OBJECTS $j"
- ;;
- esac
- done
- AC_SUBST(PKG_SOURCES)
- AC_SUBST(PKG_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_STUB_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_STUB_SOURCES
-# PKG_STUB_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_STUB_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence - allows for generic/win/unix VPATH
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find stub source file '$i'])
- fi
- PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
- done
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_TCL_SOURCES --
-#
-# Specify one or more Tcl source files. These should be platform
-# independent runtime files.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_TCL_SOURCES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_TCL_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
- fi
- PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
- done
- AC_SUBST(PKG_TCL_SOURCES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_HEADERS --
-#
-# Specify one or more source headers. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_HEADERS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_HEADERS], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
- fi
- PKG_HEADERS="$PKG_HEADERS $i"
- done
- AC_SUBST(PKG_HEADERS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_INCLUDES --
-#
-# Specify one or more include dirs. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_INCLUDES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_INCLUDES], [
- vars="$@"
- for i in $vars; do
- PKG_INCLUDES="$PKG_INCLUDES $i"
- done
- AC_SUBST(PKG_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_LIBS --
-#
-# Specify one or more libraries. Users should check for
-# the right platform before adding to their list. For Windows,
-# libraries provided in "foo.lib" format will be converted to
-# "-lfoo" when using GCC (mingw).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_LIBS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_LIBS], [
- vars="$@"
- for i in $vars; do
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
- # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
- i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
- fi
- PKG_LIBS="$PKG_LIBS $i"
- done
- AC_SUBST(PKG_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CFLAGS --
-#
-# Specify one or more CFLAGS. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_CFLAGS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CFLAGS], [
- PKG_CFLAGS="$PKG_CFLAGS $@"
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CLEANFILES --
-#
-# Specify one or more CLEANFILES.
-#
-# Arguments:
-# one or more file names to clean target
-#
-# Results:
-#
-# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CLEANFILES], [
- CLEANFILES="$CLEANFILES $@"
-])
-
-#------------------------------------------------------------------------
-# TEA_PREFIX --
-#
-# Handle the --prefix=... option by defaulting to what Tcl gave
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# If --prefix or --exec-prefix was not specified, $prefix and
-# $exec_prefix will be set to the values given to Tcl when it was
-# configured.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_PREFIX], [
- if test "${prefix}" = "NONE"; then
- prefix_default=yes
- if test x"${TCL_PREFIX}" != x; then
- AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
- prefix=${TCL_PREFIX}
- else
- AC_MSG_NOTICE([--prefix defaulting to /usr/local])
- prefix=/usr/local
- fi
- fi
- if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
- -o x"${exec_prefix_default}" = x"yes" ; then
- if test x"${TCL_EXEC_PREFIX}" != x; then
- AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
- exec_prefix=${TCL_EXEC_PREFIX}
- else
- AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
- exec_prefix=$prefix
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER_CC --
-#
-# Do compiler checks the way we want. This is just a replacement
-# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER_CC], [
- # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
- # in this macro, they need to go into TEA_SETUP_COMPILER instead.
-
- AC_PROG_CC
- AC_PROG_CPP
-
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
- #--------------------------------------------------------------------
- # Checks to see if the make program sets the $MAKE variable.
- #--------------------------------------------------------------------
-
- AC_PROG_MAKE_SET
-
- #--------------------------------------------------------------------
- # Find ranlib
- #--------------------------------------------------------------------
-
- AC_CHECK_TOOL(RANLIB, ranlib)
-
- #--------------------------------------------------------------------
- # Determines the correct binary file extension (.o, .obj, .exe etc.)
- #--------------------------------------------------------------------
-
- AC_OBJEXT
- AC_EXEEXT
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER --
-#
-# Do compiler checks that use the compiler. This must go after
-# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER], [
- # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
- AC_REQUIRE([TEA_SETUP_COMPILER_CC])
-
- #------------------------------------------------------------------------
- # If we're using GCC, see if the compiler understands -pipe. If so, use it.
- # It makes compiling go faster. (This is only a performance feature.)
- #------------------------------------------------------------------------
-
- if test -z "$no_pipe" -a -n "$GCC"; then
- AC_CACHE_CHECK([if the compiler understands -pipe],
- tcl_cv_cc_pipe, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
- AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
- CFLAGS=$hold_cflags])
- if test $tcl_cv_cc_pipe = yes; then
- CFLAGS="$CFLAGS -pipe"
- fi
- fi
-
- #--------------------------------------------------------------------
- # Common compiler flag setup
- #--------------------------------------------------------------------
-
- AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_MAKE_LIB --
-#
-# Generate a line that can be used to build a shared/unshared library
-# in a platform independent manner.
-#
-# Arguments:
-# none
-#
-# Requires:
-#
-# Results:
-#
-# Defines the following vars:
-# CFLAGS - Done late here to note disturb other AC macros
-# MAKE_LIB - Command to execute to build the Tcl library;
-# differs depending on whether or not Tcl is being
-# compiled as a shared library.
-# MAKE_SHARED_LIB Makefile rule for building a shared library
-# MAKE_STATIC_LIB Makefile rule for building a static library
-# MAKE_STUB_LIB Makefile rule for building a stub library
-# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
-# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_MAKE_LIB], [
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
- MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
- MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
- AC_EGREP_CPP([manifest needed], [
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
- ], [
- # 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}"
- TEA_ADD_CLEANFILES([*.manifest])
- ])
- 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
-
- AC_SUBST(MAKE_LIB)
- AC_SUBST(MAKE_SHARED_LIB)
- AC_SUBST(MAKE_STATIC_LIB)
- AC_SUBST(MAKE_STUB_LIB)
- AC_SUBST(RANLIB_STUB)
- AC_SUBST(VC_MANIFEST_EMBED_DLL)
- AC_SUBST(VC_MANIFEST_EMBED_EXE)
-])
-
-#------------------------------------------------------------------------
-# TEA_LIB_SPEC --
-#
-# Compute the name of an existing object library located in libdir
-# from the given base name and produce the appropriate linker flags.
-#
-# Arguments:
-# basename The base name of the library without version
-# numbers, extensions, or "lib" prefixes.
-# extra_dir Extra directory in which to search for the
-# library. This location is used first, then
-# $prefix/$exec-prefix, then some defaults.
-#
-# Requires:
-# TEA_INIT and TEA_PREFIX must be called first.
-#
-# Results:
-#
-# Defines the following vars:
-# ${basename}_LIB_NAME The computed library name.
-# ${basename}_LIB_SPEC The computed linker flags.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LIB_SPEC], [
- AC_MSG_CHECKING([for $1 library])
-
- # Look in exec-prefix for the library (defined by TEA_PREFIX).
-
- tea_lib_name_dir="${exec_prefix}/lib"
-
- # Or in a user-specified location.
-
- if test x"$2" != x ; then
- tea_extra_lib_dir=$2
- else
- tea_extra_lib_dir=NONE
- fi
-
- for i in \
- `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
- if test -f "$i" ; then
- tea_lib_name_dir=`dirname $i`
- $1_LIB_NAME=`basename $i`
- $1_LIB_PATH_NAME=$i
- break
- fi
- done
-
- if test "${TEA_PLATFORM}" = "windows"; then
- $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
- else
- # Strip off the leading "lib" and trailing ".a" or ".so"
-
- tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
- $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
- fi
-
- if test "x${$1_LIB_NAME}" = x ; then
- AC_MSG_ERROR([not found])
- else
- AC_MSG_RESULT([${$1_LIB_SPEC}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TCL_HEADERS --
-#
-# Locate the private Tcl include files
-#
-# Arguments:
-#
-# Requires:
-# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_TOP_DIR_NATIVE
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
- # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
- AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
- AC_MSG_CHECKING([for Tcl private include files])
-
- TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
- TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
-
- # Check to see if tcl<Plat>Port.h isn't already with the public headers
- # Don't look for tclInt.h because that resides with tcl.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tclh}/tclWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
- result="private headers found with public headers"
- else
- TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
- else
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TCL_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -d "${TCL_BIN_DIR}/Headers" -a \
- -d "${TCL_BIN_DIR}/PrivateHeaders"; then
- TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
- else
- TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TCL_INCLUDES}"
- else
- if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
- fi
- result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TCL_TOP_DIR_NATIVE)
-
- AC_SUBST(TCL_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TCL_HEADERS --
-#
-# Locate the installed public Tcl header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tclinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
- AC_MSG_CHECKING([for Tcl public headers])
-
- AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tclh, [
- # Use the value from --with-tclinclude, if it was given
-
- if test x"${with_tclinclude}" != x ; then
- if test -f "${with_tclinclude}/tcl.h" ; then
- ac_cv_c_tclh=${with_tclinclude}
- else
- AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers directory
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tcl is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TCL_INCLUDE_SPEC}" != x ; then
- d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tcl.h" ; then
- ac_cv_c_tclh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tclh}" = x ; then
- AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tclh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
-
- TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TCL_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TK_HEADERS --
-#
-# Locate the private Tk include files
-#
-# Arguments:
-#
-# Requires:
-# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
- # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
- AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
- AC_MSG_CHECKING([for Tk private include files])
-
- TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
- TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
-
- # Check to see if tk<Plat>Port.h isn't already with the public headers
- # Don't look for tkInt.h because that resides with tk.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tkh}/tkWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
- result="private headers found with public headers"
- else
- TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
- TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
- else
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TK_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
- # Detect and add ttk subdir
- if test -d "${TK_SRC_DIR}/generic/ttk"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
- fi
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -d "${TK_BIN_DIR}/Headers" -a \
- -d "${TK_BIN_DIR}/PrivateHeaders"; then
- TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
- else
- TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TK_INCLUDES}"
- else
- if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
- fi
- result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TK_TOP_DIR_NATIVE)
- AC_SUBST(TK_XLIB_DIR_NATIVE)
-
- AC_SUBST(TK_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TK_HEADERS --
-#
-# Locate the installed public Tk header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tkinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
- AC_MSG_CHECKING([for Tk public headers])
-
- AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tkh, [
- # Use the value from --with-tkinclude, if it was given
-
- if test x"${with_tkinclude}" != x ; then
- if test -f "${with_tkinclude}/tk.h" ; then
- ac_cv_c_tkh=${with_tkinclude}
- else
- AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers directory.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tk is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tk's --prefix location,
- # relative to directory of tkConfig.sh, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TK_PREFIX}/include 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TK_INCLUDE_SPEC}" != x ; then
- d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tk.h" ; then
- ac_cv_c_tkh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tkh}" = x ; then
- AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tkh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
-
- TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TK_INCLUDES)
-
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- # On Windows and Aqua, we need the X compat headers
- AC_MSG_CHECKING([for X11 header files])
- if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
- INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
- TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
- AC_SUBST(TK_XINCLUDES)
- fi
- AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_CONFIG --
-#
-# Locate the ${1}Config.sh file and perform a sanity check on
-# the ${1} compile flags. These are used by packages like
-# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-$1=...
-#
-# Defines the following vars:
-# $1_BIN_DIR Full path to the directory containing
-# the $1Config.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CONFIG], [
- #
- # Ok, lets find the $1 configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-$1
- #
-
- if test x"${no_$1}" = x ; then
- # we reset no_$1 in case something fails here
- no_$1=true
- AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
- AC_MSG_CHECKING([for $1 configuration])
- AC_CACHE_VAL(ac_cv_c_$1config,[
-
- # First check to see if --with-$1 was specified.
- if test x"${with_$1config}" != x ; then
- case ${with_$1config} in
- */$1Config.sh )
- if test -f ${with_$1config}; then
- AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
- with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
- fi;;
- esac
- if test -f "${with_$1config}/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
- else
- AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
- fi
- fi
-
- # then check for a private $1 installation
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in \
- ../$1 \
- `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../$1 \
- `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../../$1 \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ${srcdir}/../$1 \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- if test -f "$i/unix/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i/unix; pwd)`
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_$1config}" = x ; then
- $1_BIN_DIR="# no $1 configs found"
- AC_MSG_WARN([Cannot find $1 configuration definitions])
- exit 0
- else
- no_$1=
- $1_BIN_DIR=${ac_cv_c_$1config}
- AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG --
-#
-# Load the $1Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# $1_SRC_DIR
-# $1_LIB_FILE
-# $1_LIB_SPEC
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_CONFIG], [
- AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
-
- if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
- AC_MSG_RESULT([loading])
- . "${$1_BIN_DIR}/$1Config.sh"
- else
- AC_MSG_RESULT([file not found])
- fi
-
- #
- # If the $1_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable $1_LIB_SPEC will be set to the value
- # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
- # instead of $1_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- #
-
- if test -f "${$1_BIN_DIR}/Makefile" ; then
- AC_MSG_WARN([Found Makefile - using build library specs for $1])
- $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
- $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
- $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
- $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
- $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
- fi
-
- AC_SUBST($1_VERSION)
- AC_SUBST($1_BIN_DIR)
- AC_SUBST($1_SRC_DIR)
-
- AC_SUBST($1_LIB_FILE)
- AC_SUBST($1_LIB_SPEC)
-
- AC_SUBST($1_STUB_LIB_FILE)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_PATH)
-
- # Allow the caller to prevent this auto-check by specifying any 2nd arg
- AS_IF([test "x$2" = x], [
- # Check both upper and lower-case variants
- # If a dev wanted non-stubs libs, this function could take an option
- # to not use _STUB in the paths below
- AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
- [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
- [TEA_LOAD_CONFIG_LIB($1_STUB)])
- ])
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG_LIB --
-#
-# Helper function to load correct library from another extension's
-# ${PACKAGE}Config.sh.
-#
-# Results:
-# Adds to LIBS the appropriate extension library
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
- AC_MSG_CHECKING([For $1 library for LIBS])
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${$1_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
- TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
- AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
- else
- TEA_ADD_LIBS([${$1_LIB_SPEC}])
- AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
- fi
- else
- AC_MSG_RESULT([file not found])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_EXPORT_CONFIG --
-#
-# Define the data to insert into the ${PACKAGE}Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1
-#
-# Results:
-# Substitutes the following vars:
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_EXPORT_CONFIG], [
- #--------------------------------------------------------------------
- # These are for $1Config.sh
- #--------------------------------------------------------------------
-
- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
- eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
- if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
- eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
- else
- eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- fi
- $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
- $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
- $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
- $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
- $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
- $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
-
- AC_SUBST($1_BUILD_LIB_SPEC)
- AC_SUBST($1_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_PATH)
- AC_SUBST($1_STUB_LIB_PATH)
-
- AC_SUBST(MAJOR_VERSION)
- AC_SUBST(MINOR_VERSION)
- AC_SUBST(PATCHLEVEL)
-])
-
-
-#------------------------------------------------------------------------
-# TEA_PATH_CELIB --
-#
-# Locate Keuchel's celib emulation layer for targeting Win/CE
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-celib=...
-#
-# Defines the following vars:
-# CELIB_DIR Full path to the directory containing
-# the include and platform lib files
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CELIB], [
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-celib
-
- if test x"${no_celib}" = x ; then
- # we reset no_celib in case something fails here
- no_celib=true
- AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
- AC_MSG_CHECKING([for Windows/CE celib directory])
- AC_CACHE_VAL(ac_cv_c_celibconfig,[
- # First check to see if --with-celibconfig was specified.
- if test x"${with_celibconfig}" != x ; then
- if test -d "${with_celibconfig}/inc" ; then
- ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
- else
- AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
- fi
- fi
-
- # then check for a celib library
- if test x"${ac_cv_c_celibconfig}" = x ; then
- for i in \
- ../celib-palm-3.0 \
- ../celib \
- ../../celib-palm-3.0 \
- ../../celib \
- `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
- ${srcdir}/../celib-palm-3.0 \
- ${srcdir}/../celib \
- `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
- ; do
- if test -d "$i/inc" ; then
- ac_cv_c_celibconfig=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
- if test x"${ac_cv_c_celibconfig}" = x ; then
- AC_MSG_ERROR([Cannot find celib support library directory])
- else
- no_celib=
- CELIB_DIR=${ac_cv_c_celibconfig}
- CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
- AC_MSG_RESULT([found $CELIB_DIR])
- fi
- fi
-])
-# Local Variables:
-# mode: autoconf
-# End:
diff --git a/tcl8.6/pkgs/sqlite3.21.0/Makefile.in b/tcl8.6/pkgs/sqlite3.25.3/Makefile.in
index 196ae0c..196ae0c 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/Makefile.in
+++ b/tcl8.6/pkgs/sqlite3.25.3/Makefile.in
diff --git a/tcl8.6/pkgs/sqlite3.21.0/README b/tcl8.6/pkgs/sqlite3.25.3/README
index 99dc8b8..99dc8b8 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/README
+++ b/tcl8.6/pkgs/sqlite3.25.3/README
diff --git a/tcl8.6/pkgs/sqlite3.25.3/aclocal.m4 b/tcl8.6/pkgs/sqlite3.25.3/aclocal.m4
new file mode 100644
index 0000000..0b05739
--- /dev/null
+++ b/tcl8.6/pkgs/sqlite3.25.3/aclocal.m4
@@ -0,0 +1,9 @@
+#
+# Include the TEA standard macro set
+#
+
+builtin(include,tclconfig/tcl.m4)
+
+#
+# Add here whatever m4 macros you want to define for your package
+#
diff --git a/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/shell.c b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/shell.c
new file mode 100644
index 0000000..ae2144e
--- /dev/null
+++ b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/shell.c
@@ -0,0 +1,16438 @@
+/* DO NOT EDIT!
+** This file is automatically generated by the script in the canonical
+** SQLite source tree at tool/mkshellc.tcl. That script combines source
+** code from various constituent source files of SQLite into this single
+** "shell.c" file used to implement the SQLite command-line shell.
+**
+** Most of the code found below comes from the "src/shell.c.in" file in
+** the canonical SQLite source tree. That main file contains "INCLUDE"
+** lines that specify other files in the canonical source tree that are
+** inserted to getnerate this complete program source file.
+**
+** The code from multiple files is combined into this single "shell.c"
+** source file to help make the command-line program easier to compile.
+**
+** To modify this program, get a copy of the canonical SQLite source tree,
+** edit the src/shell.c.in" and/or some of the other files that are included
+** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
+*/
+/*
+** 2001 September 15
+**
+** 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 contains code to implement the "sqlite" command line
+** utility for accessing SQLite databases.
+*/
+#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
+/* This needs to come before any includes for MSVC compiler */
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+/*
+** Warning pragmas copied from msvc.h in the core.
+*/
+#if defined(_MSC_VER)
+#pragma warning(disable : 4054)
+#pragma warning(disable : 4055)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4127)
+#pragma warning(disable : 4130)
+#pragma warning(disable : 4152)
+#pragma warning(disable : 4189)
+#pragma warning(disable : 4206)
+#pragma warning(disable : 4210)
+#pragma warning(disable : 4232)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4305)
+#pragma warning(disable : 4306)
+#pragma warning(disable : 4702)
+#pragma warning(disable : 4706)
+#endif /* defined(_MSC_VER) */
+
+/*
+** No support for loadable extensions in VxWorks.
+*/
+#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
+# define SQLITE_OMIT_LOAD_EXTENSION 1
+#endif
+
+/*
+** Enable large-file support for fopen() and friends on unix.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "sqlite3.h"
+typedef sqlite3_int64 i64;
+typedef sqlite3_uint64 u64;
+typedef unsigned char u8;
+#if SQLITE_USER_AUTHENTICATION
+# include "sqlite3userauth.h"
+#endif
+#include <ctype.h>
+#include <stdarg.h>
+
+#if !defined(_WIN32) && !defined(WIN32)
+# include <signal.h>
+# if !defined(__RTP__) && !defined(_WRS_KERNEL)
+# include <pwd.h>
+# endif
+#endif
+#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
+# include <unistd.h>
+# include <dirent.h>
+# define GETPID getpid
+# if defined(__MINGW32__)
+# define DIRENT dirent
+# ifndef S_ISLNK
+# define S_ISLNK(mode) (0)
+# endif
+# endif
+#else
+# define GETPID (int)GetCurrentProcessId
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if HAVE_READLINE
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
+
+#if HAVE_EDITLINE
+# include <editline/readline.h>
+#endif
+
+#if HAVE_EDITLINE || HAVE_READLINE
+
+# define shell_add_history(X) add_history(X)
+# define shell_read_history(X) read_history(X)
+# define shell_write_history(X) write_history(X)
+# define shell_stifle_history(X) stifle_history(X)
+# define shell_readline(X) readline(X)
+
+#elif HAVE_LINENOISE
+
+# include "linenoise.h"
+# define shell_add_history(X) linenoiseHistoryAdd(X)
+# define shell_read_history(X) linenoiseHistoryLoad(X)
+# define shell_write_history(X) linenoiseHistorySave(X)
+# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
+# define shell_readline(X) linenoise(X)
+
+#else
+
+# define shell_read_history(X)
+# define shell_write_history(X)
+# define shell_stifle_history(X)
+
+# define SHELL_USE_LOCAL_GETLINE 1
+#endif
+
+
+#if defined(_WIN32) || defined(WIN32)
+# include <io.h>
+# include <fcntl.h>
+# define isatty(h) _isatty(h)
+# ifndef access
+# define access(f,m) _access((f),(m))
+# endif
+# ifndef unlink
+# define unlink _unlink
+# endif
+# undef popen
+# define popen _popen
+# undef pclose
+# define pclose _pclose
+#else
+ /* Make sure isatty() has a prototype. */
+ extern int isatty(int);
+
+# if !defined(__RTP__) && !defined(_WRS_KERNEL)
+ /* popen and pclose are not C89 functions and so are
+ ** sometimes omitted from the <stdio.h> header */
+ extern FILE *popen(const char*,const char*);
+ extern int pclose(FILE*);
+# else
+# define SQLITE_OMIT_POPEN 1
+# endif
+#endif
+
+#if defined(_WIN32_WCE)
+/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
+ * thus we always assume that we have a console. That can be
+ * overridden with the -batch command line option.
+ */
+#define isatty(x) 1
+#endif
+
+/* ctype macros that work with signed characters */
+#define IsSpace(X) isspace((unsigned char)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);
+extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
+#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
+** rendering quoted strings that contain \n characters). The following
+** routines take care of that.
+*/
+#if defined(_WIN32) || defined(WIN32)
+static void setBinaryMode(FILE *file, int isOutput){
+ if( isOutput ) fflush(file);
+ _setmode(_fileno(file), _O_BINARY);
+}
+static void setTextMode(FILE *file, int isOutput){
+ if( isOutput ) fflush(file);
+ _setmode(_fileno(file), _O_TEXT);
+}
+#else
+# define setBinaryMode(X,Y)
+# define setTextMode(X,Y)
+#endif
+
+
+/* True if the timer is enabled */
+static int enableTimer = 0;
+
+/* Return the current wall-clock time */
+static sqlite3_int64 timeOfDay(void){
+ static sqlite3_vfs *clockVfs = 0;
+ sqlite3_int64 t;
+ if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
+ if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
+ clockVfs->xCurrentTimeInt64(clockVfs, &t);
+ }else{
+ double r;
+ clockVfs->xCurrentTime(clockVfs, &r);
+ t = (sqlite3_int64)(r*86400000.0);
+ }
+ return t;
+}
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
+#include <sys/time.h>
+#include <sys/resource.h>
+
+/* VxWorks does not support getrusage() as far as we can determine */
+#if defined(_WRS_KERNEL) || defined(__RTP__)
+struct rusage {
+ struct timeval ru_utime; /* user CPU time used */
+ struct timeval ru_stime; /* system CPU time used */
+};
+#define getrusage(A,B) memset(B,0,sizeof(*B))
+#endif
+
+/* Saved resource information for the beginning of an operation */
+static struct rusage sBegin; /* CPU time at start */
+static sqlite3_int64 iBegin; /* Wall-clock time at start */
+
+/*
+** Begin timing an operation
+*/
+static void beginTimer(void){
+ if( enableTimer ){
+ getrusage(RUSAGE_SELF, &sBegin);
+ iBegin = timeOfDay();
+ }
+}
+
+/* Return the difference of two time_structs in seconds */
+static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
+ return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
+ (double)(pEnd->tv_sec - pStart->tv_sec);
+}
+
+/*
+** Print the timing results.
+*/
+static void endTimer(void){
+ if( enableTimer ){
+ sqlite3_int64 iEnd = timeOfDay();
+ struct rusage sEnd;
+ getrusage(RUSAGE_SELF, &sEnd);
+ printf("Run Time: real %.3f user %f sys %f\n",
+ (iEnd - iBegin)*0.001,
+ timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
+ timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
+ }
+}
+
+#define BEGIN_TIMER beginTimer()
+#define END_TIMER endTimer()
+#define HAS_TIMER 1
+
+#elif (defined(_WIN32) || defined(WIN32))
+
+/* Saved resource information for the beginning of an operation */
+static HANDLE hProcess;
+static FILETIME ftKernelBegin;
+static FILETIME ftUserBegin;
+static sqlite3_int64 ftWallBegin;
+
+/*
+** Begin timing an operation
+*/
+static void beginTimer(void){
+ if( enableTimer ){
+ FILETIME ftCreation, ftExit;
+ GetProcessTimes(hProcess,&ftCreation,&ftExit,
+ &ftKernelBegin,&ftUserBegin);
+ ftWallBegin = timeOfDay();
+ }
+}
+
+/* Return the difference of two FILETIME structs in seconds */
+static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
+ sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
+ sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
+ return (double) ((i64End - i64Start) / 10000000.0);
+}
+
+/*
+** Print the timing results.
+*/
+static void endTimer(void){
+ if( enableTimer){
+ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
+ sqlite3_int64 ftWallEnd = timeOfDay();
+ GetProcessTimes(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
+ printf("Run Time: real %.3f user %f sys %f\n",
+ (ftWallEnd - ftWallBegin)*0.001,
+ timeDiff(&ftUserBegin, &ftUserEnd),
+ timeDiff(&ftKernelBegin, &ftKernelEnd));
+ }
+}
+
+#define BEGIN_TIMER beginTimer()
+#define END_TIMER endTimer()
+#define HAS_TIMER 1
+
+#else
+#define BEGIN_TIMER
+#define END_TIMER
+#define HAS_TIMER 0
+#endif
+
+/*
+** Used to prevent warnings about unused parameters
+*/
+#define UNUSED_PARAMETER(x) (void)(x)
+
+/*
+** Number of elements in an array
+*/
+#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
+
+/*
+** If the following flag is set, then command execution stops
+** at an error if we are not interactive.
+*/
+static int bail_on_error = 0;
+
+/*
+** Threat stdin as an interactive input if the following variable
+** is true. Otherwise, assume stdin is connected to a file or pipe.
+*/
+static int stdin_is_interactive = 1;
+
+/*
+** On Windows systems we have to know if standard output is a console
+** in order to translate UTF-8 into MBCS. The following variable is
+** true if translation is required.
+*/
+static int stdout_is_console = 1;
+
+/*
+** The following is the open SQLite database. We make a pointer
+** to this database a static variable so that it can be accessed
+** by the SIGINT handler to interrupt database processing.
+*/
+static sqlite3 *globalDb = 0;
+
+/*
+** True if an interrupt (Control-C) has been received.
+*/
+static volatile int seenInterrupt = 0;
+
+/*
+** This is the name of our program. It is set in main(), used
+** in a number of other places, mostly for error messages.
+*/
+static char *Argv0;
+
+/*
+** Prompt strings. Initialized in main. Settable with
+** .prompt main continue
+*/
+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
+
+/* Indicate out-of-memory and exit. */
+static void shell_out_of_memory(void){
+ raw_printf(stderr,"Error: out of memory\n");
+ exit(1);
+}
+
+/*
+** Write I/O traces to the following stream.
+*/
+#ifdef SQLITE_ENABLE_IOTRACE
+static FILE *iotrace = 0;
+#endif
+
+/*
+** This routine works like printf in that its first argument is a
+** format string and subsequent arguments are values to be substituted
+** in place of % fields. The result of formatting this string
+** is written to iotrace.
+*/
+#ifdef SQLITE_ENABLE_IOTRACE
+static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ if( iotrace==0 ) return;
+ va_start(ap, zFormat);
+ z = sqlite3_vmprintf(zFormat, ap);
+ va_end(ap);
+ utf8_printf(iotrace, "%s", z);
+ sqlite3_free(z);
+}
+#endif
+
+/*
+** Output string zUtf to stream pOut as w characters. If w is negative,
+** then right-justify the text. W is the width in UTF-8 characters, not
+** in bytes. This is different from the %*.*s specification in printf
+** since with %*.*s the width is measured in bytes, not characters.
+*/
+static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
+ int i;
+ int n;
+ int aw = w<0 ? -w : w;
+ char zBuf[1000];
+ if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
+ for(i=n=0; zUtf[i]; i++){
+ if( (zUtf[i]&0xc0)!=0x80 ){
+ n++;
+ if( n==aw ){
+ do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
+ break;
+ }
+ }
+ }
+ if( n>=aw ){
+ utf8_printf(pOut, "%.*s", i, zUtf);
+ }else if( w<0 ){
+ utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
+ }else{
+ utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
+ }
+}
+
+
+/*
+** Determines if a string is a number of not.
+*/
+static int isNumber(const char *z, int *realnum){
+ if( *z=='-' || *z=='+' ) z++;
+ if( !IsDigit(*z) ){
+ return 0;
+ }
+ z++;
+ if( realnum ) *realnum = 0;
+ while( IsDigit(*z) ){ z++; }
+ if( *z=='.' ){
+ z++;
+ if( !IsDigit(*z) ) return 0;
+ while( IsDigit(*z) ){ z++; }
+ if( realnum ) *realnum = 1;
+ }
+ if( *z=='e' || *z=='E' ){
+ z++;
+ if( *z=='+' || *z=='-' ) z++;
+ if( !IsDigit(*z) ) return 0;
+ while( IsDigit(*z) ){ z++; }
+ if( realnum ) *realnum = 1;
+ }
+ return *z==0;
+}
+
+/*
+** Compute a string length that is limited to what can be stored in
+** lower 30 bits of a 32-bit signed integer.
+*/
+static int strlen30(const char *z){
+ const char *z2 = z;
+ while( *z2 ){ z2++; }
+ return 0x3fffffff & (int)(z2 - z);
+}
+
+/*
+** Return the length of a string in characters. Multibyte UTF8 characters
+** count as a single character.
+*/
+static int strlenChar(const char *z){
+ int n = 0;
+ while( *z ){
+ if( (0xc0&*(z++))!=0x80 ) n++;
+ }
+ return n;
+}
+
+/*
+** This routine reads a line of text from FILE in, stores
+** the text in memory obtained from malloc() and returns a pointer
+** to the text. NULL is returned at end of file, or if malloc()
+** fails.
+**
+** If zLine is not NULL then it is a malloced buffer returned from
+** a previous call to this routine that may be reused.
+*/
+static char *local_getline(char *zLine, FILE *in){
+ int nLine = zLine==0 ? 0 : 100;
+ int n = 0;
+
+ while( 1 ){
+ if( n+100>nLine ){
+ nLine = nLine*2 + 100;
+ zLine = realloc(zLine, nLine);
+ if( zLine==0 ) shell_out_of_memory();
+ }
+ if( fgets(&zLine[n], nLine - n, in)==0 ){
+ if( n==0 ){
+ free(zLine);
+ return 0;
+ }
+ zLine[n] = 0;
+ break;
+ }
+ while( zLine[n] ) n++;
+ if( n>0 && zLine[n-1]=='\n' ){
+ n--;
+ if( n>0 && zLine[n-1]=='\r' ) n--;
+ zLine[n] = 0;
+ break;
+ }
+ }
+#if defined(_WIN32) || defined(WIN32)
+ /* For interactive input on Windows systems, translate the
+ ** multi-byte characterset characters into UTF-8. */
+ if( stdin_is_interactive && in==stdin ){
+ char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
+ if( zTrans ){
+ int nTrans = strlen30(zTrans)+1;
+ if( nTrans>nLine ){
+ zLine = realloc(zLine, nTrans);
+ if( zLine==0 ) shell_out_of_memory();
+ }
+ memcpy(zLine, zTrans, nTrans);
+ sqlite3_free(zTrans);
+ }
+ }
+#endif /* defined(_WIN32) || defined(WIN32) */
+ return zLine;
+}
+
+/*
+** Retrieve a single line of input text.
+**
+** If in==0 then read from standard input and prompt before each line.
+** If isContinuation is true, then a continuation prompt is appropriate.
+** If isContinuation is zero, then the main prompt should be used.
+**
+** If zPrior is not NULL then it is a buffer from a prior call to this
+** routine that can be reused.
+**
+** The result is stored in space obtained from malloc() and must either
+** be freed by the caller or else passed back into this routine via the
+** zPrior argument for reuse.
+*/
+static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
+ char *zPrompt;
+ char *zResult;
+ if( in!=0 ){
+ zResult = local_getline(zPrior, in);
+ }else{
+ zPrompt = isContinuation ? continuePrompt : mainPrompt;
+#if SHELL_USE_LOCAL_GETLINE
+ printf("%s", zPrompt);
+ fflush(stdout);
+ zResult = local_getline(zPrior, stdin);
+#else
+ free(zPrior);
+ zResult = shell_readline(zPrompt);
+ if( zResult && *zResult ) shell_add_history(zResult);
+#endif
+ }
+ return zResult;
+}
+
+
+/*
+** Return the value of a hexadecimal digit. Return -1 if the input
+** is not a hex digit.
+*/
+static int hexDigitValue(char c){
+ if( c>='0' && c<='9' ) return c - '0';
+ if( c>='a' && c<='f' ) return c - 'a' + 10;
+ if( c>='A' && c<='F' ) return c - 'A' + 10;
+ return -1;
+}
+
+/*
+** Interpret zArg as an integer value, possibly with suffixes.
+*/
+static sqlite3_int64 integerValue(const char *zArg){
+ sqlite3_int64 v = 0;
+ static const struct { char *zSuffix; int iMult; } aMult[] = {
+ { "KiB", 1024 },
+ { "MiB", 1024*1024 },
+ { "GiB", 1024*1024*1024 },
+ { "KB", 1000 },
+ { "MB", 1000000 },
+ { "GB", 1000000000 },
+ { "K", 1000 },
+ { "M", 1000000 },
+ { "G", 1000000000 },
+ };
+ int i;
+ int isNeg = 0;
+ if( zArg[0]=='-' ){
+ isNeg = 1;
+ zArg++;
+ }else if( zArg[0]=='+' ){
+ zArg++;
+ }
+ if( zArg[0]=='0' && zArg[1]=='x' ){
+ int x;
+ zArg += 2;
+ while( (x = hexDigitValue(zArg[0]))>=0 ){
+ v = (v<<4) + x;
+ zArg++;
+ }
+ }else{
+ while( IsDigit(zArg[0]) ){
+ v = v*10 + zArg[0] - '0';
+ zArg++;
+ }
+ }
+ for(i=0; i<ArraySize(aMult); i++){
+ if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
+ v *= aMult[i].iMult;
+ break;
+ }
+ }
+ return isNeg? -v : v;
+}
+
+/*
+** A variable length string to which one can append text.
+*/
+typedef struct ShellText ShellText;
+struct ShellText {
+ char *z;
+ int n;
+ int nAlloc;
+};
+
+/*
+** Initialize and destroy a ShellText object
+*/
+static void initText(ShellText *p){
+ memset(p, 0, sizeof(*p));
+}
+static void freeText(ShellText *p){
+ free(p->z);
+ initText(p);
+}
+
+/* zIn is either a pointer to a NULL-terminated string in memory obtained
+** from malloc(), or a NULL pointer. The string pointed to by zAppend is
+** added to zIn, and the result returned in memory obtained from malloc().
+** zIn, if it was not NULL, is freed.
+**
+** If the third argument, quote, is not '\0', then it is used as a
+** quote character for zAppend.
+*/
+static void appendText(ShellText *p, char const *zAppend, char quote){
+ int len;
+ int i;
+ int nAppend = strlen30(zAppend);
+
+ len = nAppend+p->n+1;
+ if( quote ){
+ len += 2;
+ for(i=0; i<nAppend; i++){
+ if( zAppend[i]==quote ) len++;
+ }
+ }
+
+ if( p->n+len>=p->nAlloc ){
+ p->nAlloc = p->nAlloc*2 + len + 20;
+ p->z = realloc(p->z, p->nAlloc);
+ if( p->z==0 ) shell_out_of_memory();
+ }
+
+ if( quote ){
+ char *zCsr = p->z+p->n;
+ *zCsr++ = quote;
+ for(i=0; i<nAppend; i++){
+ *zCsr++ = zAppend[i];
+ if( zAppend[i]==quote ) *zCsr++ = quote;
+ }
+ *zCsr++ = quote;
+ p->n = (int)(zCsr - p->z);
+ *zCsr = '\0';
+ }else{
+ memcpy(p->z+p->n, zAppend, nAppend);
+ p->n += nAppend;
+ p->z[p->n] = '\0';
+ }
+}
+
+/*
+** Attempt to determine if identifier zName needs to be quoted, either
+** because it contains non-alphanumeric characters, or because it is an
+** SQLite keyword. Be conservative in this estimate: When in doubt assume
+** that quoting is required.
+**
+** Return '"' if quoting is required. Return 0 if no quoting is required.
+*/
+static char quoteChar(const char *zName){
+ int i;
+ if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
+ for(i=0; zName[i]; i++){
+ if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
+ }
+ return sqlite3_keyword_check(zName, i) ? '"' : 0;
+}
+
+/*
+** Construct a fake object name and column list to describe the structure
+** of the view, virtual table, or table valued function zSchema.zName.
+*/
+static char *shellFakeSchema(
+ sqlite3 *db, /* The database connection containing the vtab */
+ const char *zSchema, /* Schema of the database holding the vtab */
+ const char *zName /* The name of the virtual table */
+){
+ sqlite3_stmt *pStmt = 0;
+ char *zSql;
+ ShellText s;
+ char cQuote;
+ char *zDiv = "(";
+ int nRow = 0;
+
+ zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;",
+ zSchema ? zSchema : "main", zName);
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ initText(&s);
+ if( zSchema ){
+ cQuote = quoteChar(zSchema);
+ if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0;
+ appendText(&s, zSchema, cQuote);
+ appendText(&s, ".", 0);
+ }
+ cQuote = quoteChar(zName);
+ appendText(&s, zName, cQuote);
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ const char *zCol = (const char*)sqlite3_column_text(pStmt, 1);
+ nRow++;
+ appendText(&s, zDiv, 0);
+ zDiv = ",";
+ cQuote = quoteChar(zCol);
+ appendText(&s, zCol, cQuote);
+ }
+ appendText(&s, ")", 0);
+ sqlite3_finalize(pStmt);
+ if( nRow==0 ){
+ freeText(&s);
+ s.z = 0;
+ }
+ return s.z;
+}
+
+/*
+** SQL function: shell_module_schema(X)
+**
+** Return a fake schema for the table-valued function or eponymous virtual
+** table X.
+*/
+static void shellModuleSchema(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ const char *zName = (const char*)sqlite3_value_text(apVal[0]);
+ char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
+ UNUSED_PARAMETER(nVal);
+ if( zFake ){
+ sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
+ -1, sqlite3_free);
+ free(zFake);
+ }
+}
+
+/*
+** SQL function: shell_add_schema(S,X)
+**
+** Add the schema name X to the CREATE statement in S and return the result.
+** Examples:
+**
+** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x);
+**
+** Also works on
+**
+** CREATE INDEX
+** CREATE UNIQUE INDEX
+** CREATE VIEW
+** CREATE TRIGGER
+** CREATE VIRTUAL TABLE
+**
+** This UDF is used by the .schema command to insert the schema name of
+** attached databases into the middle of the sqlite_master.sql field.
+*/
+static void shellAddSchemaName(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ static const char *aPrefix[] = {
+ "TABLE",
+ "INDEX",
+ "UNIQUE INDEX",
+ "VIEW",
+ "TRIGGER",
+ "VIRTUAL TABLE"
+ };
+ int i = 0;
+ const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
+ const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
+ const char *zName = (const char*)sqlite3_value_text(apVal[2]);
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
+ UNUSED_PARAMETER(nVal);
+ if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
+ for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
+ int n = strlen30(aPrefix[i]);
+ if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
+ char *z = 0;
+ char *zFake = 0;
+ if( zSchema ){
+ char cQuote = quoteChar(zSchema);
+ if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){
+ z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
+ }else{
+ z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
+ }
+ }
+ if( zName
+ && aPrefix[i][0]=='V'
+ && (zFake = shellFakeSchema(db, zSchema, zName))!=0
+ ){
+ if( z==0 ){
+ z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
+ }else{
+ z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
+ }
+ free(zFake);
+ }
+ if( z ){
+ sqlite3_result_text(pCtx, z, -1, sqlite3_free);
+ return;
+ }
+ }
+ }
+ }
+ sqlite3_result_value(pCtx, apVal[0]);
+}
+
+/*
+** The source code for several run-time loadable extensions is inserted
+** below by the ../tool/mkshellc.tcl script. Before processing that included
+** code, we need to override some macros to make the included program code
+** work here in the middle of this regular program.
+*/
+#define SQLITE_EXTENSION_INIT1
+#define SQLITE_EXTENSION_INIT2(X) (void)(X)
+
+#if defined(_WIN32) && defined(_MSC_VER)
+/************************* Begin test_windirent.h ******************/
+/*
+** 2015 November 30
+**
+** 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 contains declarations for most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
+#define SQLITE_WINDIRENT_H
+
+/*
+** We need several data types from the Windows SDK header.
+*/
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include "windows.h"
+
+/*
+** We need several support functions from the SQLite core.
+*/
+
+
+/*
+** We need several things from the ANSI and MSVCRT headers.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <io.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*
+** We may need several defines that should have been in "sys/stat.h".
+*/
+
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+
+#ifndef S_ISLNK
+#define S_ISLNK(mode) (0)
+#endif
+
+/*
+** We may need to provide the "mode_t" type.
+*/
+
+#ifndef MODE_T_DEFINED
+ #define MODE_T_DEFINED
+ typedef unsigned short mode_t;
+#endif
+
+/*
+** We may need to provide the "ino_t" type.
+*/
+
+#ifndef INO_T_DEFINED
+ #define INO_T_DEFINED
+ typedef unsigned short ino_t;
+#endif
+
+/*
+** We need to define "NAME_MAX" if it was not present in "limits.h".
+*/
+
+#ifndef NAME_MAX
+# ifdef FILENAME_MAX
+# define NAME_MAX (FILENAME_MAX)
+# else
+# define NAME_MAX (260)
+# endif
+#endif
+
+/*
+** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
+*/
+
+#ifndef NULL_INTPTR_T
+# define NULL_INTPTR_T ((intptr_t)(0))
+#endif
+
+#ifndef BAD_INTPTR_T
+# define BAD_INTPTR_T ((intptr_t)(-1))
+#endif
+
+/*
+** We need to provide the necessary structures and related types.
+*/
+
+#ifndef DIRENT_DEFINED
+#define DIRENT_DEFINED
+typedef struct DIRENT DIRENT;
+typedef DIRENT *LPDIRENT;
+struct DIRENT {
+ ino_t d_ino; /* Sequence number, do not use. */
+ unsigned d_attributes; /* Win32 file attributes. */
+ char d_name[NAME_MAX + 1]; /* Name within the directory. */
+};
+#endif
+
+#ifndef DIR_DEFINED
+#define DIR_DEFINED
+typedef struct DIR DIR;
+typedef DIR *LPDIR;
+struct DIR {
+ intptr_t d_handle; /* Value returned by "_findfirst". */
+ DIRENT d_first; /* DIRENT constructed based on "_findfirst". */
+ DIRENT d_next; /* DIRENT constructed based on "_findnext". */
+};
+#endif
+
+/*
+** Provide a macro, for use by the implementation, to determine if a
+** particular directory entry should be skipped over when searching for
+** the next directory entry that should be returned by the readdir() or
+** readdir_r() functions.
+*/
+
+#ifndef is_filtered
+# define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM))
+#endif
+
+/*
+** Provide the function prototype for the POSIX compatiable getenv()
+** function. This function is not thread-safe.
+*/
+
+extern const char *windirent_getenv(const char *name);
+
+/*
+** Finally, we can provide the function prototypes for the opendir(),
+** readdir(), readdir_r(), and closedir() POSIX functions.
+*/
+
+extern LPDIR opendir(const char *dirname);
+extern LPDIRENT readdir(LPDIR dirp);
+extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
+extern INT closedir(LPDIR dirp);
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */
+
+/************************* End test_windirent.h ********************/
+/************************* Begin test_windirent.c ******************/
+/*
+** 2015 November 30
+**
+** 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 contains code to implement most of the opendir() family of
+** POSIX functions on Win32 using the MSVCRT.
+*/
+
+#if defined(_WIN32) && defined(_MSC_VER)
+/* #include "test_windirent.h" */
+
+/*
+** Implementation of the POSIX getenv() function using the Win32 API.
+** This function is not thread-safe.
+*/
+const char *windirent_getenv(
+ const char *name
+){
+ static char value[32768]; /* Maximum length, per MSDN */
+ DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
+ DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
+
+ memset(value, 0, sizeof(value));
+ dwRet = GetEnvironmentVariableA(name, value, dwSize);
+ if( dwRet==0 || dwRet>dwSize ){
+ /*
+ ** The function call to GetEnvironmentVariableA() failed -OR-
+ ** the buffer is not large enough. Either way, return NULL.
+ */
+ return 0;
+ }else{
+ /*
+ ** The function call to GetEnvironmentVariableA() succeeded
+ ** -AND- the buffer contains the entire value.
+ */
+ return value;
+ }
+}
+
+/*
+** Implementation of the POSIX opendir() function using the MSVCRT.
+*/
+LPDIR opendir(
+ const char *dirname
+){
+ struct _finddata_t data;
+ LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
+ SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
+
+ if( dirp==NULL ) return NULL;
+ memset(dirp, 0, sizeof(DIR));
+
+ /* TODO: Remove this if Unix-style root paths are not used. */
+ if( sqlite3_stricmp(dirname, "/")==0 ){
+ dirname = windirent_getenv("SystemDrive");
+ }
+
+ memset(&data, 0, sizeof(struct _finddata_t));
+ _snprintf(data.name, namesize, "%s\\*", dirname);
+ dirp->d_handle = _findfirst(data.name, &data);
+
+ if( dirp->d_handle==BAD_INTPTR_T ){
+ closedir(dirp);
+ return NULL;
+ }
+
+ /* TODO: Remove this block to allow hidden and/or system files. */
+ if( is_filtered(data) ){
+next:
+
+ memset(&data, 0, sizeof(struct _finddata_t));
+ if( _findnext(dirp->d_handle, &data)==-1 ){
+ closedir(dirp);
+ return NULL;
+ }
+
+ /* TODO: Remove this block to allow hidden and/or system files. */
+ if( is_filtered(data) ) goto next;
+ }
+
+ dirp->d_first.d_attributes = data.attrib;
+ strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
+ dirp->d_first.d_name[NAME_MAX] = '\0';
+
+ return dirp;
+}
+
+/*
+** Implementation of the POSIX readdir() function using the MSVCRT.
+*/
+LPDIRENT readdir(
+ LPDIR dirp
+){
+ struct _finddata_t data;
+
+ if( dirp==NULL ) return NULL;
+
+ if( dirp->d_first.d_ino==0 ){
+ dirp->d_first.d_ino++;
+ dirp->d_next.d_ino++;
+
+ return &dirp->d_first;
+ }
+
+next:
+
+ memset(&data, 0, sizeof(struct _finddata_t));
+ if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
+
+ /* TODO: Remove this block to allow hidden and/or system files. */
+ if( is_filtered(data) ) goto next;
+
+ dirp->d_next.d_ino++;
+ dirp->d_next.d_attributes = data.attrib;
+ strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
+ dirp->d_next.d_name[NAME_MAX] = '\0';
+
+ return &dirp->d_next;
+}
+
+/*
+** Implementation of the POSIX readdir_r() function using the MSVCRT.
+*/
+INT readdir_r(
+ LPDIR dirp,
+ LPDIRENT entry,
+ LPDIRENT *result
+){
+ struct _finddata_t data;
+
+ if( dirp==NULL ) return EBADF;
+
+ if( dirp->d_first.d_ino==0 ){
+ dirp->d_first.d_ino++;
+ dirp->d_next.d_ino++;
+
+ entry->d_ino = dirp->d_first.d_ino;
+ entry->d_attributes = dirp->d_first.d_attributes;
+ strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
+ entry->d_name[NAME_MAX] = '\0';
+
+ *result = entry;
+ return 0;
+ }
+
+next:
+
+ memset(&data, 0, sizeof(struct _finddata_t));
+ if( _findnext(dirp->d_handle, &data)==-1 ){
+ *result = NULL;
+ return ENOENT;
+ }
+
+ /* TODO: Remove this block to allow hidden and/or system files. */
+ if( is_filtered(data) ) goto next;
+
+ entry->d_ino = (ino_t)-1; /* not available */
+ entry->d_attributes = data.attrib;
+ strncpy(entry->d_name, data.name, NAME_MAX);
+ entry->d_name[NAME_MAX] = '\0';
+
+ *result = entry;
+ return 0;
+}
+
+/*
+** Implementation of the POSIX closedir() function using the MSVCRT.
+*/
+INT closedir(
+ LPDIR dirp
+){
+ INT result = 0;
+
+ if( dirp==NULL ) return EINVAL;
+
+ if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
+ result = _findclose(dirp->d_handle);
+ }
+
+ sqlite3_free(dirp);
+ return result;
+}
+
+#endif /* defined(WIN32) && defined(_MSC_VER) */
+
+/************************* End test_windirent.c ********************/
+#define dirent DIRENT
+#endif
+/************************* Begin ../ext/misc/shathree.c ******************/
+/*
+** 2017-03-08
+**
+** 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 SQLite extension implements a functions that compute SHA1 hashes.
+** Two SQL functions are implemented:
+**
+** sha3(X,SIZE)
+** sha3_query(Y,SIZE)
+**
+** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
+** X is NULL.
+**
+** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
+** and returns a hash of their results.
+**
+** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
+** is used. If SIZE is included it must be one of the integers 224, 256,
+** 384, or 512, to determine SHA3 hash variant that is computed.
+*/
+SQLITE_EXTENSION_INIT1
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+/* typedef sqlite3_uint64 u64; */
+
+/******************************************************************************
+** The Hash Engine
+*/
+/*
+** Macros to determine whether the machine is big or little endian,
+** and whether or not that determination is run-time or compile-time.
+**
+** For best performance, an attempt is made to guess at the byte-order
+** using C-preprocessor macros. If that is unsuccessful, or if
+** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
+** at run-time.
+*/
+#ifndef SHA3_BYTEORDER
+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__arm__)
+# define SHA3_BYTEORDER 1234
+# elif defined(sparc) || defined(__ppc__)
+# define SHA3_BYTEORDER 4321
+# else
+# define SHA3_BYTEORDER 0
+# endif
+#endif
+
+
+/*
+** State structure for a SHA3 hash in progress
+*/
+typedef struct SHA3Context SHA3Context;
+struct SHA3Context {
+ union {
+ u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
+ unsigned char x[1600]; /* ... or 1600 bytes */
+ } u;
+ unsigned nRate; /* Bytes of input accepted per Keccak iteration */
+ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
+ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
+};
+
+/* Allow the following routine to use the B0 variable, which is also
+** a macro in the termios.h header file */
+#undef B0
+
+/*
+** A single step of the Keccak mixing function for a 1600-bit state
+*/
+static void KeccakF1600Step(SHA3Context *p){
+ int i;
+ u64 b0, b1, b2, b3, b4;
+ u64 c0, c1, c2, c3, c4;
+ u64 d0, d1, d2, d3, d4;
+ static const u64 RC[] = {
+ 0x0000000000000001ULL, 0x0000000000008082ULL,
+ 0x800000000000808aULL, 0x8000000080008000ULL,
+ 0x000000000000808bULL, 0x0000000080000001ULL,
+ 0x8000000080008081ULL, 0x8000000000008009ULL,
+ 0x000000000000008aULL, 0x0000000000000088ULL,
+ 0x0000000080008009ULL, 0x000000008000000aULL,
+ 0x000000008000808bULL, 0x800000000000008bULL,
+ 0x8000000000008089ULL, 0x8000000000008003ULL,
+ 0x8000000000008002ULL, 0x8000000000000080ULL,
+ 0x000000000000800aULL, 0x800000008000000aULL,
+ 0x8000000080008081ULL, 0x8000000000008080ULL,
+ 0x0000000080000001ULL, 0x8000000080008008ULL
+ };
+# define a00 (p->u.s[0])
+# define a01 (p->u.s[1])
+# define a02 (p->u.s[2])
+# define a03 (p->u.s[3])
+# define a04 (p->u.s[4])
+# define a10 (p->u.s[5])
+# define a11 (p->u.s[6])
+# define a12 (p->u.s[7])
+# define a13 (p->u.s[8])
+# define a14 (p->u.s[9])
+# define a20 (p->u.s[10])
+# define a21 (p->u.s[11])
+# define a22 (p->u.s[12])
+# define a23 (p->u.s[13])
+# define a24 (p->u.s[14])
+# define a30 (p->u.s[15])
+# define a31 (p->u.s[16])
+# define a32 (p->u.s[17])
+# define a33 (p->u.s[18])
+# define a34 (p->u.s[19])
+# define a40 (p->u.s[20])
+# define a41 (p->u.s[21])
+# define a42 (p->u.s[22])
+# define a43 (p->u.s[23])
+# define a44 (p->u.s[24])
+# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
+
+ for(i=0; i<24; i+=4){
+ c0 = a00^a10^a20^a30^a40;
+ c1 = a01^a11^a21^a31^a41;
+ c2 = a02^a12^a22^a32^a42;
+ c3 = a03^a13^a23^a33^a43;
+ c4 = a04^a14^a24^a34^a44;
+ d0 = c4^ROL64(c1, 1);
+ d1 = c0^ROL64(c2, 1);
+ d2 = c1^ROL64(c3, 1);
+ d3 = c2^ROL64(c4, 1);
+ d4 = c3^ROL64(c0, 1);
+
+ b0 = (a00^d0);
+ b1 = ROL64((a11^d1), 44);
+ b2 = ROL64((a22^d2), 43);
+ b3 = ROL64((a33^d3), 21);
+ b4 = ROL64((a44^d4), 14);
+ a00 = b0 ^((~b1)& b2 );
+ a00 ^= RC[i];
+ a11 = b1 ^((~b2)& b3 );
+ a22 = b2 ^((~b3)& b4 );
+ a33 = b3 ^((~b4)& b0 );
+ a44 = b4 ^((~b0)& b1 );
+
+ b2 = ROL64((a20^d0), 3);
+ b3 = ROL64((a31^d1), 45);
+ b4 = ROL64((a42^d2), 61);
+ b0 = ROL64((a03^d3), 28);
+ b1 = ROL64((a14^d4), 20);
+ a20 = b0 ^((~b1)& b2 );
+ a31 = b1 ^((~b2)& b3 );
+ a42 = b2 ^((~b3)& b4 );
+ a03 = b3 ^((~b4)& b0 );
+ a14 = b4 ^((~b0)& b1 );
+
+ b4 = ROL64((a40^d0), 18);
+ b0 = ROL64((a01^d1), 1);
+ b1 = ROL64((a12^d2), 6);
+ b2 = ROL64((a23^d3), 25);
+ b3 = ROL64((a34^d4), 8);
+ a40 = b0 ^((~b1)& b2 );
+ a01 = b1 ^((~b2)& b3 );
+ a12 = b2 ^((~b3)& b4 );
+ a23 = b3 ^((~b4)& b0 );
+ a34 = b4 ^((~b0)& b1 );
+
+ b1 = ROL64((a10^d0), 36);
+ b2 = ROL64((a21^d1), 10);
+ b3 = ROL64((a32^d2), 15);
+ b4 = ROL64((a43^d3), 56);
+ b0 = ROL64((a04^d4), 27);
+ a10 = b0 ^((~b1)& b2 );
+ a21 = b1 ^((~b2)& b3 );
+ a32 = b2 ^((~b3)& b4 );
+ a43 = b3 ^((~b4)& b0 );
+ a04 = b4 ^((~b0)& b1 );
+
+ b3 = ROL64((a30^d0), 41);
+ b4 = ROL64((a41^d1), 2);
+ b0 = ROL64((a02^d2), 62);
+ b1 = ROL64((a13^d3), 55);
+ b2 = ROL64((a24^d4), 39);
+ a30 = b0 ^((~b1)& b2 );
+ a41 = b1 ^((~b2)& b3 );
+ a02 = b2 ^((~b3)& b4 );
+ a13 = b3 ^((~b4)& b0 );
+ a24 = b4 ^((~b0)& b1 );
+
+ c0 = a00^a20^a40^a10^a30;
+ c1 = a11^a31^a01^a21^a41;
+ c2 = a22^a42^a12^a32^a02;
+ c3 = a33^a03^a23^a43^a13;
+ c4 = a44^a14^a34^a04^a24;
+ d0 = c4^ROL64(c1, 1);
+ d1 = c0^ROL64(c2, 1);
+ d2 = c1^ROL64(c3, 1);
+ d3 = c2^ROL64(c4, 1);
+ d4 = c3^ROL64(c0, 1);
+
+ b0 = (a00^d0);
+ b1 = ROL64((a31^d1), 44);
+ b2 = ROL64((a12^d2), 43);
+ b3 = ROL64((a43^d3), 21);
+ b4 = ROL64((a24^d4), 14);
+ a00 = b0 ^((~b1)& b2 );
+ a00 ^= RC[i+1];
+ a31 = b1 ^((~b2)& b3 );
+ a12 = b2 ^((~b3)& b4 );
+ a43 = b3 ^((~b4)& b0 );
+ a24 = b4 ^((~b0)& b1 );
+
+ b2 = ROL64((a40^d0), 3);
+ b3 = ROL64((a21^d1), 45);
+ b4 = ROL64((a02^d2), 61);
+ b0 = ROL64((a33^d3), 28);
+ b1 = ROL64((a14^d4), 20);
+ a40 = b0 ^((~b1)& b2 );
+ a21 = b1 ^((~b2)& b3 );
+ a02 = b2 ^((~b3)& b4 );
+ a33 = b3 ^((~b4)& b0 );
+ a14 = b4 ^((~b0)& b1 );
+
+ b4 = ROL64((a30^d0), 18);
+ b0 = ROL64((a11^d1), 1);
+ b1 = ROL64((a42^d2), 6);
+ b2 = ROL64((a23^d3), 25);
+ b3 = ROL64((a04^d4), 8);
+ a30 = b0 ^((~b1)& b2 );
+ a11 = b1 ^((~b2)& b3 );
+ a42 = b2 ^((~b3)& b4 );
+ a23 = b3 ^((~b4)& b0 );
+ a04 = b4 ^((~b0)& b1 );
+
+ b1 = ROL64((a20^d0), 36);
+ b2 = ROL64((a01^d1), 10);
+ b3 = ROL64((a32^d2), 15);
+ b4 = ROL64((a13^d3), 56);
+ b0 = ROL64((a44^d4), 27);
+ a20 = b0 ^((~b1)& b2 );
+ a01 = b1 ^((~b2)& b3 );
+ a32 = b2 ^((~b3)& b4 );
+ a13 = b3 ^((~b4)& b0 );
+ a44 = b4 ^((~b0)& b1 );
+
+ b3 = ROL64((a10^d0), 41);
+ b4 = ROL64((a41^d1), 2);
+ b0 = ROL64((a22^d2), 62);
+ b1 = ROL64((a03^d3), 55);
+ b2 = ROL64((a34^d4), 39);
+ a10 = b0 ^((~b1)& b2 );
+ a41 = b1 ^((~b2)& b3 );
+ a22 = b2 ^((~b3)& b4 );
+ a03 = b3 ^((~b4)& b0 );
+ a34 = b4 ^((~b0)& b1 );
+
+ c0 = a00^a40^a30^a20^a10;
+ c1 = a31^a21^a11^a01^a41;
+ c2 = a12^a02^a42^a32^a22;
+ c3 = a43^a33^a23^a13^a03;
+ c4 = a24^a14^a04^a44^a34;
+ d0 = c4^ROL64(c1, 1);
+ d1 = c0^ROL64(c2, 1);
+ d2 = c1^ROL64(c3, 1);
+ d3 = c2^ROL64(c4, 1);
+ d4 = c3^ROL64(c0, 1);
+
+ b0 = (a00^d0);
+ b1 = ROL64((a21^d1), 44);
+ b2 = ROL64((a42^d2), 43);
+ b3 = ROL64((a13^d3), 21);
+ b4 = ROL64((a34^d4), 14);
+ a00 = b0 ^((~b1)& b2 );
+ a00 ^= RC[i+2];
+ a21 = b1 ^((~b2)& b3 );
+ a42 = b2 ^((~b3)& b4 );
+ a13 = b3 ^((~b4)& b0 );
+ a34 = b4 ^((~b0)& b1 );
+
+ b2 = ROL64((a30^d0), 3);
+ b3 = ROL64((a01^d1), 45);
+ b4 = ROL64((a22^d2), 61);
+ b0 = ROL64((a43^d3), 28);
+ b1 = ROL64((a14^d4), 20);
+ a30 = b0 ^((~b1)& b2 );
+ a01 = b1 ^((~b2)& b3 );
+ a22 = b2 ^((~b3)& b4 );
+ a43 = b3 ^((~b4)& b0 );
+ a14 = b4 ^((~b0)& b1 );
+
+ b4 = ROL64((a10^d0), 18);
+ b0 = ROL64((a31^d1), 1);
+ b1 = ROL64((a02^d2), 6);
+ b2 = ROL64((a23^d3), 25);
+ b3 = ROL64((a44^d4), 8);
+ a10 = b0 ^((~b1)& b2 );
+ a31 = b1 ^((~b2)& b3 );
+ a02 = b2 ^((~b3)& b4 );
+ a23 = b3 ^((~b4)& b0 );
+ a44 = b4 ^((~b0)& b1 );
+
+ b1 = ROL64((a40^d0), 36);
+ b2 = ROL64((a11^d1), 10);
+ b3 = ROL64((a32^d2), 15);
+ b4 = ROL64((a03^d3), 56);
+ b0 = ROL64((a24^d4), 27);
+ a40 = b0 ^((~b1)& b2 );
+ a11 = b1 ^((~b2)& b3 );
+ a32 = b2 ^((~b3)& b4 );
+ a03 = b3 ^((~b4)& b0 );
+ a24 = b4 ^((~b0)& b1 );
+
+ b3 = ROL64((a20^d0), 41);
+ b4 = ROL64((a41^d1), 2);
+ b0 = ROL64((a12^d2), 62);
+ b1 = ROL64((a33^d3), 55);
+ b2 = ROL64((a04^d4), 39);
+ a20 = b0 ^((~b1)& b2 );
+ a41 = b1 ^((~b2)& b3 );
+ a12 = b2 ^((~b3)& b4 );
+ a33 = b3 ^((~b4)& b0 );
+ a04 = b4 ^((~b0)& b1 );
+
+ c0 = a00^a30^a10^a40^a20;
+ c1 = a21^a01^a31^a11^a41;
+ c2 = a42^a22^a02^a32^a12;
+ c3 = a13^a43^a23^a03^a33;
+ c4 = a34^a14^a44^a24^a04;
+ d0 = c4^ROL64(c1, 1);
+ d1 = c0^ROL64(c2, 1);
+ d2 = c1^ROL64(c3, 1);
+ d3 = c2^ROL64(c4, 1);
+ d4 = c3^ROL64(c0, 1);
+
+ b0 = (a00^d0);
+ b1 = ROL64((a01^d1), 44);
+ b2 = ROL64((a02^d2), 43);
+ b3 = ROL64((a03^d3), 21);
+ b4 = ROL64((a04^d4), 14);
+ a00 = b0 ^((~b1)& b2 );
+ a00 ^= RC[i+3];
+ a01 = b1 ^((~b2)& b3 );
+ a02 = b2 ^((~b3)& b4 );
+ a03 = b3 ^((~b4)& b0 );
+ a04 = b4 ^((~b0)& b1 );
+
+ b2 = ROL64((a10^d0), 3);
+ b3 = ROL64((a11^d1), 45);
+ b4 = ROL64((a12^d2), 61);
+ b0 = ROL64((a13^d3), 28);
+ b1 = ROL64((a14^d4), 20);
+ a10 = b0 ^((~b1)& b2 );
+ a11 = b1 ^((~b2)& b3 );
+ a12 = b2 ^((~b3)& b4 );
+ a13 = b3 ^((~b4)& b0 );
+ a14 = b4 ^((~b0)& b1 );
+
+ b4 = ROL64((a20^d0), 18);
+ b0 = ROL64((a21^d1), 1);
+ b1 = ROL64((a22^d2), 6);
+ b2 = ROL64((a23^d3), 25);
+ b3 = ROL64((a24^d4), 8);
+ a20 = b0 ^((~b1)& b2 );
+ a21 = b1 ^((~b2)& b3 );
+ a22 = b2 ^((~b3)& b4 );
+ a23 = b3 ^((~b4)& b0 );
+ a24 = b4 ^((~b0)& b1 );
+
+ b1 = ROL64((a30^d0), 36);
+ b2 = ROL64((a31^d1), 10);
+ b3 = ROL64((a32^d2), 15);
+ b4 = ROL64((a33^d3), 56);
+ b0 = ROL64((a34^d4), 27);
+ a30 = b0 ^((~b1)& b2 );
+ a31 = b1 ^((~b2)& b3 );
+ a32 = b2 ^((~b3)& b4 );
+ a33 = b3 ^((~b4)& b0 );
+ a34 = b4 ^((~b0)& b1 );
+
+ b3 = ROL64((a40^d0), 41);
+ b4 = ROL64((a41^d1), 2);
+ b0 = ROL64((a42^d2), 62);
+ b1 = ROL64((a43^d3), 55);
+ b2 = ROL64((a44^d4), 39);
+ a40 = b0 ^((~b1)& b2 );
+ a41 = b1 ^((~b2)& b3 );
+ a42 = b2 ^((~b3)& b4 );
+ a43 = b3 ^((~b4)& b0 );
+ a44 = b4 ^((~b0)& b1 );
+ }
+}
+
+/*
+** Initialize a new hash. iSize determines the size of the hash
+** in bits and should be one of 224, 256, 384, or 512. Or iSize
+** can be zero to use the default hash size of 256 bits.
+*/
+static void SHA3Init(SHA3Context *p, int iSize){
+ memset(p, 0, sizeof(*p));
+ if( iSize>=128 && iSize<=512 ){
+ p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
+ }else{
+ p->nRate = (1600 - 2*256)/8;
+ }
+#if SHA3_BYTEORDER==1234
+ /* Known to be little-endian at compile-time. No-op */
+#elif SHA3_BYTEORDER==4321
+ p->ixMask = 7; /* Big-endian */
+#else
+ {
+ static unsigned int one = 1;
+ if( 1==*(unsigned char*)&one ){
+ /* Little endian. No byte swapping. */
+ p->ixMask = 0;
+ }else{
+ /* Big endian. Byte swap. */
+ p->ixMask = 7;
+ }
+ }
+#endif
+}
+
+/*
+** Make consecutive calls to the SHA3Update function to add new content
+** to the hash
+*/
+static void SHA3Update(
+ SHA3Context *p,
+ const unsigned char *aData,
+ unsigned int nData
+){
+ unsigned int i = 0;
+#if SHA3_BYTEORDER==1234
+ if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
+ for(; i+7<nData; i+=8){
+ p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
+ p->nLoaded += 8;
+ if( p->nLoaded>=p->nRate ){
+ KeccakF1600Step(p);
+ p->nLoaded = 0;
+ }
+ }
+ }
+#endif
+ for(; i<nData; i++){
+#if SHA3_BYTEORDER==1234
+ p->u.x[p->nLoaded] ^= aData[i];
+#elif SHA3_BYTEORDER==4321
+ p->u.x[p->nLoaded^0x07] ^= aData[i];
+#else
+ p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
+#endif
+ p->nLoaded++;
+ if( p->nLoaded==p->nRate ){
+ KeccakF1600Step(p);
+ p->nLoaded = 0;
+ }
+ }
+}
+
+/*
+** After all content has been added, invoke SHA3Final() to compute
+** the final hash. The function returns a pointer to the binary
+** hash value.
+*/
+static unsigned char *SHA3Final(SHA3Context *p){
+ unsigned int i;
+ if( p->nLoaded==p->nRate-1 ){
+ const unsigned char c1 = 0x86;
+ SHA3Update(p, &c1, 1);
+ }else{
+ const unsigned char c2 = 0x06;
+ const unsigned char c3 = 0x80;
+ SHA3Update(p, &c2, 1);
+ p->nLoaded = p->nRate - 1;
+ SHA3Update(p, &c3, 1);
+ }
+ for(i=0; i<p->nRate; i++){
+ p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
+ }
+ return &p->u.x[p->nRate];
+}
+/* End of the hashing logic
+*****************************************************************************/
+
+/*
+** Implementation of the sha3(X,SIZE) function.
+**
+** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
+** size is 256. If X is a BLOB, it is hashed as is.
+** For all other non-NULL types of input, X is converted into a UTF-8 string
+** and the string is hashed without the trailing 0x00 terminator. The hash
+** of a NULL value is NULL.
+*/
+static void sha3Func(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ SHA3Context cx;
+ int eType = sqlite3_value_type(argv[0]);
+ int nByte = sqlite3_value_bytes(argv[0]);
+ int iSize;
+ if( argc==1 ){
+ iSize = 256;
+ }else{
+ iSize = sqlite3_value_int(argv[1]);
+ if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
+ sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
+ "384 512", -1);
+ return;
+ }
+ }
+ if( eType==SQLITE_NULL ) return;
+ SHA3Init(&cx, iSize);
+ if( eType==SQLITE_BLOB ){
+ SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
+ }else{
+ SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
+ }
+ sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
+}
+
+/* Compute a string using sqlite3_vsnprintf() with a maximum length
+** of 50 bytes and add it to the hash.
+*/
+static void hash_step_vformat(
+ SHA3Context *p, /* Add content to this context */
+ const char *zFormat,
+ ...
+){
+ va_list ap;
+ int n;
+ char zBuf[50];
+ va_start(ap, zFormat);
+ sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
+ va_end(ap);
+ n = (int)strlen(zBuf);
+ SHA3Update(p, (unsigned char*)zBuf, n);
+}
+
+/*
+** Implementation of the sha3_query(SQL,SIZE) function.
+**
+** This function compiles and runs the SQL statement(s) given in the
+** argument. The results are hashed using a SIZE-bit SHA3. The default
+** size is 256.
+**
+** The format of the byte stream that is hashed is summarized as follows:
+**
+** S<n>:<sql>
+** R
+** N
+** I<int>
+** F<ieee-float>
+** B<size>:<bytes>
+** T<size>:<text>
+**
+** <sql> is the original SQL text for each statement run and <n> is
+** the size of that text. The SQL text is UTF-8. A single R character
+** occurs before the start of each row. N means a NULL value.
+** I mean an 8-byte little-endian integer <int>. F is a floating point
+** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
+** B means blobs of <size> bytes. T means text rendered as <size>
+** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
+** text integers.
+**
+** For each SQL statement in the X input, there is one S segment. Each
+** S segment is followed by zero or more R segments, one for each row in the
+** result set. After each R, there are one or more N, I, F, B, or T segments,
+** one for each column in the result set. Segments are concatentated directly
+** with no delimiters of any kind.
+*/
+static void sha3QueryFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ const char *zSql = (const char*)sqlite3_value_text(argv[0]);
+ sqlite3_stmt *pStmt = 0;
+ int nCol; /* Number of columns in the result set */
+ int i; /* Loop counter */
+ int rc;
+ int n;
+ const char *z;
+ SHA3Context cx;
+ int iSize;
+
+ if( argc==1 ){
+ iSize = 256;
+ }else{
+ iSize = sqlite3_value_int(argv[1]);
+ if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
+ sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
+ "384 512", -1);
+ return;
+ }
+ }
+ if( zSql==0 ) return;
+ SHA3Init(&cx, iSize);
+ while( zSql[0] ){
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
+ if( rc ){
+ char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
+ zSql, sqlite3_errmsg(db));
+ sqlite3_finalize(pStmt);
+ sqlite3_result_error(context, zMsg, -1);
+ sqlite3_free(zMsg);
+ return;
+ }
+ if( !sqlite3_stmt_readonly(pStmt) ){
+ char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
+ sqlite3_finalize(pStmt);
+ sqlite3_result_error(context, zMsg, -1);
+ sqlite3_free(zMsg);
+ return;
+ }
+ nCol = sqlite3_column_count(pStmt);
+ z = sqlite3_sql(pStmt);
+ n = (int)strlen(z);
+ hash_step_vformat(&cx,"S%d:",n);
+ SHA3Update(&cx,(unsigned char*)z,n);
+
+ /* Compute a hash over the result of the query */
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ SHA3Update(&cx,(const unsigned char*)"R",1);
+ for(i=0; i<nCol; i++){
+ switch( sqlite3_column_type(pStmt,i) ){
+ case SQLITE_NULL: {
+ SHA3Update(&cx, (const unsigned char*)"N",1);
+ break;
+ }
+ case SQLITE_INTEGER: {
+ sqlite3_uint64 u;
+ int j;
+ unsigned char x[9];
+ sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
+ memcpy(&u, &v, 8);
+ for(j=8; j>=1; j--){
+ x[j] = u & 0xff;
+ u >>= 8;
+ }
+ x[0] = 'I';
+ SHA3Update(&cx, x, 9);
+ break;
+ }
+ case SQLITE_FLOAT: {
+ sqlite3_uint64 u;
+ int j;
+ unsigned char x[9];
+ double r = sqlite3_column_double(pStmt,i);
+ memcpy(&u, &r, 8);
+ for(j=8; j>=1; j--){
+ x[j] = u & 0xff;
+ u >>= 8;
+ }
+ x[0] = 'F';
+ SHA3Update(&cx,x,9);
+ break;
+ }
+ case SQLITE_TEXT: {
+ int n2 = sqlite3_column_bytes(pStmt, i);
+ const unsigned char *z2 = sqlite3_column_text(pStmt, i);
+ hash_step_vformat(&cx,"T%d:",n2);
+ SHA3Update(&cx, z2, n2);
+ break;
+ }
+ case SQLITE_BLOB: {
+ int n2 = sqlite3_column_bytes(pStmt, i);
+ const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
+ hash_step_vformat(&cx,"B%d:",n2);
+ SHA3Update(&cx, z2, n2);
+ break;
+ }
+ }
+ }
+ }
+ sqlite3_finalize(pStmt);
+ }
+ sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
+}
+
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_shathree_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
+ sha3Func, 0, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
+ sha3Func, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
+ sha3QueryFunc, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
+ sha3QueryFunc, 0, 0);
+ }
+ return rc;
+}
+
+/************************* End ../ext/misc/shathree.c ********************/
+/************************* Begin ../ext/misc/fileio.c ******************/
+/*
+** 2014-06-13
+**
+** 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 SQLite extension implements SQL functions readfile() and
+** writefile(), and eponymous virtual type "fsdir".
+**
+** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
+**
+** If neither of the optional arguments is present, then this UDF
+** function writes blob DATA to file FILE. If successful, the number
+** of bytes written is returned. If an error occurs, NULL is returned.
+**
+** If the first option argument - MODE - is present, then it must
+** be passed an integer value that corresponds to a POSIX mode
+** value (file type + permissions, as returned in the stat.st_mode
+** field by the stat() system call). Three types of files may
+** be written/created:
+**
+** regular files: (mode & 0170000)==0100000
+** symbolic links: (mode & 0170000)==0120000
+** directories: (mode & 0170000)==0040000
+**
+** For a directory, the DATA is ignored. For a symbolic link, it is
+** interpreted as text and used as the target of the link. For a
+** regular file, it is interpreted as a blob and written into the
+** named file. Regardless of the type of file, its permissions are
+** set to (mode & 0777) before returning.
+**
+** If the optional MTIME argument is present, then it is interpreted
+** as an integer - the number of seconds since the unix epoch. The
+** modification-time of the target file is set to this value before
+** returning.
+**
+** If three or more arguments are passed to this function and an
+** error is encountered, an exception is raised.
+**
+** READFILE(FILE):
+**
+** Read and return the contents of file FILE (type blob) from disk.
+**
+** FSDIR:
+**
+** Used as follows:
+**
+** SELECT * FROM fsdir($path [, $dir]);
+**
+** Parameter $path is an absolute or relative pathname. If the file that it
+** refers to does not exist, it is an error. If the path refers to a regular
+** file or symbolic link, it returns a single row. Or, if the path refers
+** to a directory, it returns one row for the directory, and one row for each
+** file within the hierarchy rooted at $path.
+**
+** Each row has the following columns:
+**
+** name: Path to file or directory (text value).
+** mode: Value of stat.st_mode for directory entry (an integer).
+** mtime: Value of stat.st_mtime for directory entry (an integer).
+** data: For a regular file, a blob containing the file data. For a
+** symlink, a text value containing the text of the link. For a
+** directory, NULL.
+**
+** If a non-NULL value is specified for the optional $dir parameter and
+** $path is a relative path, then $path is interpreted relative to $dir.
+** And the paths returned in the "name" column of the table are also
+** relative to directory $dir.
+*/
+SQLITE_EXTENSION_INIT1
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if !defined(_WIN32) && !defined(WIN32)
+# include <unistd.h>
+# include <dirent.h>
+# include <utime.h>
+# include <sys/time.h>
+#else
+# include "windows.h"
+# include <io.h>
+# include <direct.h>
+/* # include "test_windirent.h" */
+# define dirent DIRENT
+# ifndef chmod
+# define chmod _chmod
+# endif
+# ifndef stat
+# define stat _stat
+# endif
+# define mkdir(path,mode) _mkdir(path)
+# define lstat(path,buf) stat(path,buf)
+#endif
+#include <time.h>
+#include <errno.h>
+
+
+#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
+
+/*
+** Set the result stored by context ctx to a blob containing the
+** contents of file zName.
+*/
+static void readFileContents(sqlite3_context *ctx, const char *zName){
+ FILE *in;
+ long nIn;
+ void *pBuf;
+
+ in = fopen(zName, "rb");
+ if( in==0 ) return;
+ fseek(in, 0, SEEK_END);
+ nIn = ftell(in);
+ rewind(in);
+ pBuf = sqlite3_malloc( nIn );
+ if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
+ sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free);
+ }else{
+ sqlite3_free(pBuf);
+ }
+ fclose(in);
+}
+
+/*
+** Implementation of the "readfile(X)" SQL function. The entire content
+** of the file named X is read and returned as a BLOB. NULL is returned
+** if the file does not exist or is unreadable.
+*/
+static void readfileFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zName;
+ (void)(argc); /* Unused parameter */
+ zName = (const char*)sqlite3_value_text(argv[0]);
+ if( zName==0 ) return;
+ readFileContents(context, zName);
+}
+
+/*
+** Set the error message contained in context ctx to the results of
+** vprintf(zFmt, ...).
+*/
+static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
+ char *zMsg = 0;
+ va_list ap;
+ va_start(ap, zFmt);
+ zMsg = sqlite3_vmprintf(zFmt, ap);
+ sqlite3_result_error(ctx, zMsg, -1);
+ sqlite3_free(zMsg);
+ va_end(ap);
+}
+
+#if defined(_WIN32)
+/*
+** This function is designed to convert a Win32 FILETIME structure into the
+** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
+*/
+static sqlite3_uint64 fileTimeToUnixTime(
+ LPFILETIME pFileTime
+){
+ SYSTEMTIME epochSystemTime;
+ ULARGE_INTEGER epochIntervals;
+ FILETIME epochFileTime;
+ ULARGE_INTEGER fileIntervals;
+
+ memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
+ epochSystemTime.wYear = 1970;
+ epochSystemTime.wMonth = 1;
+ epochSystemTime.wDay = 1;
+ SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
+ epochIntervals.LowPart = epochFileTime.dwLowDateTime;
+ epochIntervals.HighPart = epochFileTime.dwHighDateTime;
+
+ fileIntervals.LowPart = pFileTime->dwLowDateTime;
+ fileIntervals.HighPart = pFileTime->dwHighDateTime;
+
+ return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
+}
+
+/*
+** This function attempts to normalize the time values found in the stat()
+** buffer to UTC. This is necessary on Win32, where the runtime library
+** appears to return these values as local times.
+*/
+static void statTimesToUtc(
+ const char *zPath,
+ struct stat *pStatBuf
+){
+ HANDLE hFindFile;
+ WIN32_FIND_DATAW fd;
+ LPWSTR zUnicodeName;
+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
+ if( zUnicodeName ){
+ memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
+ hFindFile = FindFirstFileW(zUnicodeName, &fd);
+ if( hFindFile!=NULL ){
+ pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
+ pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
+ pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
+ FindClose(hFindFile);
+ }
+ sqlite3_free(zUnicodeName);
+ }
+}
+#endif
+
+/*
+** This function is used in place of stat(). On Windows, special handling
+** is required in order for the included time to be returned as UTC. On all
+** other systems, this function simply calls stat().
+*/
+static int fileStat(
+ const char *zPath,
+ struct stat *pStatBuf
+){
+#if defined(_WIN32)
+ int rc = stat(zPath, pStatBuf);
+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
+ return rc;
+#else
+ return stat(zPath, pStatBuf);
+#endif
+}
+
+/*
+** This function is used in place of lstat(). On Windows, special handling
+** is required in order for the included time to be returned as UTC. On all
+** other systems, this function simply calls lstat().
+*/
+static int fileLinkStat(
+ const char *zPath,
+ struct stat *pStatBuf
+){
+#if defined(_WIN32)
+ int rc = lstat(zPath, pStatBuf);
+ if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
+ return rc;
+#else
+ return lstat(zPath, pStatBuf);
+#endif
+}
+
+/*
+** Argument zFile is the name of a file that will be created and/or written
+** by SQL function writefile(). This function ensures that the directory
+** zFile will be written to exists, creating it if required. The permissions
+** for any path components created by this function are set to (mode&0777).
+**
+** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
+** SQLITE_OK is returned if the directory is successfully created, or
+** SQLITE_ERROR otherwise.
+*/
+static int makeDirectory(
+ const char *zFile,
+ mode_t mode
+){
+ char *zCopy = sqlite3_mprintf("%s", zFile);
+ int rc = SQLITE_OK;
+
+ if( zCopy==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int nCopy = (int)strlen(zCopy);
+ int i = 1;
+
+ while( rc==SQLITE_OK ){
+ struct stat sStat;
+ int rc2;
+
+ for(; zCopy[i]!='/' && i<nCopy; i++);
+ if( i==nCopy ) break;
+ zCopy[i] = '\0';
+
+ rc2 = fileStat(zCopy, &sStat);
+ if( rc2!=0 ){
+ if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
+ }else{
+ if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
+ }
+ zCopy[i] = '/';
+ i++;
+ }
+
+ sqlite3_free(zCopy);
+ }
+
+ return rc;
+}
+
+/*
+** This function does the work for the writefile() UDF. Refer to
+** header comments at the top of this file for details.
+*/
+static int writeFile(
+ sqlite3_context *pCtx, /* Context to return bytes written in */
+ const char *zFile, /* File to write */
+ sqlite3_value *pData, /* Data to write */
+ mode_t mode, /* MODE parameter passed to writefile() */
+ sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */
+){
+#if !defined(_WIN32) && !defined(WIN32)
+ if( S_ISLNK(mode) ){
+ const char *zTo = (const char*)sqlite3_value_text(pData);
+ if( symlink(zTo, zFile)<0 ) return 1;
+ }else
+#endif
+ {
+ if( S_ISDIR(mode) ){
+ if( mkdir(zFile, mode) ){
+ /* The mkdir() call to create the directory failed. This might not
+ ** be an error though - if there is already a directory at the same
+ ** path and either the permissions already match or can be changed
+ ** to do so using chmod(), it is not an error. */
+ struct stat sStat;
+ if( errno!=EEXIST
+ || 0!=fileStat(zFile, &sStat)
+ || !S_ISDIR(sStat.st_mode)
+ || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
+ ){
+ return 1;
+ }
+ }
+ }else{
+ sqlite3_int64 nWrite = 0;
+ const char *z;
+ int rc = 0;
+ FILE *out = fopen(zFile, "wb");
+ if( out==0 ) return 1;
+ z = (const char*)sqlite3_value_blob(pData);
+ if( z ){
+ sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
+ nWrite = sqlite3_value_bytes(pData);
+ if( nWrite!=n ){
+ rc = 1;
+ }
+ }
+ fclose(out);
+ if( rc==0 && mode && chmod(zFile, mode & 0777) ){
+ rc = 1;
+ }
+ if( rc ) return 2;
+ sqlite3_result_int64(pCtx, nWrite);
+ }
+ }
+
+ if( mtime>=0 ){
+#if defined(_WIN32)
+ /* Windows */
+ FILETIME lastAccess;
+ FILETIME lastWrite;
+ SYSTEMTIME currentTime;
+ LONGLONG intervals;
+ HANDLE hFile;
+ LPWSTR zUnicodeName;
+ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
+
+ GetSystemTime(&currentTime);
+ SystemTimeToFileTime(&currentTime, &lastAccess);
+ intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
+ lastWrite.dwLowDateTime = (DWORD)intervals;
+ lastWrite.dwHighDateTime = intervals >> 32;
+ zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
+ if( zUnicodeName==0 ){
+ return 1;
+ }
+ hFile = CreateFileW(
+ zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL
+ );
+ sqlite3_free(zUnicodeName);
+ if( hFile!=INVALID_HANDLE_VALUE ){
+ BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
+ CloseHandle(hFile);
+ return !bResult;
+ }else{
+ return 1;
+ }
+#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
+ /* Recent unix */
+ struct timespec times[2];
+ times[0].tv_nsec = times[1].tv_nsec = 0;
+ times[0].tv_sec = time(0);
+ times[1].tv_sec = mtime;
+ if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
+ return 1;
+ }
+#else
+ /* Legacy unix */
+ struct timeval times[2];
+ times[0].tv_usec = times[1].tv_usec = 0;
+ times[0].tv_sec = time(0);
+ times[1].tv_sec = mtime;
+ if( utimes(zFile, times) ){
+ return 1;
+ }
+#endif
+ }
+
+ return 0;
+}
+
+/*
+** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
+** Refer to header comments at the top of this file for details.
+*/
+static void writefileFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zFile;
+ mode_t mode = 0;
+ int res;
+ sqlite3_int64 mtime = -1;
+
+ if( argc<2 || argc>4 ){
+ sqlite3_result_error(context,
+ "wrong number of arguments to function writefile()", -1
+ );
+ return;
+ }
+
+ zFile = (const char*)sqlite3_value_text(argv[0]);
+ if( zFile==0 ) return;
+ if( argc>=3 ){
+ mode = (mode_t)sqlite3_value_int(argv[2]);
+ }
+ if( argc==4 ){
+ mtime = sqlite3_value_int64(argv[3]);
+ }
+
+ res = writeFile(context, zFile, argv[1], mode, mtime);
+ if( res==1 && errno==ENOENT ){
+ if( makeDirectory(zFile, mode)==SQLITE_OK ){
+ res = writeFile(context, zFile, argv[1], mode, mtime);
+ }
+ }
+
+ if( argc>2 && res!=0 ){
+ if( S_ISLNK(mode) ){
+ ctxErrorMsg(context, "failed to create symlink: %s", zFile);
+ }else if( S_ISDIR(mode) ){
+ ctxErrorMsg(context, "failed to create directory: %s", zFile);
+ }else{
+ ctxErrorMsg(context, "failed to write file: %s", zFile);
+ }
+ }
+}
+
+/*
+** SQL function: lsmode(MODE)
+**
+** Given a numberic st_mode from stat(), convert it into a human-readable
+** text string in the style of "ls -l".
+*/
+static void lsModeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ int iMode = sqlite3_value_int(argv[0]);
+ char z[16];
+ (void)argc;
+ if( S_ISLNK(iMode) ){
+ z[0] = 'l';
+ }else if( S_ISREG(iMode) ){
+ z[0] = '-';
+ }else if( S_ISDIR(iMode) ){
+ z[0] = 'd';
+ }else{
+ z[0] = '?';
+ }
+ for(i=0; i<3; i++){
+ int m = (iMode >> ((2-i)*3));
+ char *a = &z[1 + i*3];
+ a[0] = (m & 0x4) ? 'r' : '-';
+ a[1] = (m & 0x2) ? 'w' : '-';
+ a[2] = (m & 0x1) ? 'x' : '-';
+ }
+ z[10] = '\0';
+ sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+
+/*
+** Cursor type for recursively iterating through a directory structure.
+*/
+typedef struct fsdir_cursor fsdir_cursor;
+typedef struct FsdirLevel FsdirLevel;
+
+struct FsdirLevel {
+ DIR *pDir; /* From opendir() */
+ char *zDir; /* Name of directory (nul-terminated) */
+};
+
+struct fsdir_cursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+
+ int nLvl; /* Number of entries in aLvl[] array */
+ int iLvl; /* Index of current entry */
+ FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
+
+ const char *zBase;
+ int nBase;
+
+ struct stat sStat; /* Current lstat() results */
+ char *zPath; /* Path to current entry */
+ sqlite3_int64 iRowid; /* Current rowid */
+};
+
+typedef struct fsdir_tab fsdir_tab;
+struct fsdir_tab {
+ sqlite3_vtab base; /* Base class - must be first */
+};
+
+/*
+** Construct a new fsdir virtual table object.
+*/
+static int fsdirConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ fsdir_tab *pNew = 0;
+ int rc;
+ (void)pAux;
+ (void)argc;
+ (void)argv;
+ (void)pzErr;
+ rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
+ if( rc==SQLITE_OK ){
+ pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ }
+ *ppVtab = (sqlite3_vtab*)pNew;
+ return rc;
+}
+
+/*
+** This method is the destructor for fsdir vtab objects.
+*/
+static int fsdirDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** Constructor for a new fsdir_cursor object.
+*/
+static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ fsdir_cursor *pCur;
+ (void)p;
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ pCur->iLvl = -1;
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/*
+** Reset a cursor back to the state it was in when first returned
+** by fsdirOpen().
+*/
+static void fsdirResetCursor(fsdir_cursor *pCur){
+ int i;
+ for(i=0; i<=pCur->iLvl; i++){
+ FsdirLevel *pLvl = &pCur->aLvl[i];
+ if( pLvl->pDir ) closedir(pLvl->pDir);
+ sqlite3_free(pLvl->zDir);
+ }
+ sqlite3_free(pCur->zPath);
+ sqlite3_free(pCur->aLvl);
+ pCur->aLvl = 0;
+ pCur->zPath = 0;
+ pCur->zBase = 0;
+ pCur->nBase = 0;
+ pCur->nLvl = 0;
+ pCur->iLvl = -1;
+ pCur->iRowid = 1;
+}
+
+/*
+** Destructor for an fsdir_cursor.
+*/
+static int fsdirClose(sqlite3_vtab_cursor *cur){
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
+ fsdirResetCursor(pCur);
+ sqlite3_free(pCur);
+ return SQLITE_OK;
+}
+
+/*
+** Set the error message for the virtual table associated with cursor
+** pCur to the results of vprintf(zFmt, ...).
+*/
+static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+}
+
+
+/*
+** Advance an fsdir_cursor to its next row of output.
+*/
+static int fsdirNext(sqlite3_vtab_cursor *cur){
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ mode_t m = pCur->sStat.st_mode;
+
+ pCur->iRowid++;
+ if( S_ISDIR(m) ){
+ /* Descend into this directory */
+ int iNew = pCur->iLvl + 1;
+ FsdirLevel *pLvl;
+ if( iNew>=pCur->nLvl ){
+ int nNew = iNew+1;
+ int nByte = nNew*sizeof(FsdirLevel);
+ FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte);
+ if( aNew==0 ) return SQLITE_NOMEM;
+ memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
+ pCur->aLvl = aNew;
+ pCur->nLvl = nNew;
+ }
+ pCur->iLvl = iNew;
+ pLvl = &pCur->aLvl[iNew];
+
+ pLvl->zDir = pCur->zPath;
+ pCur->zPath = 0;
+ pLvl->pDir = opendir(pLvl->zDir);
+ if( pLvl->pDir==0 ){
+ fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
+ return SQLITE_ERROR;
+ }
+ }
+
+ while( pCur->iLvl>=0 ){
+ FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
+ struct dirent *pEntry = readdir(pLvl->pDir);
+ if( pEntry ){
+ if( pEntry->d_name[0]=='.' ){
+ if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
+ if( pEntry->d_name[1]=='\0' ) continue;
+ }
+ sqlite3_free(pCur->zPath);
+ pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
+ if( pCur->zPath==0 ) return SQLITE_NOMEM;
+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+ }
+ closedir(pLvl->pDir);
+ sqlite3_free(pLvl->zDir);
+ pLvl->pDir = 0;
+ pLvl->zDir = 0;
+ pCur->iLvl--;
+ }
+
+ /* EOF */
+ sqlite3_free(pCur->zPath);
+ pCur->zPath = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Return values of columns for the row at which the series_cursor
+** is currently pointing.
+*/
+static int fsdirColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ switch( i ){
+ case 0: { /* name */
+ sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
+ break;
+ }
+
+ case 1: /* mode */
+ sqlite3_result_int64(ctx, pCur->sStat.st_mode);
+ break;
+
+ case 2: /* mtime */
+ sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
+ break;
+
+ case 3: { /* data */
+ mode_t m = pCur->sStat.st_mode;
+ if( S_ISDIR(m) ){
+ sqlite3_result_null(ctx);
+#if !defined(_WIN32) && !defined(WIN32)
+ }else if( S_ISLNK(m) ){
+ char aStatic[64];
+ char *aBuf = aStatic;
+ int nBuf = 64;
+ int n;
+
+ while( 1 ){
+ n = readlink(pCur->zPath, aBuf, nBuf);
+ if( n<nBuf ) break;
+ if( aBuf!=aStatic ) sqlite3_free(aBuf);
+ nBuf = nBuf*2;
+ aBuf = sqlite3_malloc(nBuf);
+ if( aBuf==0 ){
+ sqlite3_result_error_nomem(ctx);
+ return SQLITE_NOMEM;
+ }
+ }
+
+ sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
+ if( aBuf!=aStatic ) sqlite3_free(aBuf);
+#endif
+ }else{
+ readFileContents(ctx, pCur->zPath);
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return the rowid for the current row. In this implementation, the
+** first row returned is assigned rowid value 1, and each subsequent
+** row a value 1 more than that of the previous.
+*/
+static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ *pRowid = pCur->iRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the cursor has been moved off of the last
+** row of output.
+*/
+static int fsdirEof(sqlite3_vtab_cursor *cur){
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ return (pCur->zPath==0);
+}
+
+/*
+** xFilter callback.
+*/
+static int fsdirFilter(
+ sqlite3_vtab_cursor *cur,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ const char *zDir = 0;
+ fsdir_cursor *pCur = (fsdir_cursor*)cur;
+ (void)idxStr;
+ fsdirResetCursor(pCur);
+
+ if( idxNum==0 ){
+ fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
+ return SQLITE_ERROR;
+ }
+
+ assert( argc==idxNum && (argc==1 || argc==2) );
+ zDir = (const char*)sqlite3_value_text(argv[0]);
+ if( zDir==0 ){
+ fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
+ return SQLITE_ERROR;
+ }
+ if( argc==2 ){
+ pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
+ }
+ if( pCur->zBase ){
+ pCur->nBase = (int)strlen(pCur->zBase)+1;
+ pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
+ }else{
+ pCur->zPath = sqlite3_mprintf("%s", zDir);
+ }
+
+ if( pCur->zPath==0 ){
+ return SQLITE_NOMEM;
+ }
+ if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
+ fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
+ return SQLITE_ERROR;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** SQLite will invoke this method one or more times while planning a query
+** that uses the generate_series virtual table. This routine needs to create
+** a query plan for each invocation and compute an estimated cost for that
+** plan.
+**
+** In this implementation idxNum is used to represent the
+** query plan. idxStr is unused.
+**
+** The query plan is represented by bits in idxNum:
+**
+** (1) start = $value -- constraint exists
+** (2) stop = $value -- constraint exists
+** (4) step = $value -- constraint exists
+** (8) output in descending order
+*/
+static int fsdirBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i; /* Loop over constraints */
+ int idx4 = -1;
+ int idx5 = -1;
+ const struct sqlite3_index_constraint *pConstraint;
+
+ (void)tab;
+ pConstraint = pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pConstraint->iColumn==4 ) idx4 = i;
+ if( pConstraint->iColumn==5 ) idx5 = i;
+ }
+
+ if( idx4<0 ){
+ pIdxInfo->idxNum = 0;
+ pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
+ }else{
+ pIdxInfo->aConstraintUsage[idx4].omit = 1;
+ pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
+ if( idx5>=0 ){
+ pIdxInfo->aConstraintUsage[idx5].omit = 1;
+ pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
+ pIdxInfo->idxNum = 2;
+ pIdxInfo->estimatedCost = 10.0;
+ }else{
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->estimatedCost = 100.0;
+ }
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Register the "fsdir" virtual table.
+*/
+static int fsdirRegister(sqlite3 *db){
+ static const sqlite3_module fsdirModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ fsdirConnect, /* xConnect */
+ fsdirBestIndex, /* xBestIndex */
+ fsdirDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ fsdirOpen, /* xOpen - open a cursor */
+ fsdirClose, /* xClose - close a cursor */
+ fsdirFilter, /* xFilter - configure scan constraints */
+ fsdirNext, /* xNext - advance a cursor */
+ fsdirEof, /* xEof - check for end of scan */
+ fsdirColumn, /* xColumn - read data */
+ fsdirRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+ };
+
+ int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
+ return rc;
+}
+#else /* SQLITE_OMIT_VIRTUALTABLE */
+# define fsdirRegister(x) SQLITE_OK
+#endif
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_fileio_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
+ readfileFunc, 0, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
+ writefileFunc, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
+ lsModeFunc, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = fsdirRegister(db);
+ }
+ return rc;
+}
+
+/************************* End ../ext/misc/fileio.c ********************/
+/************************* Begin ../ext/misc/completion.c ******************/
+/*
+** 2017-07-10
+**
+** 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 an eponymous virtual table that returns suggested
+** completions for a partial SQL input.
+**
+** Suggested usage:
+**
+** SELECT DISTINCT candidate COLLATE nocase
+** FROM completion($prefix,$wholeline)
+** ORDER BY 1;
+**
+** The two query parameters are optional. $prefix is the text of the
+** current word being typed and that is to be completed. $wholeline is
+** the complete input line, used for context.
+**
+** The raw completion() table might return the same candidate multiple
+** times, for example if the same column name is used to two or more
+** tables. And the candidates are returned in an arbitrary order. Hence,
+** the DISTINCT and ORDER BY are recommended.
+**
+** This virtual table operates at the speed of human typing, and so there
+** is no attempt to make it fast. Even a slow implementation will be much
+** faster than any human can type.
+**
+*/
+SQLITE_EXTENSION_INIT1
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+
+/* completion_vtab is a subclass of sqlite3_vtab which will
+** serve as the underlying representation of a completion virtual table
+*/
+typedef struct completion_vtab completion_vtab;
+struct completion_vtab {
+ sqlite3_vtab base; /* Base class - must be first */
+ sqlite3 *db; /* Database connection for this completion vtab */
+};
+
+/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
+** serve as the underlying representation of a cursor that scans
+** over rows of the result
+*/
+typedef struct completion_cursor completion_cursor;
+struct completion_cursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ sqlite3 *db; /* Database connection for this cursor */
+ int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */
+ char *zPrefix; /* The prefix for the word we want to complete */
+ char *zLine; /* The whole that we want to complete */
+ const char *zCurrentRow; /* Current output row */
+ int szRow; /* Length of the zCurrentRow string */
+ sqlite3_stmt *pStmt; /* Current statement */
+ sqlite3_int64 iRowid; /* The rowid */
+ int ePhase; /* Current phase */
+ int j; /* inter-phase counter */
+};
+
+/* Values for ePhase:
+*/
+#define COMPLETION_FIRST_PHASE 1
+#define COMPLETION_KEYWORDS 1
+#define COMPLETION_PRAGMAS 2
+#define COMPLETION_FUNCTIONS 3
+#define COMPLETION_COLLATIONS 4
+#define COMPLETION_INDEXES 5
+#define COMPLETION_TRIGGERS 6
+#define COMPLETION_DATABASES 7
+#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
+#define COMPLETION_COLUMNS 9
+#define COMPLETION_MODULES 10
+#define COMPLETION_EOF 11
+
+/*
+** The completionConnect() method is invoked to create a new
+** completion_vtab that describes the completion virtual table.
+**
+** Think of this routine as the constructor for completion_vtab objects.
+**
+** All this routine needs to do is:
+**
+** (1) Allocate the completion_vtab object and initialize all fields.
+**
+** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
+** result set of queries against completion will look like.
+*/
+static int completionConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ completion_vtab *pNew;
+ int rc;
+
+ (void)(pAux); /* Unused parameter */
+ (void)(argc); /* Unused parameter */
+ (void)(argv); /* Unused parameter */
+ (void)(pzErr); /* Unused parameter */
+
+/* Column numbers */
+#define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */
+#define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */
+#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
+#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
+
+ rc = sqlite3_declare_vtab(db,
+ "CREATE TABLE x("
+ " candidate TEXT,"
+ " prefix TEXT HIDDEN,"
+ " wholeline TEXT HIDDEN,"
+ " phase INT HIDDEN" /* Used for debugging only */
+ ")");
+ if( rc==SQLITE_OK ){
+ pNew = sqlite3_malloc( sizeof(*pNew) );
+ *ppVtab = (sqlite3_vtab*)pNew;
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ pNew->db = db;
+ }
+ return rc;
+}
+
+/*
+** This method is the destructor for completion_cursor objects.
+*/
+static int completionDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** Constructor for a new completion_cursor object.
+*/
+static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ completion_cursor *pCur;
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ pCur->db = ((completion_vtab*)p)->db;
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/*
+** Reset the completion_cursor.
+*/
+static void completionCursorReset(completion_cursor *pCur){
+ sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0;
+ sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0;
+ sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
+ pCur->j = 0;
+}
+
+/*
+** Destructor for a completion_cursor.
+*/
+static int completionClose(sqlite3_vtab_cursor *cur){
+ completionCursorReset((completion_cursor*)cur);
+ sqlite3_free(cur);
+ return SQLITE_OK;
+}
+
+/*
+** Advance a completion_cursor to its next row of output.
+**
+** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
+** record the current state of the scan. This routine sets ->zCurrentRow
+** to the current row of output and then returns. If no more rows remain,
+** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
+** table that has reached the end of its scan.
+**
+** The current implementation just lists potential identifiers and
+** keywords and filters them by zPrefix. Future enhancements should
+** take zLine into account to try to restrict the set of identifiers and
+** keywords based on what would be legal at the current point of input.
+*/
+static int completionNext(sqlite3_vtab_cursor *cur){
+ completion_cursor *pCur = (completion_cursor*)cur;
+ int eNextPhase = 0; /* Next phase to try if current phase reaches end */
+ int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */
+ pCur->iRowid++;
+ while( pCur->ePhase!=COMPLETION_EOF ){
+ switch( pCur->ePhase ){
+ case COMPLETION_KEYWORDS: {
+ if( pCur->j >= sqlite3_keyword_count() ){
+ pCur->zCurrentRow = 0;
+ pCur->ePhase = COMPLETION_DATABASES;
+ }else{
+ sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
+ }
+ iCol = -1;
+ break;
+ }
+ case COMPLETION_DATABASES: {
+ if( pCur->pStmt==0 ){
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
+ &pCur->pStmt, 0);
+ }
+ iCol = 1;
+ eNextPhase = COMPLETION_TABLES;
+ break;
+ }
+ case COMPLETION_TABLES: {
+ if( pCur->pStmt==0 ){
+ sqlite3_stmt *pS2;
+ char *zSql = 0;
+ const char *zSep = "";
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+ while( sqlite3_step(pS2)==SQLITE_ROW ){
+ const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+ zSql = sqlite3_mprintf(
+ "%z%s"
+ "SELECT name FROM \"%w\".sqlite_master",
+ zSql, zSep, zDb
+ );
+ if( zSql==0 ) return SQLITE_NOMEM;
+ zSep = " UNION ";
+ }
+ sqlite3_finalize(pS2);
+ sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+ iCol = 0;
+ eNextPhase = COMPLETION_COLUMNS;
+ break;
+ }
+ case COMPLETION_COLUMNS: {
+ if( pCur->pStmt==0 ){
+ sqlite3_stmt *pS2;
+ char *zSql = 0;
+ const char *zSep = "";
+ sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+ while( sqlite3_step(pS2)==SQLITE_ROW ){
+ const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+ zSql = sqlite3_mprintf(
+ "%z%s"
+ "SELECT pti.name FROM \"%w\".sqlite_master AS sm"
+ " JOIN pragma_table_info(sm.name,%Q) AS pti"
+ " WHERE sm.type='table'",
+ zSql, zSep, zDb, zDb
+ );
+ if( zSql==0 ) return SQLITE_NOMEM;
+ zSep = " UNION ";
+ }
+ sqlite3_finalize(pS2);
+ sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+ iCol = 0;
+ eNextPhase = COMPLETION_EOF;
+ break;
+ }
+ }
+ if( iCol<0 ){
+ /* This case is when the phase presets zCurrentRow */
+ if( pCur->zCurrentRow==0 ) continue;
+ }else{
+ if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
+ /* Extract the next row of content */
+ pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
+ pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
+ }else{
+ /* When all rows are finished, advance to the next phase */
+ sqlite3_finalize(pCur->pStmt);
+ pCur->pStmt = 0;
+ pCur->ePhase = eNextPhase;
+ continue;
+ }
+ }
+ if( pCur->nPrefix==0 ) break;
+ if( pCur->nPrefix<=pCur->szRow
+ && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
+ ){
+ break;
+ }
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Return values of columns for the row at which the completion_cursor
+** is currently pointing.
+*/
+static int completionColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ completion_cursor *pCur = (completion_cursor*)cur;
+ switch( i ){
+ case COMPLETION_COLUMN_CANDIDATE: {
+ sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
+ break;
+ }
+ case COMPLETION_COLUMN_PREFIX: {
+ sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
+ break;
+ }
+ case COMPLETION_COLUMN_WHOLELINE: {
+ sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
+ break;
+ }
+ case COMPLETION_COLUMN_PHASE: {
+ sqlite3_result_int(ctx, pCur->ePhase);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return the rowid for the current row. In this implementation, the
+** rowid is the same as the output value.
+*/
+static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ completion_cursor *pCur = (completion_cursor*)cur;
+ *pRowid = pCur->iRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the cursor has been moved off of the last
+** row of output.
+*/
+static int completionEof(sqlite3_vtab_cursor *cur){
+ completion_cursor *pCur = (completion_cursor*)cur;
+ return pCur->ePhase >= COMPLETION_EOF;
+}
+
+/*
+** This method is called to "rewind" the completion_cursor object back
+** to the first row of output. This method is always called at least
+** once prior to any call to completionColumn() or completionRowid() or
+** completionEof().
+*/
+static int completionFilter(
+ sqlite3_vtab_cursor *pVtabCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ completion_cursor *pCur = (completion_cursor *)pVtabCursor;
+ int iArg = 0;
+ (void)(idxStr); /* Unused parameter */
+ (void)(argc); /* Unused parameter */
+ completionCursorReset(pCur);
+ if( idxNum & 1 ){
+ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
+ if( pCur->nPrefix>0 ){
+ pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+ if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+ }
+ iArg = 1;
+ }
+ if( idxNum & 2 ){
+ pCur->nLine = sqlite3_value_bytes(argv[iArg]);
+ if( pCur->nLine>0 ){
+ pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+ if( pCur->zLine==0 ) return SQLITE_NOMEM;
+ }
+ }
+ if( pCur->zLine!=0 && pCur->zPrefix==0 ){
+ int i = pCur->nLine;
+ while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
+ i--;
+ }
+ pCur->nPrefix = pCur->nLine - i;
+ if( pCur->nPrefix>0 ){
+ pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
+ if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+ }
+ }
+ pCur->iRowid = 0;
+ pCur->ePhase = COMPLETION_FIRST_PHASE;
+ return completionNext(pVtabCursor);
+}
+
+/*
+** SQLite will invoke this method one or more times while planning a query
+** that uses the completion virtual table. This routine needs to create
+** a query plan for each invocation and compute an estimated cost for that
+** plan.
+**
+** There are two hidden parameters that act as arguments to the table-valued
+** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix"
+** is available and bit 1 is set if "wholeline" is available.
+*/
+static int completionBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i; /* Loop over constraints */
+ int idxNum = 0; /* The query plan bitmask */
+ int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */
+ int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
+ int nArg = 0; /* Number of arguments that completeFilter() expects */
+ const struct sqlite3_index_constraint *pConstraint;
+
+ (void)(tab); /* Unused parameter */
+ pConstraint = pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ switch( pConstraint->iColumn ){
+ case COMPLETION_COLUMN_PREFIX:
+ prefixIdx = i;
+ idxNum |= 1;
+ break;
+ case COMPLETION_COLUMN_WHOLELINE:
+ wholelineIdx = i;
+ idxNum |= 2;
+ break;
+ }
+ }
+ if( prefixIdx>=0 ){
+ pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
+ pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
+ }
+ if( wholelineIdx>=0 ){
+ pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
+ pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
+ }
+ pIdxInfo->idxNum = idxNum;
+ pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
+ pIdxInfo->estimatedRows = 500 - 100*nArg;
+ return SQLITE_OK;
+}
+
+/*
+** This following structure defines all the methods for the
+** completion virtual table.
+*/
+static const sqlite3_module completionModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ completionConnect, /* xConnect */
+ completionBestIndex, /* xBestIndex */
+ completionDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ completionOpen, /* xOpen - open a cursor */
+ completionClose, /* xClose - close a cursor */
+ completionFilter, /* xFilter - configure scan constraints */
+ completionNext, /* xNext - advance a cursor */
+ completionEof, /* xEof - check for end of scan */
+ completionColumn, /* xColumn - read data */
+ completionRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+int sqlite3CompletionVtabInit(sqlite3 *db){
+ int rc = SQLITE_OK;
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ rc = sqlite3_create_module(db, "completion", &completionModule, 0);
+#endif
+ return rc;
+}
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_completion_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)(pzErrMsg); /* Unused parameter */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ rc = sqlite3CompletionVtabInit(db);
+#endif
+ return rc;
+}
+
+/************************* End ../ext/misc/completion.c ********************/
+/************************* Begin ../ext/misc/appendvfs.c ******************/
+/*
+** 2017-10-20
+**
+** 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 VFS shim that allows an SQLite database to be
+** appended onto the end of some other file, such as an executable.
+**
+** A special record must appear at the end of the file that identifies the
+** file as an appended database and provides an offset to page 1. For
+** best performance page 1 should be located at a disk page boundary, though
+** that is not required.
+**
+** When opening a database using this VFS, the connection might treat
+** the file as an ordinary SQLite database, or it might treat is as a
+** database appended onto some other file. Here are the rules:
+**
+** (1) When opening a new empty file, that file is treated as an ordinary
+** database.
+**
+** (2) When opening a file that begins with the standard SQLite prefix
+** string "SQLite format 3", that file is treated as an ordinary
+** database.
+**
+** (3) When opening a file that ends with the appendvfs trailer string
+** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
+** database.
+**
+** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
+** set, then a new database is appended to the already existing file.
+**
+** (5) Otherwise, SQLITE_CANTOPEN is returned.
+**
+** To avoid unnecessary complications with the PENDING_BYTE, the size of
+** the file containing the database is limited to 1GB. This VFS will refuse
+** to read or write past the 1GB mark. This restriction might be lifted in
+** future versions. For now, if you need a large database, then keep the
+** database in a separate file.
+**
+** If the file being opened is not an appended database, then this shim is
+** a pass-through into the default underlying VFS.
+**/
+SQLITE_EXTENSION_INIT1
+#include <string.h>
+#include <assert.h>
+
+/* The append mark at the end of the database is:
+**
+** Start-Of-SQLite3-NNNNNNNN
+** 123456789 123456789 12345
+**
+** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
+** the offset to page 1.
+*/
+#define APND_MARK_PREFIX "Start-Of-SQLite3-"
+#define APND_MARK_PREFIX_SZ 17
+#define APND_MARK_SIZE 25
+
+/*
+** Maximum size of the combined prefix + database + append-mark. This
+** must be less than 0x40000000 to avoid locking issues on Windows.
+*/
+#define APND_MAX_SIZE (65536*15259)
+
+/*
+** Forward declaration of objects used by this utility
+*/
+typedef struct sqlite3_vfs ApndVfs;
+typedef struct ApndFile ApndFile;
+
+/* Access to a lower-level VFS that (might) implement dynamic loading,
+** access to randomness, etc.
+*/
+#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
+#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
+
+/* An open file */
+struct ApndFile {
+ sqlite3_file base; /* IO methods */
+ sqlite3_int64 iPgOne; /* File offset to page 1 */
+ sqlite3_int64 iMark; /* Start of the append-mark */
+};
+
+/*
+** Methods for ApndFile
+*/
+static int apndClose(sqlite3_file*);
+static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
+static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
+static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
+static int apndSync(sqlite3_file*, int flags);
+static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
+static int apndLock(sqlite3_file*, int);
+static int apndUnlock(sqlite3_file*, int);
+static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
+static int apndFileControl(sqlite3_file*, int op, void *pArg);
+static int apndSectorSize(sqlite3_file*);
+static int apndDeviceCharacteristics(sqlite3_file*);
+static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
+static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
+static void apndShmBarrier(sqlite3_file*);
+static int apndShmUnmap(sqlite3_file*, int deleteFlag);
+static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+
+/*
+** Methods for ApndVfs
+*/
+static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
+static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
+static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
+static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
+static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
+static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
+static void apndDlClose(sqlite3_vfs*, void*);
+static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
+static int apndSleep(sqlite3_vfs*, int microseconds);
+static int apndCurrentTime(sqlite3_vfs*, double*);
+static int apndGetLastError(sqlite3_vfs*, int, char *);
+static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
+static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
+static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
+static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
+
+static sqlite3_vfs apnd_vfs = {
+ 3, /* iVersion (set when registered) */
+ 0, /* szOsFile (set when registered) */
+ 1024, /* mxPathname */
+ 0, /* pNext */
+ "apndvfs", /* zName */
+ 0, /* pAppData (set when registered) */
+ apndOpen, /* xOpen */
+ apndDelete, /* xDelete */
+ apndAccess, /* xAccess */
+ apndFullPathname, /* xFullPathname */
+ apndDlOpen, /* xDlOpen */
+ apndDlError, /* xDlError */
+ apndDlSym, /* xDlSym */
+ apndDlClose, /* xDlClose */
+ apndRandomness, /* xRandomness */
+ apndSleep, /* xSleep */
+ apndCurrentTime, /* xCurrentTime */
+ apndGetLastError, /* xGetLastError */
+ apndCurrentTimeInt64, /* xCurrentTimeInt64 */
+ apndSetSystemCall, /* xSetSystemCall */
+ apndGetSystemCall, /* xGetSystemCall */
+ apndNextSystemCall /* xNextSystemCall */
+};
+
+static const sqlite3_io_methods apnd_io_methods = {
+ 3, /* iVersion */
+ apndClose, /* xClose */
+ apndRead, /* xRead */
+ apndWrite, /* xWrite */
+ apndTruncate, /* xTruncate */
+ apndSync, /* xSync */
+ apndFileSize, /* xFileSize */
+ apndLock, /* xLock */
+ apndUnlock, /* xUnlock */
+ apndCheckReservedLock, /* xCheckReservedLock */
+ apndFileControl, /* xFileControl */
+ apndSectorSize, /* xSectorSize */
+ apndDeviceCharacteristics, /* xDeviceCharacteristics */
+ apndShmMap, /* xShmMap */
+ apndShmLock, /* xShmLock */
+ apndShmBarrier, /* xShmBarrier */
+ apndShmUnmap, /* xShmUnmap */
+ apndFetch, /* xFetch */
+ apndUnfetch /* xUnfetch */
+};
+
+
+
+/*
+** Close an apnd-file.
+*/
+static int apndClose(sqlite3_file *pFile){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xClose(pFile);
+}
+
+/*
+** Read data from an apnd-file.
+*/
+static int apndRead(
+ sqlite3_file *pFile,
+ void *zBuf,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ ApndFile *p = (ApndFile *)pFile;
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
+}
+
+/*
+** Add the append-mark onto the end of the file.
+*/
+static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
+ int i;
+ unsigned char a[APND_MARK_SIZE];
+ memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
+ for(i=0; i<8; i++){
+ a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
+ }
+ return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
+}
+
+/*
+** Write data to an apnd-file.
+*/
+static int apndWrite(
+ sqlite3_file *pFile,
+ const void *zBuf,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ int rc;
+ ApndFile *p = (ApndFile *)pFile;
+ pFile = ORIGFILE(pFile);
+ if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
+ rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
+ if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){
+ sqlite3_int64 sz = 0;
+ rc = pFile->pMethods->xFileSize(pFile, &sz);
+ if( rc==SQLITE_OK ){
+ p->iMark = sz - APND_MARK_SIZE;
+ if( iOfst + iAmt + p->iPgOne > p->iMark ){
+ p->iMark = p->iPgOne + iOfst + iAmt;
+ rc = apndWriteMark(p, pFile);
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** Truncate an apnd-file.
+*/
+static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
+ int rc;
+ ApndFile *p = (ApndFile *)pFile;
+ pFile = ORIGFILE(pFile);
+ rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
+ if( rc==SQLITE_OK ){
+ p->iMark = p->iPgOne+size;
+ rc = apndWriteMark(p, pFile);
+ }
+ return rc;
+}
+
+/*
+** Sync an apnd-file.
+*/
+static int apndSync(sqlite3_file *pFile, int flags){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xSync(pFile, flags);
+}
+
+/*
+** Return the current file-size of an apnd-file.
+*/
+static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+ ApndFile *p = (ApndFile *)pFile;
+ int rc;
+ pFile = ORIGFILE(p);
+ rc = pFile->pMethods->xFileSize(pFile, pSize);
+ if( rc==SQLITE_OK && p->iPgOne ){
+ *pSize -= p->iPgOne + APND_MARK_SIZE;
+ }
+ return rc;
+}
+
+/*
+** Lock an apnd-file.
+*/
+static int apndLock(sqlite3_file *pFile, int eLock){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xLock(pFile, eLock);
+}
+
+/*
+** Unlock an apnd-file.
+*/
+static int apndUnlock(sqlite3_file *pFile, int eLock){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xUnlock(pFile, eLock);
+}
+
+/*
+** Check if another file-handle holds a RESERVED lock on an apnd-file.
+*/
+static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
+}
+
+/*
+** File control method. For custom operations on an apnd-file.
+*/
+static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
+ ApndFile *p = (ApndFile *)pFile;
+ int rc;
+ pFile = ORIGFILE(pFile);
+ rc = pFile->pMethods->xFileControl(pFile, op, pArg);
+ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
+ *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
+ }
+ return rc;
+}
+
+/*
+** Return the sector-size in bytes for an apnd-file.
+*/
+static int apndSectorSize(sqlite3_file *pFile){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xSectorSize(pFile);
+}
+
+/*
+** Return the device characteristic flags supported by an apnd-file.
+*/
+static int apndDeviceCharacteristics(sqlite3_file *pFile){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xDeviceCharacteristics(pFile);
+}
+
+/* Create a shared memory file mapping */
+static int apndShmMap(
+ sqlite3_file *pFile,
+ int iPg,
+ int pgsz,
+ int bExtend,
+ void volatile **pp
+){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
+}
+
+/* Perform locking on a shared-memory segment */
+static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xShmLock(pFile,offset,n,flags);
+}
+
+/* Memory barrier operation on shared memory */
+static void apndShmBarrier(sqlite3_file *pFile){
+ pFile = ORIGFILE(pFile);
+ pFile->pMethods->xShmBarrier(pFile);
+}
+
+/* Unmap a shared memory segment */
+static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
+}
+
+/* Fetch a page of a memory-mapped file */
+static int apndFetch(
+ sqlite3_file *pFile,
+ sqlite3_int64 iOfst,
+ int iAmt,
+ void **pp
+){
+ ApndFile *p = (ApndFile *)pFile;
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
+}
+
+/* Release a memory-mapped page */
+static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
+ ApndFile *p = (ApndFile *)pFile;
+ pFile = ORIGFILE(pFile);
+ return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
+}
+
+/*
+** Check to see if the file is an ordinary SQLite database file.
+*/
+static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
+ int rc;
+ char zHdr[16];
+ static const char aSqliteHdr[] = "SQLite format 3";
+ if( sz<512 ) return 0;
+ rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
+ if( rc ) return 0;
+ return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
+}
+
+/*
+** Try to read the append-mark off the end of a file. Return the
+** start of the appended database if the append-mark is present. If
+** there is no append-mark, return -1;
+*/
+static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
+ int rc, i;
+ sqlite3_int64 iMark;
+ unsigned char a[APND_MARK_SIZE];
+
+ if( sz<=APND_MARK_SIZE ) return -1;
+ rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
+ if( rc ) return -1;
+ if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
+ iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
+ for(i=1; i<8; i++){
+ iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
+ }
+ return iMark;
+}
+
+/*
+** Open an apnd file handle.
+*/
+static int apndOpen(
+ sqlite3_vfs *pVfs,
+ const char *zName,
+ sqlite3_file *pFile,
+ int flags,
+ int *pOutFlags
+){
+ ApndFile *p;
+ sqlite3_file *pSubFile;
+ sqlite3_vfs *pSubVfs;
+ int rc;
+ sqlite3_int64 sz;
+ pSubVfs = ORIGVFS(pVfs);
+ if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
+ return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
+ }
+ p = (ApndFile*)pFile;
+ memset(p, 0, sizeof(*p));
+ pSubFile = ORIGFILE(pFile);
+ p->base.pMethods = &apnd_io_methods;
+ rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
+ if( rc ) goto apnd_open_done;
+ rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
+ if( rc ){
+ pSubFile->pMethods->xClose(pSubFile);
+ goto apnd_open_done;
+ }
+ if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
+ memmove(pFile, pSubFile, pSubVfs->szOsFile);
+ return SQLITE_OK;
+ }
+ p->iMark = 0;
+ p->iPgOne = apndReadMark(sz, pFile);
+ if( p->iPgOne>0 ){
+ return SQLITE_OK;
+ }
+ if( (flags & SQLITE_OPEN_CREATE)==0 ){
+ pSubFile->pMethods->xClose(pSubFile);
+ rc = SQLITE_CANTOPEN;
+ }
+ p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
+apnd_open_done:
+ if( rc ) pFile->pMethods = 0;
+ return rc;
+}
+
+/*
+** All other VFS methods are pass-thrus.
+*/
+static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
+}
+static int apndAccess(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int flags,
+ int *pResOut
+){
+ return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
+}
+static int apndFullPathname(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int nOut,
+ char *zOut
+){
+ return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
+}
+static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
+}
+static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
+}
+static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
+ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
+}
+static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
+ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
+}
+static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
+}
+static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
+ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
+}
+static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
+}
+static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
+}
+static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
+ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
+}
+static int apndSetSystemCall(
+ sqlite3_vfs *pVfs,
+ const char *zName,
+ sqlite3_syscall_ptr pCall
+){
+ return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
+}
+static sqlite3_syscall_ptr apndGetSystemCall(
+ sqlite3_vfs *pVfs,
+ const char *zName
+){
+ return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
+}
+static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
+ return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
+}
+
+
+#ifdef _WIN32
+
+#endif
+/*
+** This routine is called when the extension is loaded.
+** Register the new VFS.
+*/
+int sqlite3_appendvfs_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ sqlite3_vfs *pOrig;
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg;
+ (void)db;
+ pOrig = sqlite3_vfs_find(0);
+ apnd_vfs.iVersion = pOrig->iVersion;
+ apnd_vfs.pAppData = pOrig;
+ apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
+ rc = sqlite3_vfs_register(&apnd_vfs, 0);
+#ifdef APPENDVFS_TEST
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
+ }
+#endif
+ if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
+ return rc;
+}
+
+/************************* End ../ext/misc/appendvfs.c ********************/
+#ifdef SQLITE_HAVE_ZLIB
+/************************* Begin ../ext/misc/zipfile.c ******************/
+/*
+** 2017-12-26
+**
+** 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 virtual table for reading and writing ZIP archive
+** files.
+**
+** Usage example:
+**
+** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
+**
+** Current limitations:
+**
+** * No support for encryption
+** * No support for ZIP archives spanning multiple files
+** * No support for zip64 extensions
+** * Only the "inflate/deflate" (zlib) compression method is supported
+*/
+SQLITE_EXTENSION_INIT1
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <zlib.h>
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+
+#ifndef SQLITE_AMALGAMATION
+
+/* typedef sqlite3_int64 i64; */
+/* typedef unsigned char u8; */
+typedef unsigned short u16;
+typedef unsigned long u32;
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
+# define ALWAYS(X) (1)
+# define NEVER(X) (0)
+#elif !defined(NDEBUG)
+# define ALWAYS(X) ((X)?1:(assert(0),0))
+# define NEVER(X) ((X)?(assert(0),1):0)
+#else
+# define ALWAYS(X) (X)
+# define NEVER(X) (X)
+#endif
+
+#endif /* SQLITE_AMALGAMATION */
+
+/*
+** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
+**
+** In some ways it would be better to obtain these values from system
+** header files. But, the dependency is undesirable and (a) these
+** have been stable for decades, (b) the values are part of POSIX and
+** are also made explicit in [man stat], and (c) are part of the
+** file format for zip archives.
+*/
+#ifndef S_IFDIR
+# define S_IFDIR 0040000
+#endif
+#ifndef S_IFREG
+# define S_IFREG 0100000
+#endif
+#ifndef S_IFLNK
+# define S_IFLNK 0120000
+#endif
+
+static const char ZIPFILE_SCHEMA[] =
+ "CREATE TABLE y("
+ "name PRIMARY KEY," /* 0: Name of file in zip archive */
+ "mode," /* 1: POSIX mode for file */
+ "mtime," /* 2: Last modification time (secs since 1970)*/
+ "sz," /* 3: Size of object */
+ "rawdata," /* 4: Raw data */
+ "data," /* 5: Uncompressed data */
+ "method," /* 6: Compression method (integer) */
+ "z HIDDEN" /* 7: Name of zip file */
+ ") WITHOUT ROWID;";
+
+#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
+#define ZIPFILE_BUFFER_SIZE (64*1024)
+
+
+/*
+** Magic numbers used to read and write zip files.
+**
+** ZIPFILE_NEWENTRY_MADEBY:
+** Use this value for the "version-made-by" field in new zip file
+** entries. The upper byte indicates "unix", and the lower byte
+** indicates that the zip file matches pkzip specification 3.0.
+** This is what info-zip seems to do.
+**
+** ZIPFILE_NEWENTRY_REQUIRED:
+** Value for "version-required-to-extract" field of new entries.
+** Version 2.0 is required to support folders and deflate compression.
+**
+** ZIPFILE_NEWENTRY_FLAGS:
+** Value for "general-purpose-bit-flags" field of new entries. Bit
+** 11 means "utf-8 filename and comment".
+**
+** ZIPFILE_SIGNATURE_CDS:
+** First 4 bytes of a valid CDS record.
+**
+** ZIPFILE_SIGNATURE_LFH:
+** First 4 bytes of a valid LFH record.
+**
+** ZIPFILE_SIGNATURE_EOCD
+** First 4 bytes of a valid EOCD record.
+*/
+#define ZIPFILE_EXTRA_TIMESTAMP 0x5455
+#define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30)
+#define ZIPFILE_NEWENTRY_REQUIRED 20
+#define ZIPFILE_NEWENTRY_FLAGS 0x800
+#define ZIPFILE_SIGNATURE_CDS 0x02014b50
+#define ZIPFILE_SIGNATURE_LFH 0x04034b50
+#define ZIPFILE_SIGNATURE_EOCD 0x06054b50
+
+/*
+** The sizes of the fixed-size part of each of the three main data
+** structures in a zip archive.
+*/
+#define ZIPFILE_LFH_FIXED_SZ 30
+#define ZIPFILE_EOCD_FIXED_SZ 22
+#define ZIPFILE_CDS_FIXED_SZ 46
+
+/*
+*** 4.3.16 End of central directory record:
+***
+*** end of central dir signature 4 bytes (0x06054b50)
+*** number of this disk 2 bytes
+*** number of the disk with the
+*** start of the central directory 2 bytes
+*** total number of entries in the
+*** central directory on this disk 2 bytes
+*** total number of entries in
+*** the central directory 2 bytes
+*** size of the central directory 4 bytes
+*** offset of start of central
+*** directory with respect to
+*** the starting disk number 4 bytes
+*** .ZIP file comment length 2 bytes
+*** .ZIP file comment (variable size)
+*/
+typedef struct ZipfileEOCD ZipfileEOCD;
+struct ZipfileEOCD {
+ u16 iDisk;
+ u16 iFirstDisk;
+ u16 nEntry;
+ u16 nEntryTotal;
+ u32 nSize;
+ u32 iOffset;
+};
+
+/*
+*** 4.3.12 Central directory structure:
+***
+*** ...
+***
+*** central file header signature 4 bytes (0x02014b50)
+*** version made by 2 bytes
+*** version needed to extract 2 bytes
+*** general purpose bit flag 2 bytes
+*** compression method 2 bytes
+*** last mod file time 2 bytes
+*** last mod file date 2 bytes
+*** crc-32 4 bytes
+*** compressed size 4 bytes
+*** uncompressed size 4 bytes
+*** file name length 2 bytes
+*** extra field length 2 bytes
+*** file comment length 2 bytes
+*** disk number start 2 bytes
+*** internal file attributes 2 bytes
+*** external file attributes 4 bytes
+*** relative offset of local header 4 bytes
+*/
+typedef struct ZipfileCDS ZipfileCDS;
+struct ZipfileCDS {
+ u16 iVersionMadeBy;
+ u16 iVersionExtract;
+ u16 flags;
+ u16 iCompression;
+ u16 mTime;
+ u16 mDate;
+ u32 crc32;
+ u32 szCompressed;
+ u32 szUncompressed;
+ u16 nFile;
+ u16 nExtra;
+ u16 nComment;
+ u16 iDiskStart;
+ u16 iInternalAttr;
+ u32 iExternalAttr;
+ u32 iOffset;
+ char *zFile; /* Filename (sqlite3_malloc()) */
+};
+
+/*
+*** 4.3.7 Local file header:
+***
+*** local file header signature 4 bytes (0x04034b50)
+*** version needed to extract 2 bytes
+*** general purpose bit flag 2 bytes
+*** compression method 2 bytes
+*** last mod file time 2 bytes
+*** last mod file date 2 bytes
+*** crc-32 4 bytes
+*** compressed size 4 bytes
+*** uncompressed size 4 bytes
+*** file name length 2 bytes
+*** extra field length 2 bytes
+***
+*/
+typedef struct ZipfileLFH ZipfileLFH;
+struct ZipfileLFH {
+ u16 iVersionExtract;
+ u16 flags;
+ u16 iCompression;
+ u16 mTime;
+ u16 mDate;
+ u32 crc32;
+ u32 szCompressed;
+ u32 szUncompressed;
+ u16 nFile;
+ u16 nExtra;
+};
+
+typedef struct ZipfileEntry ZipfileEntry;
+struct ZipfileEntry {
+ ZipfileCDS cds; /* Parsed CDS record */
+ u32 mUnixTime; /* Modification time, in UNIX format */
+ u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */
+ i64 iDataOff; /* Offset to data in file (if aData==0) */
+ u8 *aData; /* cds.szCompressed bytes of compressed data */
+ ZipfileEntry *pNext; /* Next element in in-memory CDS */
+};
+
+/*
+** Cursor type for zipfile tables.
+*/
+typedef struct ZipfileCsr ZipfileCsr;
+struct ZipfileCsr {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ i64 iId; /* Cursor ID */
+ u8 bEof; /* True when at EOF */
+ u8 bNoop; /* If next xNext() call is no-op */
+
+ /* Used outside of write transactions */
+ FILE *pFile; /* Zip file */
+ i64 iNextOff; /* Offset of next record in central directory */
+ ZipfileEOCD eocd; /* Parse of central directory record */
+
+ ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */
+ ZipfileEntry *pCurrent; /* Current entry */
+ ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */
+};
+
+typedef struct ZipfileTab ZipfileTab;
+struct ZipfileTab {
+ sqlite3_vtab base; /* Base class - must be first */
+ char *zFile; /* Zip file this table accesses (may be NULL) */
+ sqlite3 *db; /* Host database connection */
+ u8 *aBuffer; /* Temporary buffer used for various tasks */
+
+ ZipfileCsr *pCsrList; /* List of cursors */
+ i64 iNextCsrid;
+
+ /* The following are used by write transactions only */
+ ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
+ ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */
+ FILE *pWriteFd; /* File handle open on zip archive */
+ i64 szCurrent; /* Current size of zip archive */
+ i64 szOrig; /* Size of archive at start of transaction */
+};
+
+/*
+** Set the error message contained in context ctx to the results of
+** vprintf(zFmt, ...).
+*/
+static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
+ char *zMsg = 0;
+ va_list ap;
+ va_start(ap, zFmt);
+ zMsg = sqlite3_vmprintf(zFmt, ap);
+ sqlite3_result_error(ctx, zMsg, -1);
+ sqlite3_free(zMsg);
+ va_end(ap);
+}
+
+/*
+** If string zIn is quoted, dequote it in place. Otherwise, if the string
+** is not quoted, do nothing.
+*/
+static void zipfileDequote(char *zIn){
+ char q = zIn[0];
+ if( q=='"' || q=='\'' || q=='`' || q=='[' ){
+ int iIn = 1;
+ int iOut = 0;
+ if( q=='[' ) q = ']';
+ while( ALWAYS(zIn[iIn]) ){
+ char c = zIn[iIn++];
+ if( c==q && zIn[iIn++]!=q ) break;
+ zIn[iOut++] = c;
+ }
+ zIn[iOut] = '\0';
+ }
+}
+
+/*
+** Construct a new ZipfileTab virtual table object.
+**
+** argv[0] -> module name ("zipfile")
+** argv[1] -> database name
+** argv[2] -> table name
+** argv[...] -> "column name" and other module argument fields.
+*/
+static int zipfileConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
+ int nFile = 0;
+ const char *zFile = 0;
+ ZipfileTab *pNew = 0;
+ int rc;
+
+ /* If the table name is not "zipfile", require that the argument be
+ ** specified. This stops zipfile tables from being created as:
+ **
+ ** CREATE VIRTUAL TABLE zzz USING zipfile();
+ **
+ ** It does not prevent:
+ **
+ ** CREATE VIRTUAL TABLE zipfile USING zipfile();
+ */
+ assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
+ if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
+ *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
+ return SQLITE_ERROR;
+ }
+
+ if( argc>3 ){
+ zFile = argv[3];
+ nFile = (int)strlen(zFile)+1;
+ }
+
+ rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
+ if( rc==SQLITE_OK ){
+ pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile);
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, nByte+nFile);
+ pNew->db = db;
+ pNew->aBuffer = (u8*)&pNew[1];
+ if( zFile ){
+ pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
+ memcpy(pNew->zFile, zFile, nFile);
+ zipfileDequote(pNew->zFile);
+ }
+ }
+ *ppVtab = (sqlite3_vtab*)pNew;
+ return rc;
+}
+
+/*
+** Free the ZipfileEntry structure indicated by the only argument.
+*/
+static void zipfileEntryFree(ZipfileEntry *p){
+ if( p ){
+ sqlite3_free(p->cds.zFile);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Release resources that should be freed at the end of a write
+** transaction.
+*/
+static void zipfileCleanupTransaction(ZipfileTab *pTab){
+ ZipfileEntry *pEntry;
+ ZipfileEntry *pNext;
+
+ if( pTab->pWriteFd ){
+ fclose(pTab->pWriteFd);
+ pTab->pWriteFd = 0;
+ }
+ for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
+ pNext = pEntry->pNext;
+ zipfileEntryFree(pEntry);
+ }
+ pTab->pFirstEntry = 0;
+ pTab->pLastEntry = 0;
+ pTab->szCurrent = 0;
+ pTab->szOrig = 0;
+}
+
+/*
+** This method is the destructor for zipfile vtab objects.
+*/
+static int zipfileDisconnect(sqlite3_vtab *pVtab){
+ zipfileCleanupTransaction((ZipfileTab*)pVtab);
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** Constructor for a new ZipfileCsr object.
+*/
+static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
+ ZipfileTab *pTab = (ZipfileTab*)p;
+ ZipfileCsr *pCsr;
+ pCsr = sqlite3_malloc(sizeof(*pCsr));
+ *ppCsr = (sqlite3_vtab_cursor*)pCsr;
+ if( pCsr==0 ){
+ return SQLITE_NOMEM;
+ }
+ memset(pCsr, 0, sizeof(*pCsr));
+ pCsr->iId = ++pTab->iNextCsrid;
+ pCsr->pCsrNext = pTab->pCsrList;
+ pTab->pCsrList = pCsr;
+ return SQLITE_OK;
+}
+
+/*
+** Reset a cursor back to the state it was in when first returned
+** by zipfileOpen().
+*/
+static void zipfileResetCursor(ZipfileCsr *pCsr){
+ ZipfileEntry *p;
+ ZipfileEntry *pNext;
+
+ pCsr->bEof = 0;
+ if( pCsr->pFile ){
+ fclose(pCsr->pFile);
+ pCsr->pFile = 0;
+ zipfileEntryFree(pCsr->pCurrent);
+ pCsr->pCurrent = 0;
+ }
+
+ for(p=pCsr->pFreeEntry; p; p=pNext){
+ pNext = p->pNext;
+ zipfileEntryFree(p);
+ }
+}
+
+/*
+** Destructor for an ZipfileCsr.
+*/
+static int zipfileClose(sqlite3_vtab_cursor *cur){
+ ZipfileCsr *pCsr = (ZipfileCsr*)cur;
+ ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
+ ZipfileCsr **pp;
+ zipfileResetCursor(pCsr);
+
+ /* Remove this cursor from the ZipfileTab.pCsrList list. */
+ for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext));
+ *pp = pCsr->pCsrNext;
+
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/*
+** Set the error message for the virtual table associated with cursor
+** pCsr to the results of vprintf(zFmt, ...).
+*/
+static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ sqlite3_free(pTab->base.zErrMsg);
+ pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+}
+static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ sqlite3_free(pCsr->base.pVtab->zErrMsg);
+ pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+}
+
+/*
+** Read nRead bytes of data from offset iOff of file pFile into buffer
+** aRead[]. Return SQLITE_OK if successful, or an SQLite error code
+** otherwise.
+**
+** If an error does occur, output variable (*pzErrmsg) may be set to point
+** to an English language error message. It is the responsibility of the
+** caller to eventually free this buffer using
+** sqlite3_free().
+*/
+static int zipfileReadData(
+ FILE *pFile, /* Read from this file */
+ u8 *aRead, /* Read into this buffer */
+ int nRead, /* Number of bytes to read */
+ i64 iOff, /* Offset to read from */
+ char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */
+){
+ size_t n;
+ fseek(pFile, (long)iOff, SEEK_SET);
+ n = fread(aRead, 1, nRead, pFile);
+ if( (int)n!=nRead ){
+ *pzErrmsg = sqlite3_mprintf("error in fread()");
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+}
+
+static int zipfileAppendData(
+ ZipfileTab *pTab,
+ const u8 *aWrite,
+ int nWrite
+){
+ size_t n;
+ fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
+ n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
+ if( (int)n!=nWrite ){
+ pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
+ return SQLITE_ERROR;
+ }
+ pTab->szCurrent += nWrite;
+ return SQLITE_OK;
+}
+
+/*
+** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
+*/
+static u16 zipfileGetU16(const u8 *aBuf){
+ return (aBuf[1] << 8) + aBuf[0];
+}
+
+/*
+** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
+*/
+static u32 zipfileGetU32(const u8 *aBuf){
+ return ((u32)(aBuf[3]) << 24)
+ + ((u32)(aBuf[2]) << 16)
+ + ((u32)(aBuf[1]) << 8)
+ + ((u32)(aBuf[0]) << 0);
+}
+
+/*
+** Write a 16-bit little endiate integer into buffer aBuf.
+*/
+static void zipfilePutU16(u8 *aBuf, u16 val){
+ aBuf[0] = val & 0xFF;
+ aBuf[1] = (val>>8) & 0xFF;
+}
+
+/*
+** Write a 32-bit little endiate integer into buffer aBuf.
+*/
+static void zipfilePutU32(u8 *aBuf, u32 val){
+ aBuf[0] = val & 0xFF;
+ aBuf[1] = (val>>8) & 0xFF;
+ aBuf[2] = (val>>16) & 0xFF;
+ aBuf[3] = (val>>24) & 0xFF;
+}
+
+#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
+#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
+
+#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
+#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
+
+/*
+** Magic numbers used to read CDS records.
+*/
+#define ZIPFILE_CDS_NFILE_OFF 28
+#define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
+
+/*
+** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
+** if the record is not well-formed, or SQLITE_OK otherwise.
+*/
+static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
+ u8 *aRead = aBuf;
+ u32 sig = zipfileRead32(aRead);
+ int rc = SQLITE_OK;
+ if( sig!=ZIPFILE_SIGNATURE_CDS ){
+ rc = SQLITE_ERROR;
+ }else{
+ pCDS->iVersionMadeBy = zipfileRead16(aRead);
+ pCDS->iVersionExtract = zipfileRead16(aRead);
+ pCDS->flags = zipfileRead16(aRead);
+ pCDS->iCompression = zipfileRead16(aRead);
+ pCDS->mTime = zipfileRead16(aRead);
+ pCDS->mDate = zipfileRead16(aRead);
+ pCDS->crc32 = zipfileRead32(aRead);
+ pCDS->szCompressed = zipfileRead32(aRead);
+ pCDS->szUncompressed = zipfileRead32(aRead);
+ assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
+ pCDS->nFile = zipfileRead16(aRead);
+ pCDS->nExtra = zipfileRead16(aRead);
+ pCDS->nComment = zipfileRead16(aRead);
+ pCDS->iDiskStart = zipfileRead16(aRead);
+ pCDS->iInternalAttr = zipfileRead16(aRead);
+ pCDS->iExternalAttr = zipfileRead32(aRead);
+ pCDS->iOffset = zipfileRead32(aRead);
+ assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
+ }
+
+ return rc;
+}
+
+/*
+** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
+** if the record is not well-formed, or SQLITE_OK otherwise.
+*/
+static int zipfileReadLFH(
+ u8 *aBuffer,
+ ZipfileLFH *pLFH
+){
+ u8 *aRead = aBuffer;
+ int rc = SQLITE_OK;
+
+ u32 sig = zipfileRead32(aRead);
+ if( sig!=ZIPFILE_SIGNATURE_LFH ){
+ rc = SQLITE_ERROR;
+ }else{
+ pLFH->iVersionExtract = zipfileRead16(aRead);
+ pLFH->flags = zipfileRead16(aRead);
+ pLFH->iCompression = zipfileRead16(aRead);
+ pLFH->mTime = zipfileRead16(aRead);
+ pLFH->mDate = zipfileRead16(aRead);
+ pLFH->crc32 = zipfileRead32(aRead);
+ pLFH->szCompressed = zipfileRead32(aRead);
+ pLFH->szUncompressed = zipfileRead32(aRead);
+ pLFH->nFile = zipfileRead16(aRead);
+ pLFH->nExtra = zipfileRead16(aRead);
+ }
+ return rc;
+}
+
+
+/*
+** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
+** Scan through this buffer to find an "extra-timestamp" field. If one
+** exists, extract the 32-bit modification-timestamp from it and store
+** the value in output parameter *pmTime.
+**
+** Zero is returned if no extra-timestamp record could be found (and so
+** *pmTime is left unchanged), or non-zero otherwise.
+**
+** The general format of an extra field is:
+**
+** Header ID 2 bytes
+** Data Size 2 bytes
+** Data N bytes
+*/
+static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
+ int ret = 0;
+ u8 *p = aExtra;
+ u8 *pEnd = &aExtra[nExtra];
+
+ while( p<pEnd ){
+ u16 id = zipfileRead16(p);
+ u16 nByte = zipfileRead16(p);
+
+ switch( id ){
+ case ZIPFILE_EXTRA_TIMESTAMP: {
+ u8 b = p[0];
+ if( b & 0x01 ){ /* 0x01 -> modtime is present */
+ *pmTime = zipfileGetU32(&p[1]);
+ ret = 1;
+ }
+ break;
+ }
+ }
+
+ p += nByte;
+ }
+ return ret;
+}
+
+/*
+** Convert the standard MS-DOS timestamp stored in the mTime and mDate
+** fields of the CDS structure passed as the only argument to a 32-bit
+** UNIX seconds-since-the-epoch timestamp. Return the result.
+**
+** "Standard" MS-DOS time format:
+**
+** File modification time:
+** Bits 00-04: seconds divided by 2
+** Bits 05-10: minute
+** Bits 11-15: hour
+** File modification date:
+** Bits 00-04: day
+** Bits 05-08: month (1-12)
+** Bits 09-15: years from 1980
+**
+** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
+*/
+static u32 zipfileMtime(ZipfileCDS *pCDS){
+ int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
+ int M = ((pCDS->mDate >> 5) & 0x0F);
+ int D = (pCDS->mDate & 0x1F);
+ int B = -13;
+
+ int sec = (pCDS->mTime & 0x1F)*2;
+ int min = (pCDS->mTime >> 5) & 0x3F;
+ int hr = (pCDS->mTime >> 11) & 0x1F;
+ i64 JD;
+
+ /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
+
+ /* Calculate the JD in seconds for noon on the day in question */
+ if( M<3 ){
+ Y = Y-1;
+ M = M+12;
+ }
+ JD = (i64)(24*60*60) * (
+ (int)(365.25 * (Y + 4716))
+ + (int)(30.6001 * (M + 1))
+ + D + B - 1524
+ );
+
+ /* Correct the JD for the time within the day */
+ JD += (hr-12) * 3600 + min * 60 + sec;
+
+ /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
+ return (u32)(JD - (i64)(24405875) * 24*60*6);
+}
+
+/*
+** The opposite of zipfileMtime(). This function populates the mTime and
+** mDate fields of the CDS structure passed as the first argument according
+** to the UNIX timestamp value passed as the second.
+*/
+static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
+ /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
+ i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
+
+ int A, B, C, D, E;
+ int yr, mon, day;
+ int hr, min, sec;
+
+ A = (int)((JD - 1867216.25)/36524.25);
+ A = (int)(JD + 1 + A - (A/4));
+ B = A + 1524;
+ C = (int)((B - 122.1)/365.25);
+ D = (36525*(C&32767))/100;
+ E = (int)((B-D)/30.6001);
+
+ day = B - D - (int)(30.6001*E);
+ mon = (E<14 ? E-1 : E-13);
+ yr = mon>2 ? C-4716 : C-4715;
+
+ hr = (mUnixTime % (24*60*60)) / (60*60);
+ min = (mUnixTime % (60*60)) / 60;
+ sec = (mUnixTime % 60);
+
+ if( yr>=1980 ){
+ pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
+ pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
+ }else{
+ pCds->mDate = pCds->mTime = 0;
+ }
+
+ assert( mUnixTime<315507600
+ || mUnixTime==zipfileMtime(pCds)
+ || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds))
+ /* || (mUnixTime % 2) */
+ );
+}
+
+/*
+** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
+** size) containing an entire zip archive image. Or, if aBlob is NULL,
+** then pFile is a file-handle open on a zip file. In either case, this
+** function creates a ZipfileEntry object based on the zip archive entry
+** for which the CDS record is at offset iOff.
+**
+** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
+** the new object. Otherwise, an SQLite error code is returned and the
+** final value of (*ppEntry) undefined.
+*/
+static int zipfileGetEntry(
+ ZipfileTab *pTab, /* Store any error message here */
+ const u8 *aBlob, /* Pointer to in-memory file image */
+ int nBlob, /* Size of aBlob[] in bytes */
+ FILE *pFile, /* If aBlob==0, read from this file */
+ i64 iOff, /* Offset of CDS record */
+ ZipfileEntry **ppEntry /* OUT: Pointer to new object */
+){
+ u8 *aRead;
+ char **pzErr = &pTab->base.zErrMsg;
+ int rc = SQLITE_OK;
+
+ if( aBlob==0 ){
+ aRead = pTab->aBuffer;
+ rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
+ }else{
+ aRead = (u8*)&aBlob[iOff];
+ }
+
+ if( rc==SQLITE_OK ){
+ int nAlloc;
+ ZipfileEntry *pNew;
+
+ int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
+ int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
+ nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
+
+ nAlloc = sizeof(ZipfileEntry) + nExtra;
+ if( aBlob ){
+ nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
+ }
+
+ pNew = (ZipfileEntry*)sqlite3_malloc(nAlloc);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pNew, 0, sizeof(ZipfileEntry));
+ rc = zipfileReadCDS(aRead, &pNew->cds);
+ if( rc!=SQLITE_OK ){
+ *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
+ }else if( aBlob==0 ){
+ rc = zipfileReadData(
+ pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
+ );
+ }else{
+ aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ u32 *pt = &pNew->mUnixTime;
+ pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
+ pNew->aExtra = (u8*)&pNew[1];
+ memcpy(pNew->aExtra, &aRead[nFile], nExtra);
+ if( pNew->cds.zFile==0 ){
+ rc = SQLITE_NOMEM;
+ }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
+ pNew->mUnixTime = zipfileMtime(&pNew->cds);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ static const int szFix = ZIPFILE_LFH_FIXED_SZ;
+ ZipfileLFH lfh;
+ if( pFile ){
+ rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
+ }else{
+ aRead = (u8*)&aBlob[pNew->cds.iOffset];
+ }
+
+ rc = zipfileReadLFH(aRead, &lfh);
+ if( rc==SQLITE_OK ){
+ pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
+ pNew->iDataOff += lfh.nFile + lfh.nExtra;
+ if( aBlob && pNew->cds.szCompressed ){
+ pNew->aData = &pNew->aExtra[nExtra];
+ memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
+ }
+ }else{
+ *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
+ (int)pNew->cds.iOffset
+ );
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ zipfileEntryFree(pNew);
+ }else{
+ *ppEntry = pNew;
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Advance an ZipfileCsr to its next row of output.
+*/
+static int zipfileNext(sqlite3_vtab_cursor *cur){
+ ZipfileCsr *pCsr = (ZipfileCsr*)cur;
+ int rc = SQLITE_OK;
+
+ if( pCsr->pFile ){
+ i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
+ zipfileEntryFree(pCsr->pCurrent);
+ pCsr->pCurrent = 0;
+ if( pCsr->iNextOff>=iEof ){
+ pCsr->bEof = 1;
+ }else{
+ ZipfileEntry *p = 0;
+ ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
+ rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
+ if( rc==SQLITE_OK ){
+ pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
+ pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
+ }
+ pCsr->pCurrent = p;
+ }
+ }else{
+ if( !pCsr->bNoop ){
+ pCsr->pCurrent = pCsr->pCurrent->pNext;
+ }
+ if( pCsr->pCurrent==0 ){
+ pCsr->bEof = 1;
+ }
+ }
+
+ pCsr->bNoop = 0;
+ return rc;
+}
+
+static void zipfileFree(void *p) {
+ sqlite3_free(p);
+}
+
+/*
+** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
+** size is nOut bytes. This function uncompresses the data and sets the
+** return value in context pCtx to the result (a blob).
+**
+** If an error occurs, an error code is left in pCtx instead.
+*/
+static void zipfileInflate(
+ sqlite3_context *pCtx, /* Store result here */
+ const u8 *aIn, /* Compressed data */
+ int nIn, /* Size of buffer aIn[] in bytes */
+ int nOut /* Expected output size */
+){
+ u8 *aRes = sqlite3_malloc(nOut);
+ if( aRes==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ int err;
+ z_stream str;
+ memset(&str, 0, sizeof(str));
+
+ str.next_in = (Byte*)aIn;
+ str.avail_in = nIn;
+ str.next_out = (Byte*)aRes;
+ str.avail_out = nOut;
+
+ err = inflateInit2(&str, -15);
+ if( err!=Z_OK ){
+ zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
+ }else{
+ err = inflate(&str, Z_NO_FLUSH);
+ if( err!=Z_STREAM_END ){
+ zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
+ }else{
+ sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
+ aRes = 0;
+ }
+ }
+ sqlite3_free(aRes);
+ inflateEnd(&str);
+ }
+}
+
+/*
+** Buffer aIn (size nIn bytes) contains uncompressed data. This function
+** compresses it and sets (*ppOut) to point to a buffer containing the
+** compressed data. The caller is responsible for eventually calling
+** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut)
+** is set to the size of buffer (*ppOut) in bytes.
+**
+** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
+** code is returned and an error message left in virtual-table handle
+** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
+** case.
+*/
+static int zipfileDeflate(
+ const u8 *aIn, int nIn, /* Input */
+ u8 **ppOut, int *pnOut, /* Output */
+ char **pzErr /* OUT: Error message */
+){
+ int nAlloc = (int)compressBound(nIn);
+ u8 *aOut;
+ int rc = SQLITE_OK;
+
+ aOut = (u8*)sqlite3_malloc(nAlloc);
+ if( aOut==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int res;
+ z_stream str;
+ memset(&str, 0, sizeof(str));
+ str.next_in = (Bytef*)aIn;
+ str.avail_in = nIn;
+ str.next_out = aOut;
+ str.avail_out = nAlloc;
+
+ deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+ res = deflate(&str, Z_FINISH);
+
+ if( res==Z_STREAM_END ){
+ *ppOut = aOut;
+ *pnOut = (int)str.total_out;
+ }else{
+ sqlite3_free(aOut);
+ *pzErr = sqlite3_mprintf("zipfile: deflate() error");
+ rc = SQLITE_ERROR;
+ }
+ deflateEnd(&str);
+ }
+
+ return rc;
+}
+
+
+/*
+** Return values of columns for the row at which the series_cursor
+** is currently pointing.
+*/
+static int zipfileColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ ZipfileCsr *pCsr = (ZipfileCsr*)cur;
+ ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
+ int rc = SQLITE_OK;
+ switch( i ){
+ case 0: /* name */
+ sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
+ break;
+ case 1: /* mode */
+ /* TODO: Whether or not the following is correct surely depends on
+ ** the platform on which the archive was created. */
+ sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
+ break;
+ case 2: { /* mtime */
+ sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
+ break;
+ }
+ case 3: { /* sz */
+ if( sqlite3_vtab_nochange(ctx)==0 ){
+ sqlite3_result_int64(ctx, pCDS->szUncompressed);
+ }
+ break;
+ }
+ case 4: /* rawdata */
+ if( sqlite3_vtab_nochange(ctx) ) break;
+ case 5: { /* data */
+ if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
+ int sz = pCDS->szCompressed;
+ int szFinal = pCDS->szUncompressed;
+ if( szFinal>0 ){
+ u8 *aBuf;
+ u8 *aFree = 0;
+ if( pCsr->pCurrent->aData ){
+ aBuf = pCsr->pCurrent->aData;
+ }else{
+ aBuf = aFree = sqlite3_malloc(sz);
+ if( aBuf==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ FILE *pFile = pCsr->pFile;
+ if( pFile==0 ){
+ pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
+ }
+ rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
+ &pCsr->base.pVtab->zErrMsg
+ );
+ }
+ }
+ if( rc==SQLITE_OK ){
+ if( i==5 && pCDS->iCompression ){
+ zipfileInflate(ctx, aBuf, sz, szFinal);
+ }else{
+ sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
+ }
+ }
+ sqlite3_free(aFree);
+ }else{
+ /* Figure out if this is a directory or a zero-sized file. Consider
+ ** it to be a directory either if the mode suggests so, or if
+ ** the final character in the name is '/'. */
+ u32 mode = pCDS->iExternalAttr >> 16;
+ if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
+ sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
+ }
+ }
+ }
+ break;
+ }
+ case 6: /* method */
+ sqlite3_result_int(ctx, pCDS->iCompression);
+ break;
+ default: /* z */
+ assert( i==7 );
+ sqlite3_result_int64(ctx, pCsr->iId);
+ break;
+ }
+
+ return rc;
+}
+
+/*
+** Return TRUE if the cursor is at EOF.
+*/
+static int zipfileEof(sqlite3_vtab_cursor *cur){
+ ZipfileCsr *pCsr = (ZipfileCsr*)cur;
+ return pCsr->bEof;
+}
+
+/*
+** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
+** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
+** is guaranteed to be a file-handle open on a zip file.
+**
+** This function attempts to locate the EOCD record within the zip archive
+** and populate *pEOCD with the results of decoding it. SQLITE_OK is
+** returned if successful. Otherwise, an SQLite error code is returned and
+** an English language error message may be left in virtual-table pTab.
+*/
+static int zipfileReadEOCD(
+ ZipfileTab *pTab, /* Return errors here */
+ const u8 *aBlob, /* Pointer to in-memory file image */
+ int nBlob, /* Size of aBlob[] in bytes */
+ FILE *pFile, /* Read from this file if aBlob==0 */
+ ZipfileEOCD *pEOCD /* Object to populate */
+){
+ u8 *aRead = pTab->aBuffer; /* Temporary buffer */
+ int nRead; /* Bytes to read from file */
+ int rc = SQLITE_OK;
+
+ if( aBlob==0 ){
+ i64 iOff; /* Offset to read from */
+ i64 szFile; /* Total size of file in bytes */
+ fseek(pFile, 0, SEEK_END);
+ szFile = (i64)ftell(pFile);
+ if( szFile==0 ){
+ memset(pEOCD, 0, sizeof(ZipfileEOCD));
+ return SQLITE_OK;
+ }
+ nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
+ iOff = szFile - nRead;
+ rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
+ }else{
+ nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
+ aRead = (u8*)&aBlob[nBlob-nRead];
+ }
+
+ if( rc==SQLITE_OK ){
+ int i;
+
+ /* Scan backwards looking for the signature bytes */
+ for(i=nRead-20; i>=0; i--){
+ if( aRead[i]==0x50 && aRead[i+1]==0x4b
+ && aRead[i+2]==0x05 && aRead[i+3]==0x06
+ ){
+ break;
+ }
+ }
+ if( i<0 ){
+ pTab->base.zErrMsg = sqlite3_mprintf(
+ "cannot find end of central directory record"
+ );
+ return SQLITE_ERROR;
+ }
+
+ aRead += i+4;
+ pEOCD->iDisk = zipfileRead16(aRead);
+ pEOCD->iFirstDisk = zipfileRead16(aRead);
+ pEOCD->nEntry = zipfileRead16(aRead);
+ pEOCD->nEntryTotal = zipfileRead16(aRead);
+ pEOCD->nSize = zipfileRead32(aRead);
+ pEOCD->iOffset = zipfileRead32(aRead);
+ }
+
+ return rc;
+}
+
+/*
+** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry
+** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
+** to the end of the list. Otherwise, it is added to the list immediately
+** before pBefore (which is guaranteed to be a part of said list).
+*/
+static void zipfileAddEntry(
+ ZipfileTab *pTab,
+ ZipfileEntry *pBefore,
+ ZipfileEntry *pNew
+){
+ assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
+ assert( pNew->pNext==0 );
+ if( pBefore==0 ){
+ if( pTab->pFirstEntry==0 ){
+ pTab->pFirstEntry = pTab->pLastEntry = pNew;
+ }else{
+ assert( pTab->pLastEntry->pNext==0 );
+ pTab->pLastEntry->pNext = pNew;
+ pTab->pLastEntry = pNew;
+ }
+ }else{
+ ZipfileEntry **pp;
+ for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
+ pNew->pNext = pBefore;
+ *pp = pNew;
+ }
+}
+
+static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
+ ZipfileEOCD eocd;
+ int rc;
+ int i;
+ i64 iOff;
+
+ rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
+ iOff = eocd.iOffset;
+ for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
+ ZipfileEntry *pNew = 0;
+ rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
+
+ if( rc==SQLITE_OK ){
+ zipfileAddEntry(pTab, 0, pNew);
+ iOff += ZIPFILE_CDS_FIXED_SZ;
+ iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
+ }
+ }
+ return rc;
+}
+
+/*
+** xFilter callback.
+*/
+static int zipfileFilter(
+ sqlite3_vtab_cursor *cur,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
+ ZipfileCsr *pCsr = (ZipfileCsr*)cur;
+ const char *zFile = 0; /* Zip file to scan */
+ int rc = SQLITE_OK; /* Return Code */
+ int bInMemory = 0; /* True for an in-memory zipfile */
+
+ zipfileResetCursor(pCsr);
+
+ if( pTab->zFile ){
+ zFile = pTab->zFile;
+ }else if( idxNum==0 ){
+ zipfileCursorErr(pCsr, "zipfile() function requires an argument");
+ return SQLITE_ERROR;
+ }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
+ const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
+ int nBlob = sqlite3_value_bytes(argv[0]);
+ assert( pTab->pFirstEntry==0 );
+ rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
+ pCsr->pFreeEntry = pTab->pFirstEntry;
+ pTab->pFirstEntry = pTab->pLastEntry = 0;
+ if( rc!=SQLITE_OK ) return rc;
+ bInMemory = 1;
+ }else{
+ zFile = (const char*)sqlite3_value_text(argv[0]);
+ }
+
+ if( 0==pTab->pWriteFd && 0==bInMemory ){
+ pCsr->pFile = fopen(zFile, "rb");
+ if( pCsr->pFile==0 ){
+ zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
+ rc = SQLITE_ERROR;
+ }else{
+ rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
+ if( rc==SQLITE_OK ){
+ if( pCsr->eocd.nEntry==0 ){
+ pCsr->bEof = 1;
+ }else{
+ pCsr->iNextOff = pCsr->eocd.iOffset;
+ rc = zipfileNext(cur);
+ }
+ }
+ }
+ }else{
+ pCsr->bNoop = 1;
+ pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
+ rc = zipfileNext(cur);
+ }
+
+ return rc;
+}
+
+/*
+** xBestIndex callback.
+*/
+static int zipfileBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i;
+
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
+ if( pCons->usable==0 ) continue;
+ if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
+ break;
+ }
+
+ if( i<pIdxInfo->nConstraint ){
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ pIdxInfo->estimatedCost = 1000.0;
+ pIdxInfo->idxNum = 1;
+ }else{
+ pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
+ pIdxInfo->idxNum = 0;
+ }
+
+ return SQLITE_OK;
+}
+
+static ZipfileEntry *zipfileNewEntry(const char *zPath){
+ ZipfileEntry *pNew;
+ pNew = sqlite3_malloc(sizeof(ZipfileEntry));
+ if( pNew ){
+ memset(pNew, 0, sizeof(ZipfileEntry));
+ pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
+ if( pNew->cds.zFile==0 ){
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }
+ return pNew;
+}
+
+static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
+ ZipfileCDS *pCds = &pEntry->cds;
+ u8 *a = aBuf;
+
+ pCds->nExtra = 9;
+
+ /* Write the LFH itself */
+ zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
+ zipfileWrite16(a, pCds->iVersionExtract);
+ zipfileWrite16(a, pCds->flags);
+ zipfileWrite16(a, pCds->iCompression);
+ zipfileWrite16(a, pCds->mTime);
+ zipfileWrite16(a, pCds->mDate);
+ zipfileWrite32(a, pCds->crc32);
+ zipfileWrite32(a, pCds->szCompressed);
+ zipfileWrite32(a, pCds->szUncompressed);
+ zipfileWrite16(a, (u16)pCds->nFile);
+ zipfileWrite16(a, pCds->nExtra);
+ assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
+
+ /* Add the file name */
+ memcpy(a, pCds->zFile, (int)pCds->nFile);
+ a += (int)pCds->nFile;
+
+ /* The "extra" data */
+ zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
+ zipfileWrite16(a, 5);
+ *a++ = 0x01;
+ zipfileWrite32(a, pEntry->mUnixTime);
+
+ return a-aBuf;
+}
+
+static int zipfileAppendEntry(
+ ZipfileTab *pTab,
+ ZipfileEntry *pEntry,
+ const u8 *pData,
+ int nData
+){
+ u8 *aBuf = pTab->aBuffer;
+ int nBuf;
+ int rc;
+
+ nBuf = zipfileSerializeLFH(pEntry, aBuf);
+ rc = zipfileAppendData(pTab, aBuf, nBuf);
+ if( rc==SQLITE_OK ){
+ pEntry->iDataOff = pTab->szCurrent;
+ rc = zipfileAppendData(pTab, pData, nData);
+ }
+
+ return rc;
+}
+
+static int zipfileGetMode(
+ sqlite3_value *pVal,
+ int bIsDir, /* If true, default to directory */
+ u32 *pMode, /* OUT: Mode value */
+ char **pzErr /* OUT: Error message */
+){
+ const char *z = (const char*)sqlite3_value_text(pVal);
+ u32 mode = 0;
+ if( z==0 ){
+ mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
+ }else if( z[0]>='0' && z[0]<='9' ){
+ mode = (unsigned int)sqlite3_value_int(pVal);
+ }else{
+ const char zTemplate[11] = "-rwxrwxrwx";
+ int i;
+ if( strlen(z)!=10 ) goto parse_error;
+ switch( z[0] ){
+ case '-': mode |= S_IFREG; break;
+ case 'd': mode |= S_IFDIR; break;
+ case 'l': mode |= S_IFLNK; break;
+ default: goto parse_error;
+ }
+ for(i=1; i<10; i++){
+ if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
+ else if( z[i]!='-' ) goto parse_error;
+ }
+ }
+ if( ((mode & S_IFDIR)==0)==bIsDir ){
+ /* The "mode" attribute is a directory, but data has been specified.
+ ** Or vice-versa - no data but "mode" is a file or symlink. */
+ *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
+ return SQLITE_CONSTRAINT;
+ }
+ *pMode = mode;
+ return SQLITE_OK;
+
+ parse_error:
+ *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
+ return SQLITE_ERROR;
+}
+
+/*
+** Both (const char*) arguments point to nul-terminated strings. Argument
+** nB is the value of strlen(zB). This function returns 0 if the strings are
+** identical, ignoring any trailing '/' character in either path. */
+static int zipfileComparePath(const char *zA, const char *zB, int nB){
+ int nA = (int)strlen(zA);
+ if( zA[nA-1]=='/' ) nA--;
+ if( zB[nB-1]=='/' ) nB--;
+ if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
+ return 1;
+}
+
+static int zipfileBegin(sqlite3_vtab *pVtab){
+ ZipfileTab *pTab = (ZipfileTab*)pVtab;
+ int rc = SQLITE_OK;
+
+ assert( pTab->pWriteFd==0 );
+
+ /* Open a write fd on the file. Also load the entire central directory
+ ** structure into memory. During the transaction any new file data is
+ ** appended to the archive file, but the central directory is accumulated
+ ** in main-memory until the transaction is committed. */
+ pTab->pWriteFd = fopen(pTab->zFile, "ab+");
+ if( pTab->pWriteFd==0 ){
+ pTab->base.zErrMsg = sqlite3_mprintf(
+ "zipfile: failed to open file %s for writing", pTab->zFile
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ fseek(pTab->pWriteFd, 0, SEEK_END);
+ pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
+ rc = zipfileLoadDirectory(pTab, 0, 0);
+ }
+
+ if( rc!=SQLITE_OK ){
+ zipfileCleanupTransaction(pTab);
+ }
+
+ return rc;
+}
+
+/*
+** Return the current time as a 32-bit timestamp in UNIX epoch format (like
+** time(2)).
+*/
+static u32 zipfileTime(void){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
+ u32 ret;
+ if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
+ i64 ms;
+ pVfs->xCurrentTimeInt64(pVfs, &ms);
+ ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
+ }else{
+ double day;
+ pVfs->xCurrentTime(pVfs, &day);
+ ret = (u32)((day - 2440587.5) * 86400);
+ }
+ return ret;
+}
+
+/*
+** Return a 32-bit timestamp in UNIX epoch format.
+**
+** If the value passed as the only argument is either NULL or an SQL NULL,
+** return the current time. Otherwise, return the value stored in (*pVal)
+** cast to a 32-bit unsigned integer.
+*/
+static u32 zipfileGetTime(sqlite3_value *pVal){
+ if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
+ return zipfileTime();
+ }
+ return (u32)sqlite3_value_int64(pVal);
+}
+
+/*
+** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
+** linked list. Remove it from the list and free the object.
+*/
+static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
+ if( pOld ){
+ ZipfileEntry **pp;
+ for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
+ *pp = (*pp)->pNext;
+ zipfileEntryFree(pOld);
+ }
+}
+
+/*
+** xUpdate method.
+*/
+static int zipfileUpdate(
+ sqlite3_vtab *pVtab,
+ int nVal,
+ sqlite3_value **apVal,
+ sqlite_int64 *pRowid
+){
+ ZipfileTab *pTab = (ZipfileTab*)pVtab;
+ int rc = SQLITE_OK; /* Return Code */
+ ZipfileEntry *pNew = 0; /* New in-memory CDS entry */
+
+ u32 mode = 0; /* Mode for new entry */
+ u32 mTime = 0; /* Modification time for new entry */
+ i64 sz = 0; /* Uncompressed size */
+ const char *zPath = 0; /* Path for new entry */
+ int nPath = 0; /* strlen(zPath) */
+ const u8 *pData = 0; /* Pointer to buffer containing content */
+ int nData = 0; /* Size of pData buffer in bytes */
+ int iMethod = 0; /* Compression method for new entry */
+ u8 *pFree = 0; /* Free this */
+ char *zFree = 0; /* Also free this */
+ ZipfileEntry *pOld = 0;
+ ZipfileEntry *pOld2 = 0;
+ int bUpdate = 0; /* True for an update that modifies "name" */
+ int bIsDir = 0;
+ u32 iCrc32 = 0;
+
+ if( pTab->pWriteFd==0 ){
+ rc = zipfileBegin(pVtab);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+
+ /* If this is a DELETE or UPDATE, find the archive entry to delete. */
+ if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
+ const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
+ int nDelete = (int)strlen(zDelete);
+ if( nVal>1 ){
+ const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
+ if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
+ bUpdate = 1;
+ }
+ }
+ for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
+ if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
+ break;
+ }
+ assert( pOld->pNext );
+ }
+ }
+
+ if( nVal>1 ){
+ /* Check that "sz" and "rawdata" are both NULL: */
+ if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
+ zipfileTableErr(pTab, "sz must be NULL");
+ rc = SQLITE_CONSTRAINT;
+ }
+ if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
+ zipfileTableErr(pTab, "rawdata must be NULL");
+ rc = SQLITE_CONSTRAINT;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
+ /* data=NULL. A directory */
+ bIsDir = 1;
+ }else{
+ /* Value specified for "data", and possibly "method". This must be
+ ** a regular file or a symlink. */
+ const u8 *aIn = sqlite3_value_blob(apVal[7]);
+ int nIn = sqlite3_value_bytes(apVal[7]);
+ int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
+
+ iMethod = sqlite3_value_int(apVal[8]);
+ sz = nIn;
+ pData = aIn;
+ nData = nIn;
+ if( iMethod!=0 && iMethod!=8 ){
+ zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
+ rc = SQLITE_CONSTRAINT;
+ }else{
+ if( bAuto || iMethod ){
+ int nCmp;
+ rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
+ if( rc==SQLITE_OK ){
+ if( iMethod || nCmp<nIn ){
+ iMethod = 8;
+ pData = pFree;
+ nData = nCmp;
+ }
+ }
+ }
+ iCrc32 = crc32(0, aIn, nIn);
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
+ }
+
+ if( rc==SQLITE_OK ){
+ zPath = (const char*)sqlite3_value_text(apVal[2]);
+ nPath = (int)strlen(zPath);
+ mTime = zipfileGetTime(apVal[4]);
+ }
+
+ if( rc==SQLITE_OK && bIsDir ){
+ /* For a directory, check that the last character in the path is a
+ ** '/'. This appears to be required for compatibility with info-zip
+ ** (the unzip command on unix). It does not create directories
+ ** otherwise. */
+ if( zPath[nPath-1]!='/' ){
+ zFree = sqlite3_mprintf("%s/", zPath);
+ if( zFree==0 ){ rc = SQLITE_NOMEM; }
+ zPath = (const char*)zFree;
+ nPath++;
+ }
+ }
+
+ /* Check that we're not inserting a duplicate entry -OR- updating an
+ ** entry with a path, thereby making it into a duplicate. */
+ if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
+ ZipfileEntry *p;
+ for(p=pTab->pFirstEntry; p; p=p->pNext){
+ if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
+ switch( sqlite3_vtab_on_conflict(pTab->db) ){
+ case SQLITE_IGNORE: {
+ goto zipfile_update_done;
+ }
+ case SQLITE_REPLACE: {
+ pOld2 = p;
+ break;
+ }
+ default: {
+ zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
+ rc = SQLITE_CONSTRAINT;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ /* Create the new CDS record. */
+ pNew = zipfileNewEntry(zPath);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
+ pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
+ pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
+ pNew->cds.iCompression = (u16)iMethod;
+ zipfileMtimeToDos(&pNew->cds, mTime);
+ pNew->cds.crc32 = iCrc32;
+ pNew->cds.szCompressed = nData;
+ pNew->cds.szUncompressed = (u32)sz;
+ pNew->cds.iExternalAttr = (mode<<16);
+ pNew->cds.iOffset = (u32)pTab->szCurrent;
+ pNew->cds.nFile = (u16)nPath;
+ pNew->mUnixTime = (u32)mTime;
+ rc = zipfileAppendEntry(pTab, pNew, pData, nData);
+ zipfileAddEntry(pTab, pOld, pNew);
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK && (pOld || pOld2) ){
+ ZipfileCsr *pCsr;
+ for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
+ if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
+ pCsr->pCurrent = pCsr->pCurrent->pNext;
+ pCsr->bNoop = 1;
+ }
+ }
+
+ zipfileRemoveEntryFromList(pTab, pOld);
+ zipfileRemoveEntryFromList(pTab, pOld2);
+ }
+
+zipfile_update_done:
+ sqlite3_free(pFree);
+ sqlite3_free(zFree);
+ return rc;
+}
+
+static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
+ u8 *a = aBuf;
+ zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
+ zipfileWrite16(a, p->iDisk);
+ zipfileWrite16(a, p->iFirstDisk);
+ zipfileWrite16(a, p->nEntry);
+ zipfileWrite16(a, p->nEntryTotal);
+ zipfileWrite32(a, p->nSize);
+ zipfileWrite32(a, p->iOffset);
+ zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/
+
+ return a-aBuf;
+}
+
+static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
+ int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
+ assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
+ return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
+}
+
+/*
+** Serialize the CDS structure into buffer aBuf[]. Return the number
+** of bytes written.
+*/
+static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
+ u8 *a = aBuf;
+ ZipfileCDS *pCDS = &pEntry->cds;
+
+ if( pEntry->aExtra==0 ){
+ pCDS->nExtra = 9;
+ }
+
+ zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
+ zipfileWrite16(a, pCDS->iVersionMadeBy);
+ zipfileWrite16(a, pCDS->iVersionExtract);
+ zipfileWrite16(a, pCDS->flags);
+ zipfileWrite16(a, pCDS->iCompression);
+ zipfileWrite16(a, pCDS->mTime);
+ zipfileWrite16(a, pCDS->mDate);
+ zipfileWrite32(a, pCDS->crc32);
+ zipfileWrite32(a, pCDS->szCompressed);
+ zipfileWrite32(a, pCDS->szUncompressed);
+ assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
+ zipfileWrite16(a, pCDS->nFile);
+ zipfileWrite16(a, pCDS->nExtra);
+ zipfileWrite16(a, pCDS->nComment);
+ zipfileWrite16(a, pCDS->iDiskStart);
+ zipfileWrite16(a, pCDS->iInternalAttr);
+ zipfileWrite32(a, pCDS->iExternalAttr);
+ zipfileWrite32(a, pCDS->iOffset);
+
+ memcpy(a, pCDS->zFile, pCDS->nFile);
+ a += pCDS->nFile;
+
+ if( pEntry->aExtra ){
+ int n = (int)pCDS->nExtra + (int)pCDS->nComment;
+ memcpy(a, pEntry->aExtra, n);
+ a += n;
+ }else{
+ assert( pCDS->nExtra==9 );
+ zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
+ zipfileWrite16(a, 5);
+ *a++ = 0x01;
+ zipfileWrite32(a, pEntry->mUnixTime);
+ }
+
+ return a-aBuf;
+}
+
+static int zipfileCommit(sqlite3_vtab *pVtab){
+ ZipfileTab *pTab = (ZipfileTab*)pVtab;
+ int rc = SQLITE_OK;
+ if( pTab->pWriteFd ){
+ i64 iOffset = pTab->szCurrent;
+ ZipfileEntry *p;
+ ZipfileEOCD eocd;
+ int nEntry = 0;
+
+ /* Write out all entries */
+ for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
+ int n = zipfileSerializeCDS(p, pTab->aBuffer);
+ rc = zipfileAppendData(pTab, pTab->aBuffer, n);
+ nEntry++;
+ }
+
+ /* Write out the EOCD record */
+ eocd.iDisk = 0;
+ eocd.iFirstDisk = 0;
+ eocd.nEntry = (u16)nEntry;
+ eocd.nEntryTotal = (u16)nEntry;
+ eocd.nSize = (u32)(pTab->szCurrent - iOffset);
+ eocd.iOffset = (u32)iOffset;
+ rc = zipfileAppendEOCD(pTab, &eocd);
+
+ zipfileCleanupTransaction(pTab);
+ }
+ return rc;
+}
+
+static int zipfileRollback(sqlite3_vtab *pVtab){
+ return zipfileCommit(pVtab);
+}
+
+static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
+ ZipfileCsr *pCsr;
+ for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
+ if( iId==pCsr->iId ) break;
+ }
+ return pCsr;
+}
+
+static void zipfileFunctionCds(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ ZipfileCsr *pCsr;
+ ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
+ assert( argc>0 );
+
+ pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
+ if( pCsr ){
+ ZipfileCDS *p = &pCsr->pCurrent->cds;
+ char *zRes = sqlite3_mprintf("{"
+ "\"version-made-by\" : %u, "
+ "\"version-to-extract\" : %u, "
+ "\"flags\" : %u, "
+ "\"compression\" : %u, "
+ "\"time\" : %u, "
+ "\"date\" : %u, "
+ "\"crc32\" : %u, "
+ "\"compressed-size\" : %u, "
+ "\"uncompressed-size\" : %u, "
+ "\"file-name-length\" : %u, "
+ "\"extra-field-length\" : %u, "
+ "\"file-comment-length\" : %u, "
+ "\"disk-number-start\" : %u, "
+ "\"internal-attr\" : %u, "
+ "\"external-attr\" : %u, "
+ "\"offset\" : %u }",
+ (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
+ (u32)p->flags, (u32)p->iCompression,
+ (u32)p->mTime, (u32)p->mDate,
+ (u32)p->crc32, (u32)p->szCompressed,
+ (u32)p->szUncompressed, (u32)p->nFile,
+ (u32)p->nExtra, (u32)p->nComment,
+ (u32)p->iDiskStart, (u32)p->iInternalAttr,
+ (u32)p->iExternalAttr, (u32)p->iOffset
+ );
+
+ if( zRes==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
+ sqlite3_free(zRes);
+ }
+ }
+}
+
+/*
+** xFindFunction method.
+*/
+static int zipfileFindFunction(
+ sqlite3_vtab *pVtab, /* Virtual table handle */
+ int nArg, /* Number of SQL function arguments */
+ const char *zName, /* Name of SQL function */
+ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
+ void **ppArg /* OUT: User data for *pxFunc */
+){
+ if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
+ *pxFunc = zipfileFunctionCds;
+ *ppArg = (void*)pVtab;
+ return 1;
+ }
+ return 0;
+}
+
+typedef struct ZipfileBuffer ZipfileBuffer;
+struct ZipfileBuffer {
+ u8 *a; /* Pointer to buffer */
+ int n; /* Size of buffer in bytes */
+ int nAlloc; /* Byte allocated at a[] */
+};
+
+typedef struct ZipfileCtx ZipfileCtx;
+struct ZipfileCtx {
+ int nEntry;
+ ZipfileBuffer body;
+ ZipfileBuffer cds;
+};
+
+static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
+ if( pBuf->n+nByte>pBuf->nAlloc ){
+ u8 *aNew;
+ int nNew = pBuf->n ? pBuf->n*2 : 512;
+ int nReq = pBuf->n + nByte;
+
+ while( nNew<nReq ) nNew = nNew*2;
+ aNew = sqlite3_realloc(pBuf->a, nNew);
+ if( aNew==0 ) return SQLITE_NOMEM;
+ pBuf->a = aNew;
+ pBuf->nAlloc = nNew;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** xStep() callback for the zipfile() aggregate. This can be called in
+** any of the following ways:
+**
+** SELECT zipfile(name,data) ...
+** SELECT zipfile(name,mode,mtime,data) ...
+** SELECT zipfile(name,mode,mtime,data,method) ...
+*/
+void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
+ ZipfileCtx *p; /* Aggregate function context */
+ ZipfileEntry e; /* New entry to add to zip archive */
+
+ sqlite3_value *pName = 0;
+ sqlite3_value *pMode = 0;
+ sqlite3_value *pMtime = 0;
+ sqlite3_value *pData = 0;
+ sqlite3_value *pMethod = 0;
+
+ int bIsDir = 0;
+ u32 mode;
+ int rc = SQLITE_OK;
+ char *zErr = 0;
+
+ int iMethod = -1; /* Compression method to use (0 or 8) */
+
+ const u8 *aData = 0; /* Possibly compressed data for new entry */
+ int nData = 0; /* Size of aData[] in bytes */
+ int szUncompressed = 0; /* Size of data before compression */
+ u8 *aFree = 0; /* Free this before returning */
+ u32 iCrc32 = 0; /* crc32 of uncompressed data */
+
+ char *zName = 0; /* Path (name) of new entry */
+ int nName = 0; /* Size of zName in bytes */
+ char *zFree = 0; /* Free this before returning */
+ int nByte;
+
+ memset(&e, 0, sizeof(e));
+ p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
+ if( p==0 ) return;
+
+ /* Martial the arguments into stack variables */
+ if( nVal!=2 && nVal!=4 && nVal!=5 ){
+ zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
+ rc = SQLITE_ERROR;
+ goto zipfile_step_out;
+ }
+ pName = apVal[0];
+ if( nVal==2 ){
+ pData = apVal[1];
+ }else{
+ pMode = apVal[1];
+ pMtime = apVal[2];
+ pData = apVal[3];
+ if( nVal==5 ){
+ pMethod = apVal[4];
+ }
+ }
+
+ /* Check that the 'name' parameter looks ok. */
+ zName = (char*)sqlite3_value_text(pName);
+ nName = sqlite3_value_bytes(pName);
+ if( zName==0 ){
+ zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
+ rc = SQLITE_ERROR;
+ goto zipfile_step_out;
+ }
+
+ /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
+ ** deflate compression) or NULL (choose automatically). */
+ if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
+ iMethod = (int)sqlite3_value_int64(pMethod);
+ if( iMethod!=0 && iMethod!=8 ){
+ zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
+ rc = SQLITE_ERROR;
+ goto zipfile_step_out;
+ }
+ }
+
+ /* Now inspect the data. If this is NULL, then the new entry must be a
+ ** directory. Otherwise, figure out whether or not the data should
+ ** be deflated or simply stored in the zip archive. */
+ if( sqlite3_value_type(pData)==SQLITE_NULL ){
+ bIsDir = 1;
+ iMethod = 0;
+ }else{
+ aData = sqlite3_value_blob(pData);
+ szUncompressed = nData = sqlite3_value_bytes(pData);
+ iCrc32 = crc32(0, aData, nData);
+ if( iMethod<0 || iMethod==8 ){
+ int nOut = 0;
+ rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
+ if( rc!=SQLITE_OK ){
+ goto zipfile_step_out;
+ }
+ if( iMethod==8 || nOut<nData ){
+ aData = aFree;
+ nData = nOut;
+ iMethod = 8;
+ }else{
+ iMethod = 0;
+ }
+ }
+ }
+
+ /* Decode the "mode" argument. */
+ rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
+ if( rc ) goto zipfile_step_out;
+
+ /* Decode the "mtime" argument. */
+ e.mUnixTime = zipfileGetTime(pMtime);
+
+ /* If this is a directory entry, ensure that there is exactly one '/'
+ ** at the end of the path. Or, if this is not a directory and the path
+ ** ends in '/' it is an error. */
+ if( bIsDir==0 ){
+ if( zName[nName-1]=='/' ){
+ zErr = sqlite3_mprintf("non-directory name must not end with /");
+ rc = SQLITE_ERROR;
+ goto zipfile_step_out;
+ }
+ }else{
+ if( zName[nName-1]!='/' ){
+ zName = zFree = sqlite3_mprintf("%s/", zName);
+ nName++;
+ if( zName==0 ){
+ rc = SQLITE_NOMEM;
+ goto zipfile_step_out;
+ }
+ }else{
+ while( nName>1 && zName[nName-2]=='/' ) nName--;
+ }
+ }
+
+ /* Assemble the ZipfileEntry object for the new zip archive entry */
+ e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
+ e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
+ e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
+ e.cds.iCompression = (u16)iMethod;
+ zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
+ e.cds.crc32 = iCrc32;
+ e.cds.szCompressed = nData;
+ e.cds.szUncompressed = szUncompressed;
+ e.cds.iExternalAttr = (mode<<16);
+ e.cds.iOffset = p->body.n;
+ e.cds.nFile = (u16)nName;
+ e.cds.zFile = zName;
+
+ /* Append the LFH to the body of the new archive */
+ nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
+ if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
+ p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
+
+ /* Append the data to the body of the new archive */
+ if( nData>0 ){
+ if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
+ memcpy(&p->body.a[p->body.n], aData, nData);
+ p->body.n += nData;
+ }
+
+ /* Append the CDS record to the directory of the new archive */
+ nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
+ if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
+ p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
+
+ /* Increment the count of entries in the archive */
+ p->nEntry++;
+
+ zipfile_step_out:
+ sqlite3_free(aFree);
+ sqlite3_free(zFree);
+ if( rc ){
+ if( zErr ){
+ sqlite3_result_error(pCtx, zErr, -1);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ }
+ sqlite3_free(zErr);
+}
+
+/*
+** xFinalize() callback for zipfile aggregate function.
+*/
+void zipfileFinal(sqlite3_context *pCtx){
+ ZipfileCtx *p;
+ ZipfileEOCD eocd;
+ int nZip;
+ u8 *aZip;
+
+ p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
+ if( p==0 ) return;
+ if( p->nEntry>0 ){
+ memset(&eocd, 0, sizeof(eocd));
+ eocd.nEntry = (u16)p->nEntry;
+ eocd.nEntryTotal = (u16)p->nEntry;
+ eocd.nSize = p->cds.n;
+ eocd.iOffset = p->body.n;
+
+ nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
+ aZip = (u8*)sqlite3_malloc(nZip);
+ if( aZip==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ memcpy(aZip, p->body.a, p->body.n);
+ memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
+ zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
+ sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree);
+ }
+ }
+
+ sqlite3_free(p->body.a);
+ sqlite3_free(p->cds.a);
+}
+
+
+/*
+** Register the "zipfile" virtual table.
+*/
+static int zipfileRegister(sqlite3 *db){
+ static const sqlite3_module zipfileModule = {
+ 1, /* iVersion */
+ zipfileConnect, /* xCreate */
+ zipfileConnect, /* xConnect */
+ zipfileBestIndex, /* xBestIndex */
+ zipfileDisconnect, /* xDisconnect */
+ zipfileDisconnect, /* xDestroy */
+ zipfileOpen, /* xOpen - open a cursor */
+ zipfileClose, /* xClose - close a cursor */
+ zipfileFilter, /* xFilter - configure scan constraints */
+ zipfileNext, /* xNext - advance a cursor */
+ zipfileEof, /* xEof - check for end of scan */
+ zipfileColumn, /* xColumn - read data */
+ 0, /* xRowid - read data */
+ zipfileUpdate, /* xUpdate */
+ zipfileBegin, /* xBegin */
+ 0, /* xSync */
+ zipfileCommit, /* xCommit */
+ zipfileRollback, /* xRollback */
+ zipfileFindFunction, /* xFindMethod */
+ 0, /* xRename */
+ };
+
+ int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
+ if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0,
+ zipfileStep, zipfileFinal
+ );
+ }
+ return rc;
+}
+#else /* SQLITE_OMIT_VIRTUALTABLE */
+# define zipfileRegister(x) SQLITE_OK
+#endif
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_zipfile_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return zipfileRegister(db);
+}
+
+/************************* End ../ext/misc/zipfile.c ********************/
+/************************* Begin ../ext/misc/sqlar.c ******************/
+/*
+** 2017-12-17
+**
+** 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.
+**
+******************************************************************************
+**
+** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
+** for working with sqlar archives and used by the shell tool's built-in
+** sqlar support.
+*/
+SQLITE_EXTENSION_INIT1
+#include <zlib.h>
+
+/*
+** Implementation of the "sqlar_compress(X)" SQL function.
+**
+** If the type of X is SQLITE_BLOB, and compressing that blob using
+** zlib utility function compress() yields a smaller blob, return the
+** compressed blob. Otherwise, return a copy of X.
+**
+** SQLar uses the "zlib format" for compressed content. The zlib format
+** contains a two-byte identification header and a four-byte checksum at
+** the end. This is different from ZIP which uses the raw deflate format.
+**
+** Future enhancements to SQLar might add support for new compression formats.
+** If so, those new formats will be identified by alternative headers in the
+** compressed data.
+*/
+static void sqlarCompressFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ assert( argc==1 );
+ if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
+ const Bytef *pData = sqlite3_value_blob(argv[0]);
+ uLong nData = sqlite3_value_bytes(argv[0]);
+ uLongf nOut = compressBound(nData);
+ Bytef *pOut;
+
+ pOut = (Bytef*)sqlite3_malloc(nOut);
+ if( pOut==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }else{
+ if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
+ sqlite3_result_error(context, "error in compress()", -1);
+ }else if( nOut<nData ){
+ sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_value(context, argv[0]);
+ }
+ sqlite3_free(pOut);
+ }
+ }else{
+ sqlite3_result_value(context, argv[0]);
+ }
+}
+
+/*
+** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
+**
+** Parameter SZ is interpreted as an integer. If it is less than or
+** equal to zero, then this function returns a copy of X. Or, if
+** SZ is equal to the size of X when interpreted as a blob, also
+** return a copy of X. Otherwise, decompress blob X using zlib
+** utility function uncompress() and return the results (another
+** blob).
+*/
+static void sqlarUncompressFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ uLong nData;
+ uLongf sz;
+
+ assert( argc==2 );
+ sz = sqlite3_value_int(argv[1]);
+
+ if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
+ sqlite3_result_value(context, argv[0]);
+ }else{
+ const Bytef *pData= sqlite3_value_blob(argv[0]);
+ Bytef *pOut = sqlite3_malloc(sz);
+ if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
+ sqlite3_result_error(context, "error in uncompress()", -1);
+ }else{
+ sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
+ }
+ sqlite3_free(pOut);
+ }
+}
+
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_sqlar_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ int rc = SQLITE_OK;
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
+ sqlarCompressFunc, 0, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
+ sqlarUncompressFunc, 0, 0);
+ }
+ return rc;
+}
+
+/************************* End ../ext/misc/sqlar.c ********************/
+#endif
+/************************* Begin ../ext/expert/sqlite3expert.h ******************/
+/*
+** 2017 April 07
+**
+** 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.
+**
+*************************************************************************
+*/
+
+
+
+typedef struct sqlite3expert sqlite3expert;
+
+/*
+** Create a new sqlite3expert object.
+**
+** If successful, a pointer to the new object is returned and (*pzErr) set
+** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to
+** an English-language error message. In this case it is the responsibility
+** of the caller to eventually free the error message buffer using
+** sqlite3_free().
+*/
+sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr);
+
+/*
+** Configure an sqlite3expert object.
+**
+** EXPERT_CONFIG_SAMPLE:
+** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for
+** each candidate index. This involves scanning and sorting the entire
+** contents of each user database table once for each candidate index
+** associated with the table. For large databases, this can be
+** prohibitively slow. This option allows the sqlite3expert object to
+** be configured so that sqlite_stat1 data is instead generated based on a
+** subset of each table, or so that no sqlite_stat1 data is used at all.
+**
+** A single integer argument is passed to this option. If the value is less
+** than or equal to zero, then no sqlite_stat1 data is generated or used by
+** the analysis - indexes are recommended based on the database schema only.
+** Or, if the value is 100 or greater, complete sqlite_stat1 data is
+** generated for each candidate index (this is the default). Finally, if the
+** value falls between 0 and 100, then it represents the percentage of user
+** table rows that should be considered when generating sqlite_stat1 data.
+**
+** Examples:
+**
+** // Do not generate any sqlite_stat1 data
+** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0);
+**
+** // Generate sqlite_stat1 data based on 10% of the rows in each table.
+** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10);
+*/
+int sqlite3_expert_config(sqlite3expert *p, int op, ...);
+
+#define EXPERT_CONFIG_SAMPLE 1 /* int */
+
+/*
+** Specify zero or more SQL statements to be included in the analysis.
+**
+** Buffer zSql must contain zero or more complete SQL statements. This
+** function parses all statements contained in the buffer and adds them
+** to the internal list of statements to analyze. If successful, SQLITE_OK
+** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example
+** due to a error in the SQL - an SQLite error code is returned and (*pzErr)
+** may be set to point to an English language error message. In this case
+** the caller is responsible for eventually freeing the error message buffer
+** using sqlite3_free().
+**
+** If an error does occur while processing one of the statements in the
+** buffer passed as the second argument, none of the statements in the
+** buffer are added to the analysis.
+**
+** This function must be called before sqlite3_expert_analyze(). If a call
+** to this function is made on an sqlite3expert object that has already
+** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned
+** immediately and no statements are added to the analysis.
+*/
+int sqlite3_expert_sql(
+ sqlite3expert *p, /* From a successful sqlite3_expert_new() */
+ const char *zSql, /* SQL statement(s) to add */
+ char **pzErr /* OUT: Error message (if any) */
+);
+
+
+/*
+** This function is called after the sqlite3expert object has been configured
+** with all SQL statements using sqlite3_expert_sql() to actually perform
+** the analysis. Once this function has been called, it is not possible to
+** add further SQL statements to the analysis.
+**
+** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if
+** an error occurs, an SQLite error code is returned and (*pzErr) set to
+** point to a buffer containing an English language error message. In this
+** case it is the responsibility of the caller to eventually free the buffer
+** using sqlite3_free().
+**
+** If an error does occur within this function, the sqlite3expert object
+** is no longer useful for any purpose. At that point it is no longer
+** possible to add further SQL statements to the object or to re-attempt
+** the analysis. The sqlite3expert object must still be freed using a call
+** sqlite3_expert_destroy().
+*/
+int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr);
+
+/*
+** Return the total number of statements loaded using sqlite3_expert_sql().
+** The total number of SQL statements may be different from the total number
+** to calls to sqlite3_expert_sql().
+*/
+int sqlite3_expert_count(sqlite3expert*);
+
+/*
+** Return a component of the report.
+**
+** This function is called after sqlite3_expert_analyze() to extract the
+** results of the analysis. Each call to this function returns either a
+** NULL pointer or a pointer to a buffer containing a nul-terminated string.
+** The value passed as the third argument must be one of the EXPERT_REPORT_*
+** #define constants defined below.
+**
+** For some EXPERT_REPORT_* parameters, the buffer returned contains
+** information relating to a specific SQL statement. In these cases that
+** SQL statement is identified by the value passed as the second argument.
+** SQL statements are numbered from 0 in the order in which they are parsed.
+** If an out-of-range value (less than zero or equal to or greater than the
+** value returned by sqlite3_expert_count()) is passed as the second argument
+** along with such an EXPERT_REPORT_* parameter, NULL is always returned.
+**
+** EXPERT_REPORT_SQL:
+** Return the text of SQL statement iStmt.
+**
+** EXPERT_REPORT_INDEXES:
+** Return a buffer containing the CREATE INDEX statements for all recommended
+** indexes for statement iStmt. If there are no new recommeded indexes, NULL
+** is returned.
+**
+** EXPERT_REPORT_PLAN:
+** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query
+** iStmt after the proposed indexes have been added to the database schema.
+**
+** EXPERT_REPORT_CANDIDATES:
+** Return a pointer to a buffer containing the CREATE INDEX statements
+** for all indexes that were tested (for all SQL statements). The iStmt
+** parameter is ignored for EXPERT_REPORT_CANDIDATES calls.
+*/
+const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
+
+/*
+** Values for the third argument passed to sqlite3_expert_report().
+*/
+#define EXPERT_REPORT_SQL 1
+#define EXPERT_REPORT_INDEXES 2
+#define EXPERT_REPORT_PLAN 3
+#define EXPERT_REPORT_CANDIDATES 4
+
+/*
+** Free an (sqlite3expert*) handle and all associated resources. There
+** should be one call to this function for each successful call to
+** sqlite3-expert_new().
+*/
+void sqlite3_expert_destroy(sqlite3expert*);
+
+
+
+/************************* End ../ext/expert/sqlite3expert.h ********************/
+/************************* Begin ../ext/expert/sqlite3expert.c ******************/
+/*
+** 2017 April 09
+**
+** 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.
+**
+*************************************************************************
+*/
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+
+/* typedef sqlite3_int64 i64; */
+/* typedef sqlite3_uint64 u64; */
+
+typedef struct IdxColumn IdxColumn;
+typedef struct IdxConstraint IdxConstraint;
+typedef struct IdxScan IdxScan;
+typedef struct IdxStatement IdxStatement;
+typedef struct IdxTable IdxTable;
+typedef struct IdxWrite IdxWrite;
+
+#define STRLEN (int)strlen
+
+/*
+** A temp table name that we assume no user database will actually use.
+** If this assumption proves incorrect triggers on the table with the
+** conflicting name will be ignored.
+*/
+#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
+
+/*
+** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
+** any other type of single-ended range constraint on a column).
+**
+** pLink:
+** Used to temporarily link IdxConstraint objects into lists while
+** creating candidate indexes.
+*/
+struct IdxConstraint {
+ char *zColl; /* Collation sequence */
+ int bRange; /* True for range, false for eq */
+ int iCol; /* Constrained table column */
+ int bFlag; /* Used by idxFindCompatible() */
+ int bDesc; /* True if ORDER BY <expr> DESC */
+ IdxConstraint *pNext; /* Next constraint in pEq or pRange list */
+ IdxConstraint *pLink; /* See above */
+};
+
+/*
+** A single scan of a single table.
+*/
+struct IdxScan {
+ IdxTable *pTab; /* Associated table object */
+ int iDb; /* Database containing table zTable */
+ i64 covering; /* Mask of columns required for cov. index */
+ IdxConstraint *pOrder; /* ORDER BY columns */
+ IdxConstraint *pEq; /* List of == constraints */
+ IdxConstraint *pRange; /* List of < constraints */
+ IdxScan *pNextScan; /* Next IdxScan object for same analysis */
+};
+
+/*
+** Information regarding a single database table. Extracted from
+** "PRAGMA table_info" by function idxGetTableInfo().
+*/
+struct IdxColumn {
+ char *zName;
+ char *zColl;
+ int iPk;
+};
+struct IdxTable {
+ int nCol;
+ char *zName; /* Table name */
+ IdxColumn *aCol;
+ IdxTable *pNext; /* Next table in linked list of all tables */
+};
+
+/*
+** An object of the following type is created for each unique table/write-op
+** seen. The objects are stored in a singly-linked list beginning at
+** sqlite3expert.pWrite.
+*/
+struct IdxWrite {
+ IdxTable *pTab;
+ int eOp; /* SQLITE_UPDATE, DELETE or INSERT */
+ IdxWrite *pNext;
+};
+
+/*
+** Each statement being analyzed is represented by an instance of this
+** structure.
+*/
+struct IdxStatement {
+ int iId; /* Statement number */
+ char *zSql; /* SQL statement */
+ char *zIdx; /* Indexes */
+ char *zEQP; /* Plan */
+ IdxStatement *pNext;
+};
+
+
+/*
+** A hash table for storing strings. With space for a payload string
+** with each entry. Methods are:
+**
+** idxHashInit()
+** idxHashClear()
+** idxHashAdd()
+** idxHashSearch()
+*/
+#define IDX_HASH_SIZE 1023
+typedef struct IdxHashEntry IdxHashEntry;
+typedef struct IdxHash IdxHash;
+struct IdxHashEntry {
+ char *zKey; /* nul-terminated key */
+ char *zVal; /* nul-terminated value string */
+ char *zVal2; /* nul-terminated value string 2 */
+ IdxHashEntry *pHashNext; /* Next entry in same hash bucket */
+ IdxHashEntry *pNext; /* Next entry in hash */
+};
+struct IdxHash {
+ IdxHashEntry *pFirst;
+ IdxHashEntry *aHash[IDX_HASH_SIZE];
+};
+
+/*
+** sqlite3expert object.
+*/
+struct sqlite3expert {
+ int iSample; /* Percentage of tables to sample for stat1 */
+ sqlite3 *db; /* User database */
+ sqlite3 *dbm; /* In-memory db for this analysis */
+ sqlite3 *dbv; /* Vtab schema for this analysis */
+ IdxTable *pTable; /* List of all IdxTable objects */
+ IdxScan *pScan; /* List of scan objects */
+ IdxWrite *pWrite; /* List of write objects */
+ IdxStatement *pStatement; /* List of IdxStatement objects */
+ int bRun; /* True once analysis has run */
+ char **pzErrmsg;
+ int rc; /* Error code from whereinfo hook */
+ IdxHash hIdx; /* Hash containing all candidate indexes */
+ char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */
+};
+
+
+/*
+** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
+** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
+*/
+static void *idxMalloc(int *pRc, int nByte){
+ void *pRet;
+ assert( *pRc==SQLITE_OK );
+ assert( nByte>0 );
+ pRet = sqlite3_malloc(nByte);
+ if( pRet ){
+ memset(pRet, 0, nByte);
+ }else{
+ *pRc = SQLITE_NOMEM;
+ }
+ return pRet;
+}
+
+/*
+** Initialize an IdxHash hash table.
+*/
+static void idxHashInit(IdxHash *pHash){
+ memset(pHash, 0, sizeof(IdxHash));
+}
+
+/*
+** Reset an IdxHash hash table.
+*/
+static void idxHashClear(IdxHash *pHash){
+ int i;
+ for(i=0; i<IDX_HASH_SIZE; i++){
+ IdxHashEntry *pEntry;
+ IdxHashEntry *pNext;
+ for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
+ pNext = pEntry->pHashNext;
+ sqlite3_free(pEntry->zVal2);
+ sqlite3_free(pEntry);
+ }
+ }
+ memset(pHash, 0, sizeof(IdxHash));
+}
+
+/*
+** Return the index of the hash bucket that the string specified by the
+** arguments to this function belongs.
+*/
+static int idxHashString(const char *z, int n){
+ unsigned int ret = 0;
+ int i;
+ for(i=0; i<n; i++){
+ ret += (ret<<3) + (unsigned char)(z[i]);
+ }
+ return (int)(ret % IDX_HASH_SIZE);
+}
+
+/*
+** If zKey is already present in the hash table, return non-zero and do
+** nothing. Otherwise, add an entry with key zKey and payload string zVal to
+** the hash table passed as the second argument.
+*/
+static int idxHashAdd(
+ int *pRc,
+ IdxHash *pHash,
+ const char *zKey,
+ const char *zVal
+){
+ int nKey = STRLEN(zKey);
+ int iHash = idxHashString(zKey, nKey);
+ int nVal = (zVal ? STRLEN(zVal) : 0);
+ IdxHashEntry *pEntry;
+ assert( iHash>=0 );
+ for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
+ if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
+ return 1;
+ }
+ }
+ pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
+ if( pEntry ){
+ pEntry->zKey = (char*)&pEntry[1];
+ memcpy(pEntry->zKey, zKey, nKey);
+ if( zVal ){
+ pEntry->zVal = &pEntry->zKey[nKey+1];
+ memcpy(pEntry->zVal, zVal, nVal);
+ }
+ pEntry->pHashNext = pHash->aHash[iHash];
+ pHash->aHash[iHash] = pEntry;
+
+ pEntry->pNext = pHash->pFirst;
+ pHash->pFirst = pEntry;
+ }
+ return 0;
+}
+
+/*
+** If zKey/nKey is present in the hash table, return a pointer to the
+** hash-entry object.
+*/
+static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
+ int iHash;
+ IdxHashEntry *pEntry;
+ if( nKey<0 ) nKey = STRLEN(zKey);
+ iHash = idxHashString(zKey, nKey);
+ assert( iHash>=0 );
+ for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
+ if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
+ return pEntry;
+ }
+ }
+ return 0;
+}
+
+/*
+** If the hash table contains an entry with a key equal to the string
+** passed as the final two arguments to this function, return a pointer
+** to the payload string. Otherwise, if zKey/nKey is not present in the
+** hash table, return NULL.
+*/
+static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
+ IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
+ if( pEntry ) return pEntry->zVal;
+ return 0;
+}
+
+/*
+** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
+** variable to point to a copy of nul-terminated string zColl.
+*/
+static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
+ IdxConstraint *pNew;
+ int nColl = STRLEN(zColl);
+
+ assert( *pRc==SQLITE_OK );
+ pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
+ if( pNew ){
+ pNew->zColl = (char*)&pNew[1];
+ memcpy(pNew->zColl, zColl, nColl+1);
+ }
+ return pNew;
+}
+
+/*
+** An error associated with database handle db has just occurred. Pass
+** the error message to callback function xOut.
+*/
+static void idxDatabaseError(
+ sqlite3 *db, /* Database handle */
+ char **pzErrmsg /* Write error here */
+){
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+}
+
+/*
+** Prepare an SQL statement.
+*/
+static int idxPrepareStmt(
+ sqlite3 *db, /* Database handle to compile against */
+ sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */
+ char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */
+ const char *zSql /* SQL statement to compile */
+){
+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
+ if( rc!=SQLITE_OK ){
+ *ppStmt = 0;
+ idxDatabaseError(db, pzErrmsg);
+ }
+ return rc;
+}
+
+/*
+** Prepare an SQL statement using the results of a printf() formatting.
+*/
+static int idxPrintfPrepareStmt(
+ sqlite3 *db, /* Database handle to compile against */
+ sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */
+ char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */
+ const char *zFmt, /* printf() format of SQL statement */
+ ... /* Trailing printf() arguments */
+){
+ va_list ap;
+ int rc;
+ char *zSql;
+ va_start(ap, zFmt);
+ zSql = sqlite3_vmprintf(zFmt, ap);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
+ sqlite3_free(zSql);
+ }
+ va_end(ap);
+ return rc;
+}
+
+
+/*************************************************************************
+** Beginning of virtual table implementation.
+*/
+typedef struct ExpertVtab ExpertVtab;
+struct ExpertVtab {
+ sqlite3_vtab base;
+ IdxTable *pTab;
+ sqlite3expert *pExpert;
+};
+
+typedef struct ExpertCsr ExpertCsr;
+struct ExpertCsr {
+ sqlite3_vtab_cursor base;
+ sqlite3_stmt *pData;
+};
+
+static char *expertDequote(const char *zIn){
+ int n = STRLEN(zIn);
+ char *zRet = sqlite3_malloc(n);
+
+ assert( zIn[0]=='\'' );
+ assert( zIn[n-1]=='\'' );
+
+ if( zRet ){
+ int iOut = 0;
+ int iIn = 0;
+ for(iIn=1; iIn<(n-1); iIn++){
+ if( zIn[iIn]=='\'' ){
+ assert( zIn[iIn+1]=='\'' );
+ iIn++;
+ }
+ zRet[iOut++] = zIn[iIn];
+ }
+ zRet[iOut] = '\0';
+ }
+
+ return zRet;
+}
+
+/*
+** This function is the implementation of both the xConnect and xCreate
+** methods of the r-tree virtual table.
+**
+** argv[0] -> module name
+** argv[1] -> database name
+** argv[2] -> table name
+** argv[...] -> column names...
+*/
+static int expertConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ sqlite3expert *pExpert = (sqlite3expert*)pAux;
+ ExpertVtab *p = 0;
+ int rc;
+
+ if( argc!=4 ){
+ *pzErr = sqlite3_mprintf("internal error!");
+ rc = SQLITE_ERROR;
+ }else{
+ char *zCreateTable = expertDequote(argv[3]);
+ if( zCreateTable ){
+ rc = sqlite3_declare_vtab(db, zCreateTable);
+ if( rc==SQLITE_OK ){
+ p = idxMalloc(&rc, sizeof(ExpertVtab));
+ }
+ if( rc==SQLITE_OK ){
+ p->pExpert = pExpert;
+ p->pTab = pExpert->pTable;
+ assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
+ }
+ sqlite3_free(zCreateTable);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+
+ *ppVtab = (sqlite3_vtab*)p;
+ return rc;
+}
+
+static int expertDisconnect(sqlite3_vtab *pVtab){
+ ExpertVtab *p = (ExpertVtab*)pVtab;
+ sqlite3_free(p);
+ return SQLITE_OK;
+}
+
+static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
+ ExpertVtab *p = (ExpertVtab*)pVtab;
+ int rc = SQLITE_OK;
+ int n = 0;
+ IdxScan *pScan;
+ const int opmask =
+ SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
+ SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
+ SQLITE_INDEX_CONSTRAINT_LE;
+
+ pScan = idxMalloc(&rc, sizeof(IdxScan));
+ if( pScan ){
+ int i;
+
+ /* Link the new scan object into the list */
+ pScan->pTab = p->pTab;
+ pScan->pNextScan = p->pExpert->pScan;
+ p->pExpert->pScan = pScan;
+
+ /* Add the constraints to the IdxScan object */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
+ if( pCons->usable
+ && pCons->iColumn>=0
+ && p->pTab->aCol[pCons->iColumn].iPk==0
+ && (pCons->op & opmask)
+ ){
+ IdxConstraint *pNew;
+ const char *zColl = sqlite3_vtab_collation(pIdxInfo, i);
+ pNew = idxNewConstraint(&rc, zColl);
+ if( pNew ){
+ pNew->iCol = pCons->iColumn;
+ if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ pNew->pNext = pScan->pEq;
+ pScan->pEq = pNew;
+ }else{
+ pNew->bRange = 1;
+ pNew->pNext = pScan->pRange;
+ pScan->pRange = pNew;
+ }
+ }
+ n++;
+ pIdxInfo->aConstraintUsage[i].argvIndex = n;
+ }
+ }
+
+ /* Add the ORDER BY to the IdxScan object */
+ for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
+ int iCol = pIdxInfo->aOrderBy[i].iColumn;
+ if( iCol>=0 ){
+ IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
+ if( pNew ){
+ pNew->iCol = iCol;
+ pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
+ pNew->pNext = pScan->pOrder;
+ pNew->pLink = pScan->pOrder;
+ pScan->pOrder = pNew;
+ n++;
+ }
+ }
+ }
+ }
+
+ pIdxInfo->estimatedCost = 1000000.0 / (n+1);
+ return rc;
+}
+
+static int expertUpdate(
+ sqlite3_vtab *pVtab,
+ int nData,
+ sqlite3_value **azData,
+ sqlite_int64 *pRowid
+){
+ (void)pVtab;
+ (void)nData;
+ (void)azData;
+ (void)pRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Virtual table module xOpen method.
+*/
+static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+ int rc = SQLITE_OK;
+ ExpertCsr *pCsr;
+ (void)pVTab;
+ pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
+ *ppCursor = (sqlite3_vtab_cursor*)pCsr;
+ return rc;
+}
+
+/*
+** Virtual table module xClose method.
+*/
+static int expertClose(sqlite3_vtab_cursor *cur){
+ ExpertCsr *pCsr = (ExpertCsr*)cur;
+ sqlite3_finalize(pCsr->pData);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/*
+** Virtual table module xEof method.
+**
+** Return non-zero if the cursor does not currently point to a valid
+** record (i.e if the scan has finished), or zero otherwise.
+*/
+static int expertEof(sqlite3_vtab_cursor *cur){
+ ExpertCsr *pCsr = (ExpertCsr*)cur;
+ return pCsr->pData==0;
+}
+
+/*
+** Virtual table module xNext method.
+*/
+static int expertNext(sqlite3_vtab_cursor *cur){
+ ExpertCsr *pCsr = (ExpertCsr*)cur;
+ int rc = SQLITE_OK;
+
+ assert( pCsr->pData );
+ rc = sqlite3_step(pCsr->pData);
+ if( rc!=SQLITE_ROW ){
+ rc = sqlite3_finalize(pCsr->pData);
+ pCsr->pData = 0;
+ }else{
+ rc = SQLITE_OK;
+ }
+
+ return rc;
+}
+
+/*
+** Virtual table module xRowid method.
+*/
+static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ (void)cur;
+ *pRowid = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Virtual table module xColumn method.
+*/
+static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
+ ExpertCsr *pCsr = (ExpertCsr*)cur;
+ sqlite3_value *pVal;
+ pVal = sqlite3_column_value(pCsr->pData, i);
+ if( pVal ){
+ sqlite3_result_value(ctx, pVal);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Virtual table module xFilter method.
+*/
+static int expertFilter(
+ sqlite3_vtab_cursor *cur,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ ExpertCsr *pCsr = (ExpertCsr*)cur;
+ ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
+ sqlite3expert *pExpert = pVtab->pExpert;
+ int rc;
+
+ (void)idxNum;
+ (void)idxStr;
+ (void)argc;
+ (void)argv;
+ rc = sqlite3_finalize(pCsr->pData);
+ pCsr->pData = 0;
+ if( rc==SQLITE_OK ){
+ rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
+ "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
+ );
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = expertNext(cur);
+ }
+ return rc;
+}
+
+static int idxRegisterVtab(sqlite3expert *p){
+ static const sqlite3_module expertModule = {
+ 2, /* iVersion */
+ expertConnect, /* xCreate - create a table */
+ expertConnect, /* xConnect - connect to an existing table */
+ expertBestIndex, /* xBestIndex - Determine search strategy */
+ expertDisconnect, /* xDisconnect - Disconnect from a table */
+ expertDisconnect, /* xDestroy - Drop a table */
+ expertOpen, /* xOpen - open a cursor */
+ expertClose, /* xClose - close a cursor */
+ expertFilter, /* xFilter - configure scan constraints */
+ expertNext, /* xNext - advance a cursor */
+ expertEof, /* xEof */
+ expertColumn, /* xColumn - read data */
+ expertRowid, /* xRowid - read data */
+ expertUpdate, /* xUpdate - write data */
+ 0, /* xBegin - begin transaction */
+ 0, /* xSync - sync transaction */
+ 0, /* xCommit - commit transaction */
+ 0, /* xRollback - rollback transaction */
+ 0, /* xFindFunction - function overloading */
+ 0, /* xRename - rename the table */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
+ };
+
+ return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
+}
+/*
+** End of virtual table implementation.
+*************************************************************************/
+/*
+** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
+** is called, set it to the return value of sqlite3_finalize() before
+** returning. Otherwise, discard the sqlite3_finalize() return value.
+*/
+static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
+ int rc = sqlite3_finalize(pStmt);
+ if( *pRc==SQLITE_OK ) *pRc = rc;
+}
+
+/*
+** Attempt to allocate an IdxTable structure corresponding to table zTab
+** in the main database of connection db. If successful, set (*ppOut) to
+** point to the new object and return SQLITE_OK. Otherwise, return an
+** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
+** set to point to an error string.
+**
+** It is the responsibility of the caller to eventually free either the
+** IdxTable object or error message using sqlite3_free().
+*/
+static int idxGetTableInfo(
+ sqlite3 *db, /* Database connection to read details from */
+ const char *zTab, /* Table name */
+ IdxTable **ppOut, /* OUT: New object (if successful) */
+ char **pzErrmsg /* OUT: Error message (if not) */
+){
+ sqlite3_stmt *p1 = 0;
+ int nCol = 0;
+ int nTab = STRLEN(zTab);
+ int nByte = sizeof(IdxTable) + nTab + 1;
+ IdxTable *pNew = 0;
+ int rc, rc2;
+ char *pCsr = 0;
+
+ rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
+ const char *zCol = (const char*)sqlite3_column_text(p1, 1);
+ nByte += 1 + STRLEN(zCol);
+ rc = sqlite3_table_column_metadata(
+ db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
+ );
+ nByte += 1 + STRLEN(zCol);
+ nCol++;
+ }
+ rc2 = sqlite3_reset(p1);
+ if( rc==SQLITE_OK ) rc = rc2;
+
+ nByte += sizeof(IdxColumn) * nCol;
+ if( rc==SQLITE_OK ){
+ pNew = idxMalloc(&rc, nByte);
+ }
+ if( rc==SQLITE_OK ){
+ pNew->aCol = (IdxColumn*)&pNew[1];
+ pNew->nCol = nCol;
+ pCsr = (char*)&pNew->aCol[nCol];
+ }
+
+ nCol = 0;
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
+ const char *zCol = (const char*)sqlite3_column_text(p1, 1);
+ int nCopy = STRLEN(zCol) + 1;
+ pNew->aCol[nCol].zName = pCsr;
+ pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
+ memcpy(pCsr, zCol, nCopy);
+ pCsr += nCopy;
+
+ rc = sqlite3_table_column_metadata(
+ db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
+ );
+ if( rc==SQLITE_OK ){
+ nCopy = STRLEN(zCol) + 1;
+ pNew->aCol[nCol].zColl = pCsr;
+ memcpy(pCsr, zCol, nCopy);
+ pCsr += nCopy;
+ }
+
+ nCol++;
+ }
+ idxFinalize(&rc, p1);
+
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(pNew);
+ pNew = 0;
+ }else{
+ pNew->zName = pCsr;
+ memcpy(pNew->zName, zTab, nTab+1);
+ }
+
+ *ppOut = pNew;
+ return rc;
+}
+
+/*
+** This function is a no-op if *pRc is set to anything other than
+** SQLITE_OK when it is called.
+**
+** If *pRc is initially set to SQLITE_OK, then the text specified by
+** the printf() style arguments is appended to zIn and the result returned
+** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
+** zIn before returning.
+*/
+static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
+ va_list ap;
+ char *zAppend = 0;
+ char *zRet = 0;
+ int nIn = zIn ? STRLEN(zIn) : 0;
+ int nAppend = 0;
+ va_start(ap, zFmt);
+ if( *pRc==SQLITE_OK ){
+ zAppend = sqlite3_vmprintf(zFmt, ap);
+ if( zAppend ){
+ nAppend = STRLEN(zAppend);
+ zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
+ }
+ if( zAppend && zRet ){
+ if( nIn ) memcpy(zRet, zIn, nIn);
+ memcpy(&zRet[nIn], zAppend, nAppend+1);
+ }else{
+ sqlite3_free(zRet);
+ zRet = 0;
+ *pRc = SQLITE_NOMEM;
+ }
+ sqlite3_free(zAppend);
+ sqlite3_free(zIn);
+ }
+ va_end(ap);
+ return zRet;
+}
+
+/*
+** Return true if zId must be quoted in order to use it as an SQL
+** identifier, or false otherwise.
+*/
+static int idxIdentifierRequiresQuotes(const char *zId){
+ int i;
+ for(i=0; zId[i]; i++){
+ if( !(zId[i]=='_')
+ && !(zId[i]>='0' && zId[i]<='9')
+ && !(zId[i]>='a' && zId[i]<='z')
+ && !(zId[i]>='A' && zId[i]<='Z')
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** This function appends an index column definition suitable for constraint
+** pCons to the string passed as zIn and returns the result.
+*/
+static char *idxAppendColDefn(
+ int *pRc, /* IN/OUT: Error code */
+ char *zIn, /* Column defn accumulated so far */
+ IdxTable *pTab, /* Table index will be created on */
+ IdxConstraint *pCons
+){
+ char *zRet = zIn;
+ IdxColumn *p = &pTab->aCol[pCons->iCol];
+ if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
+
+ if( idxIdentifierRequiresQuotes(p->zName) ){
+ zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
+ }else{
+ zRet = idxAppendText(pRc, zRet, "%s", p->zName);
+ }
+
+ if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
+ if( idxIdentifierRequiresQuotes(pCons->zColl) ){
+ zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
+ }else{
+ zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
+ }
+ }
+
+ if( pCons->bDesc ){
+ zRet = idxAppendText(pRc, zRet, " DESC");
+ }
+ return zRet;
+}
+
+/*
+** Search database dbm for an index compatible with the one idxCreateFromCons()
+** would create from arguments pScan, pEq and pTail. If no error occurs and
+** such an index is found, return non-zero. Or, if no such index is found,
+** return zero.
+**
+** If an error occurs, set *pRc to an SQLite error code and return zero.
+*/
+static int idxFindCompatible(
+ int *pRc, /* OUT: Error code */
+ sqlite3* dbm, /* Database to search */
+ IdxScan *pScan, /* Scan for table to search for index on */
+ IdxConstraint *pEq, /* List of == constraints */
+ IdxConstraint *pTail /* List of range constraints */
+){
+ const char *zTbl = pScan->pTab->zName;
+ sqlite3_stmt *pIdxList = 0;
+ IdxConstraint *pIter;
+ int nEq = 0; /* Number of elements in pEq */
+ int rc;
+
+ /* Count the elements in list pEq */
+ for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
+
+ rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
+ while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
+ int bMatch = 1;
+ IdxConstraint *pT = pTail;
+ sqlite3_stmt *pInfo = 0;
+ const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
+
+ /* Zero the IdxConstraint.bFlag values in the pEq list */
+ for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
+
+ rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
+ while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
+ int iIdx = sqlite3_column_int(pInfo, 0);
+ int iCol = sqlite3_column_int(pInfo, 1);
+ const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
+
+ if( iIdx<nEq ){
+ for(pIter=pEq; pIter; pIter=pIter->pLink){
+ if( pIter->bFlag ) continue;
+ if( pIter->iCol!=iCol ) continue;
+ if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
+ pIter->bFlag = 1;
+ break;
+ }
+ if( pIter==0 ){
+ bMatch = 0;
+ break;
+ }
+ }else{
+ if( pT ){
+ if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
+ bMatch = 0;
+ break;
+ }
+ pT = pT->pLink;
+ }
+ }
+ }
+ idxFinalize(&rc, pInfo);
+
+ if( rc==SQLITE_OK && bMatch ){
+ sqlite3_finalize(pIdxList);
+ return 1;
+ }
+ }
+ idxFinalize(&rc, pIdxList);
+
+ *pRc = rc;
+ return 0;
+}
+
+static int idxCreateFromCons(
+ sqlite3expert *p,
+ IdxScan *pScan,
+ IdxConstraint *pEq,
+ IdxConstraint *pTail
+){
+ sqlite3 *dbm = p->dbm;
+ int rc = SQLITE_OK;
+ if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
+ IdxTable *pTab = pScan->pTab;
+ char *zCols = 0;
+ char *zIdx = 0;
+ IdxConstraint *pCons;
+ unsigned int h = 0;
+ const char *zFmt;
+
+ for(pCons=pEq; pCons; pCons=pCons->pLink){
+ zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
+ }
+ for(pCons=pTail; pCons; pCons=pCons->pLink){
+ zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
+ }
+
+ if( rc==SQLITE_OK ){
+ /* Hash the list of columns to come up with a name for the index */
+ const char *zTable = pScan->pTab->zName;
+ char *zName; /* Index name */
+ int i;
+ for(i=0; zCols[i]; i++){
+ h += ((h<<3) + zCols[i]);
+ }
+ zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
+ if( zName==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ if( idxIdentifierRequiresQuotes(zTable) ){
+ zFmt = "CREATE INDEX '%q' ON %Q(%s)";
+ }else{
+ zFmt = "CREATE INDEX %s ON %s(%s)";
+ }
+ zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
+ if( !zIdx ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
+ idxHashAdd(&rc, &p->hIdx, zName, zIdx);
+ }
+ sqlite3_free(zName);
+ sqlite3_free(zIdx);
+ }
+ }
+
+ sqlite3_free(zCols);
+ }
+ return rc;
+}
+
+/*
+** Return true if list pList (linked by IdxConstraint.pLink) contains
+** a constraint compatible with *p. Otherwise return false.
+*/
+static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
+ IdxConstraint *pCmp;
+ for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
+ if( p->iCol==pCmp->iCol ) return 1;
+ }
+ return 0;
+}
+
+static int idxCreateFromWhere(
+ sqlite3expert *p,
+ IdxScan *pScan, /* Create indexes for this scan */
+ IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */
+){
+ IdxConstraint *p1 = 0;
+ IdxConstraint *pCon;
+ int rc;
+
+ /* Gather up all the == constraints. */
+ for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
+ pCon->pLink = p1;
+ p1 = pCon;
+ }
+ }
+
+ /* Create an index using the == constraints collected above. And the
+ ** range constraint/ORDER BY terms passed in by the caller, if any. */
+ rc = idxCreateFromCons(p, pScan, p1, pTail);
+
+ /* If no range/ORDER BY passed by the caller, create a version of the
+ ** index for each range constraint. */
+ if( pTail==0 ){
+ for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
+ assert( pCon->pLink==0 );
+ if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
+ rc = idxCreateFromCons(p, pScan, p1, pCon);
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Create candidate indexes in database [dbm] based on the data in
+** linked-list pScan.
+*/
+static int idxCreateCandidates(sqlite3expert *p){
+ int rc = SQLITE_OK;
+ IdxScan *pIter;
+
+ for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
+ rc = idxCreateFromWhere(p, pIter, 0);
+ if( rc==SQLITE_OK && pIter->pOrder ){
+ rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
+ }
+ }
+
+ return rc;
+}
+
+/*
+** Free all elements of the linked list starting at pConstraint.
+*/
+static void idxConstraintFree(IdxConstraint *pConstraint){
+ IdxConstraint *pNext;
+ IdxConstraint *p;
+
+ for(p=pConstraint; p; p=pNext){
+ pNext = p->pNext;
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Free all elements of the linked list starting from pScan up until pLast
+** (pLast is not freed).
+*/
+static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
+ IdxScan *p;
+ IdxScan *pNext;
+ for(p=pScan; p!=pLast; p=pNext){
+ pNext = p->pNextScan;
+ idxConstraintFree(p->pOrder);
+ idxConstraintFree(p->pEq);
+ idxConstraintFree(p->pRange);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Free all elements of the linked list starting from pStatement up
+** until pLast (pLast is not freed).
+*/
+static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
+ IdxStatement *p;
+ IdxStatement *pNext;
+ for(p=pStatement; p!=pLast; p=pNext){
+ pNext = p->pNext;
+ sqlite3_free(p->zEQP);
+ sqlite3_free(p->zIdx);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Free the linked list of IdxTable objects starting at pTab.
+*/
+static void idxTableFree(IdxTable *pTab){
+ IdxTable *pIter;
+ IdxTable *pNext;
+ for(pIter=pTab; pIter; pIter=pNext){
+ pNext = pIter->pNext;
+ sqlite3_free(pIter);
+ }
+}
+
+/*
+** Free the linked list of IdxWrite objects starting at pTab.
+*/
+static void idxWriteFree(IdxWrite *pTab){
+ IdxWrite *pIter;
+ IdxWrite *pNext;
+ for(pIter=pTab; pIter; pIter=pNext){
+ pNext = pIter->pNext;
+ sqlite3_free(pIter);
+ }
+}
+
+
+
+/*
+** This function is called after candidate indexes have been created. It
+** runs all the queries to see which indexes they prefer, and populates
+** IdxStatement.zIdx and IdxStatement.zEQP with the results.
+*/
+int idxFindIndexes(
+ sqlite3expert *p,
+ char **pzErr /* OUT: Error message (sqlite3_malloc) */
+){
+ IdxStatement *pStmt;
+ sqlite3 *dbm = p->dbm;
+ int rc = SQLITE_OK;
+
+ IdxHash hIdx;
+ idxHashInit(&hIdx);
+
+ for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
+ IdxHashEntry *pEntry;
+ sqlite3_stmt *pExplain = 0;
+ idxHashClear(&hIdx);
+ rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
+ "EXPLAIN QUERY PLAN %s", pStmt->zSql
+ );
+ while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
+ /* int iId = sqlite3_column_int(pExplain, 0); */
+ /* int iParent = sqlite3_column_int(pExplain, 1); */
+ /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
+ const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
+ int nDetail = STRLEN(zDetail);
+ int i;
+
+ for(i=0; i<nDetail; i++){
+ const char *zIdx = 0;
+ if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
+ zIdx = &zDetail[i+13];
+ }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
+ zIdx = &zDetail[i+22];
+ }
+ if( zIdx ){
+ const char *zSql;
+ int nIdx = 0;
+ while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
+ nIdx++;
+ }
+ zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
+ if( zSql ){
+ idxHashAdd(&rc, &hIdx, zSql, 0);
+ if( rc ) goto find_indexes_out;
+ }
+ break;
+ }
+ }
+
+ if( zDetail[0]!='-' ){
+ pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
+ }
+ }
+
+ for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
+ pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
+ }
+
+ idxFinalize(&rc, pExplain);
+ }
+
+ find_indexes_out:
+ idxHashClear(&hIdx);
+ return rc;
+}
+
+static int idxAuthCallback(
+ void *pCtx,
+ int eOp,
+ const char *z3,
+ const char *z4,
+ const char *zDb,
+ const char *zTrigger
+){
+ int rc = SQLITE_OK;
+ (void)z4;
+ (void)zTrigger;
+ if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
+ if( sqlite3_stricmp(zDb, "main")==0 ){
+ sqlite3expert *p = (sqlite3expert*)pCtx;
+ IdxTable *pTab;
+ for(pTab=p->pTable; pTab; pTab=pTab->pNext){
+ if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
+ }
+ if( pTab ){
+ IdxWrite *pWrite;
+ for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
+ if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
+ }
+ if( pWrite==0 ){
+ pWrite = idxMalloc(&rc, sizeof(IdxWrite));
+ if( rc==SQLITE_OK ){
+ pWrite->pTab = pTab;
+ pWrite->eOp = eOp;
+ pWrite->pNext = p->pWrite;
+ p->pWrite = pWrite;
+ }
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+static int idxProcessOneTrigger(
+ sqlite3expert *p,
+ IdxWrite *pWrite,
+ char **pzErr
+){
+ static const char *zInt = UNIQUE_TABLE_NAME;
+ static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
+ IdxTable *pTab = pWrite->pTab;
+ const char *zTab = pTab->zName;
+ const char *zSql =
+ "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
+ "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
+ "ORDER BY type;";
+ sqlite3_stmt *pSelect = 0;
+ int rc = SQLITE_OK;
+ char *zWrite = 0;
+
+ /* Create the table and its triggers in the temp schema */
+ rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
+ const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
+ rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
+ }
+ idxFinalize(&rc, pSelect);
+
+ /* Rename the table in the temp schema to zInt */
+ if( rc==SQLITE_OK ){
+ char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
+ if( z==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
+ sqlite3_free(z);
+ }
+ }
+
+ switch( pWrite->eOp ){
+ case SQLITE_INSERT: {
+ int i;
+ zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
+ for(i=0; i<pTab->nCol; i++){
+ zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
+ }
+ zWrite = idxAppendText(&rc, zWrite, ")");
+ break;
+ }
+ case SQLITE_UPDATE: {
+ int i;
+ zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
+ for(i=0; i<pTab->nCol; i++){
+ zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ",
+ pTab->aCol[i].zName
+ );
+ }
+ break;
+ }
+ default: {
+ assert( pWrite->eOp==SQLITE_DELETE );
+ if( rc==SQLITE_OK ){
+ zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
+ if( zWrite==0 ) rc = SQLITE_NOMEM;
+ }
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3_stmt *pX = 0;
+ rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
+ idxFinalize(&rc, pX);
+ if( rc!=SQLITE_OK ){
+ idxDatabaseError(p->dbv, pzErr);
+ }
+ }
+ sqlite3_free(zWrite);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
+ }
+
+ return rc;
+}
+
+static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
+ int rc = SQLITE_OK;
+ IdxWrite *pEnd = 0;
+ IdxWrite *pFirst = p->pWrite;
+
+ while( rc==SQLITE_OK && pFirst!=pEnd ){
+ IdxWrite *pIter;
+ for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
+ rc = idxProcessOneTrigger(p, pIter, pzErr);
+ }
+ pEnd = pFirst;
+ pFirst = p->pWrite;
+ }
+
+ return rc;
+}
+
+
+static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
+ int rc = idxRegisterVtab(p);
+ sqlite3_stmt *pSchema = 0;
+
+ /* For each table in the main db schema:
+ **
+ ** 1) Add an entry to the p->pTable list, and
+ ** 2) Create the equivalent virtual table in dbv.
+ */
+ rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
+ "SELECT type, name, sql, 1 FROM sqlite_master "
+ "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
+ " UNION ALL "
+ "SELECT type, name, sql, 2 FROM sqlite_master "
+ "WHERE type = 'trigger'"
+ " AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
+ "ORDER BY 4, 1"
+ );
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
+ const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
+ const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
+ const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
+
+ if( zType[0]=='v' || zType[1]=='r' ){
+ rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
+ }else{
+ IdxTable *pTab;
+ rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
+ if( rc==SQLITE_OK ){
+ int i;
+ char *zInner = 0;
+ char *zOuter = 0;
+ pTab->pNext = p->pTable;
+ p->pTable = pTab;
+
+ /* The statement the vtab will pass to sqlite3_declare_vtab() */
+ zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
+ for(i=0; i<pTab->nCol; i++){
+ zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
+ (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
+ );
+ }
+ zInner = idxAppendText(&rc, zInner, ")");
+
+ /* The CVT statement to create the vtab */
+ zOuter = idxAppendText(&rc, 0,
+ "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
+ );
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
+ }
+ sqlite3_free(zInner);
+ sqlite3_free(zOuter);
+ }
+ }
+ }
+ idxFinalize(&rc, pSchema);
+ return rc;
+}
+
+struct IdxSampleCtx {
+ int iTarget;
+ double target; /* Target nRet/nRow value */
+ double nRow; /* Number of rows seen */
+ double nRet; /* Number of rows returned */
+};
+
+static void idxSampleFunc(
+ sqlite3_context *pCtx,
+ int argc,
+ sqlite3_value **argv
+){
+ struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
+ int bRet;
+
+ (void)argv;
+ assert( argc==0 );
+ if( p->nRow==0.0 ){
+ bRet = 1;
+ }else{
+ bRet = (p->nRet / p->nRow) <= p->target;
+ if( bRet==0 ){
+ unsigned short rnd;
+ sqlite3_randomness(2, (void*)&rnd);
+ bRet = ((int)rnd % 100) <= p->iTarget;
+ }
+ }
+
+ sqlite3_result_int(pCtx, bRet);
+ p->nRow += 1.0;
+ p->nRet += (double)bRet;
+}
+
+struct IdxRemCtx {
+ int nSlot;
+ struct IdxRemSlot {
+ int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
+ i64 iVal; /* SQLITE_INTEGER value */
+ double rVal; /* SQLITE_FLOAT value */
+ int nByte; /* Bytes of space allocated at z */
+ int n; /* Size of buffer z */
+ char *z; /* SQLITE_TEXT/BLOB value */
+ } aSlot[1];
+};
+
+/*
+** Implementation of scalar function rem().
+*/
+static void idxRemFunc(
+ sqlite3_context *pCtx,
+ int argc,
+ sqlite3_value **argv
+){
+ struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
+ struct IdxRemSlot *pSlot;
+ int iSlot;
+ assert( argc==2 );
+
+ iSlot = sqlite3_value_int(argv[0]);
+ assert( iSlot<=p->nSlot );
+ pSlot = &p->aSlot[iSlot];
+
+ switch( pSlot->eType ){
+ case SQLITE_NULL:
+ /* no-op */
+ break;
+
+ case SQLITE_INTEGER:
+ sqlite3_result_int64(pCtx, pSlot->iVal);
+ break;
+
+ case SQLITE_FLOAT:
+ sqlite3_result_double(pCtx, pSlot->rVal);
+ break;
+
+ case SQLITE_BLOB:
+ sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
+ break;
+
+ case SQLITE_TEXT:
+ sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
+ break;
+ }
+
+ pSlot->eType = sqlite3_value_type(argv[1]);
+ switch( pSlot->eType ){
+ case SQLITE_NULL:
+ /* no-op */
+ break;
+
+ case SQLITE_INTEGER:
+ pSlot->iVal = sqlite3_value_int64(argv[1]);
+ break;
+
+ case SQLITE_FLOAT:
+ pSlot->rVal = sqlite3_value_double(argv[1]);
+ break;
+
+ case SQLITE_BLOB:
+ case SQLITE_TEXT: {
+ int nByte = sqlite3_value_bytes(argv[1]);
+ if( nByte>pSlot->nByte ){
+ char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
+ if( zNew==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return;
+ }
+ pSlot->nByte = nByte*2;
+ pSlot->z = zNew;
+ }
+ pSlot->n = nByte;
+ if( pSlot->eType==SQLITE_BLOB ){
+ memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
+ }else{
+ memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
+ }
+ break;
+ }
+ }
+}
+
+static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
+ int rc = SQLITE_OK;
+ const char *zMax =
+ "SELECT max(i.seqno) FROM "
+ " sqlite_master AS s, "
+ " pragma_index_list(s.name) AS l, "
+ " pragma_index_info(l.name) AS i "
+ "WHERE s.type = 'table'";
+ sqlite3_stmt *pMax = 0;
+
+ *pnMax = 0;
+ rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+ *pnMax = sqlite3_column_int(pMax, 0) + 1;
+ }
+ idxFinalize(&rc, pMax);
+
+ return rc;
+}
+
+static int idxPopulateOneStat1(
+ sqlite3expert *p,
+ sqlite3_stmt *pIndexXInfo,
+ sqlite3_stmt *pWriteStat,
+ const char *zTab,
+ const char *zIdx,
+ char **pzErr
+){
+ char *zCols = 0;
+ char *zOrder = 0;
+ char *zQuery = 0;
+ int nCol = 0;
+ int i;
+ sqlite3_stmt *pQuery = 0;
+ int *aStat = 0;
+ int rc = SQLITE_OK;
+
+ assert( p->iSample>0 );
+
+ /* Formulate the query text */
+ sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
+ while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
+ const char *zComma = zCols==0 ? "" : ", ";
+ const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
+ const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
+ zCols = idxAppendText(&rc, zCols,
+ "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
+ );
+ zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
+ }
+ sqlite3_reset(pIndexXInfo);
+ if( rc==SQLITE_OK ){
+ if( p->iSample==100 ){
+ zQuery = sqlite3_mprintf(
+ "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
+ );
+ }else{
+ zQuery = sqlite3_mprintf(
+ "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
+ );
+ }
+ }
+ sqlite3_free(zCols);
+ sqlite3_free(zOrder);
+
+ /* Formulate the query text */
+ if( rc==SQLITE_OK ){
+ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
+ rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
+ }
+ sqlite3_free(zQuery);
+
+ if( rc==SQLITE_OK ){
+ aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
+ }
+ if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
+ IdxHashEntry *pEntry;
+ char *zStat = 0;
+ for(i=0; i<=nCol; i++) aStat[i] = 1;
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
+ aStat[0]++;
+ for(i=0; i<nCol; i++){
+ if( sqlite3_column_int(pQuery, i)==0 ) break;
+ }
+ for(/*no-op*/; i<nCol; i++){
+ aStat[i+1]++;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ int s0 = aStat[0];
+ zStat = sqlite3_mprintf("%d", s0);
+ if( zStat==0 ) rc = SQLITE_NOMEM;
+ for(i=1; rc==SQLITE_OK && i<=nCol; i++){
+ zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
+ sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
+ sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
+ sqlite3_step(pWriteStat);
+ rc = sqlite3_reset(pWriteStat);
+ }
+
+ pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
+ if( pEntry ){
+ assert( pEntry->zVal2==0 );
+ pEntry->zVal2 = zStat;
+ }else{
+ sqlite3_free(zStat);
+ }
+ }
+ sqlite3_free(aStat);
+ idxFinalize(&rc, pQuery);
+
+ return rc;
+}
+
+static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
+ int rc;
+ char *zSql;
+
+ rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
+ if( rc!=SQLITE_OK ) return rc;
+
+ zSql = sqlite3_mprintf(
+ "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
+ );
+ if( zSql==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
+ sqlite3_free(zSql);
+
+ return rc;
+}
+
+/*
+** This function is called as part of sqlite3_expert_analyze(). Candidate
+** indexes have already been created in database sqlite3expert.dbm, this
+** function populates sqlite_stat1 table in the same database.
+**
+** The stat1 data is generated by querying the
+*/
+static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
+ int rc = SQLITE_OK;
+ int nMax =0;
+ struct IdxRemCtx *pCtx = 0;
+ struct IdxSampleCtx samplectx;
+ int i;
+ i64 iPrev = -100000;
+ sqlite3_stmt *pAllIndex = 0;
+ sqlite3_stmt *pIndexXInfo = 0;
+ sqlite3_stmt *pWrite = 0;
+
+ const char *zAllIndex =
+ "SELECT s.rowid, s.name, l.name FROM "
+ " sqlite_master AS s, "
+ " pragma_index_list(s.name) AS l "
+ "WHERE s.type = 'table'";
+ const char *zIndexXInfo =
+ "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
+ const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
+
+ /* If iSample==0, no sqlite_stat1 data is required. */
+ if( p->iSample==0 ) return SQLITE_OK;
+
+ rc = idxLargestIndex(p->dbm, &nMax, pzErr);
+ if( nMax<=0 || rc!=SQLITE_OK ) return rc;
+
+ rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
+
+ if( rc==SQLITE_OK ){
+ int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
+ pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
+ rc = sqlite3_create_function(
+ dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
+ );
+ }
+
+ if( rc==SQLITE_OK ){
+ pCtx->nSlot = nMax+1;
+ rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
+ }
+ if( rc==SQLITE_OK ){
+ rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
+ }
+ if( rc==SQLITE_OK ){
+ rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
+ }
+
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
+ i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
+ const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
+ const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
+ if( p->iSample<100 && iPrev!=iRowid ){
+ samplectx.target = (double)p->iSample / 100.0;
+ samplectx.iTarget = p->iSample;
+ samplectx.nRow = 0.0;
+ samplectx.nRet = 0.0;
+ rc = idxBuildSampleTable(p, zTab);
+ if( rc!=SQLITE_OK ) break;
+ }
+ rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
+ iPrev = iRowid;
+ }
+ if( rc==SQLITE_OK && p->iSample<100 ){
+ rc = sqlite3_exec(p->dbv,
+ "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
+ );
+ }
+
+ idxFinalize(&rc, pAllIndex);
+ idxFinalize(&rc, pIndexXInfo);
+ idxFinalize(&rc, pWrite);
+
+ for(i=0; i<pCtx->nSlot; i++){
+ sqlite3_free(pCtx->aSlot[i].z);
+ }
+ sqlite3_free(pCtx);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
+ }
+
+ sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
+ return rc;
+}
+
+/*
+** Allocate a new sqlite3expert object.
+*/
+sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
+ int rc = SQLITE_OK;
+ sqlite3expert *pNew;
+
+ pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
+
+ /* Open two in-memory databases to work with. The "vtab database" (dbv)
+ ** will contain a virtual table corresponding to each real table in
+ ** the user database schema, and a copy of each view. It is used to
+ ** collect information regarding the WHERE, ORDER BY and other clauses
+ ** of the user's query.
+ */
+ if( rc==SQLITE_OK ){
+ pNew->db = db;
+ pNew->iSample = 100;
+ rc = sqlite3_open(":memory:", &pNew->dbv);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_open(":memory:", &pNew->dbm);
+ if( rc==SQLITE_OK ){
+ sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0);
+ }
+ }
+
+
+ /* Copy the entire schema of database [db] into [dbm]. */
+ if( rc==SQLITE_OK ){
+ sqlite3_stmt *pSql;
+ rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
+ "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
+ " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
+ );
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
+ const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
+ rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
+ }
+ idxFinalize(&rc, pSql);
+ }
+
+ /* Create the vtab schema */
+ if( rc==SQLITE_OK ){
+ rc = idxCreateVtabSchema(pNew, pzErrmsg);
+ }
+
+ /* Register the auth callback with dbv */
+ if( rc==SQLITE_OK ){
+ sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
+ }
+
+ /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
+ ** return the new sqlite3expert handle. */
+ if( rc!=SQLITE_OK ){
+ sqlite3_expert_destroy(pNew);
+ pNew = 0;
+ }
+ return pNew;
+}
+
+/*
+** Configure an sqlite3expert object.
+*/
+int sqlite3_expert_config(sqlite3expert *p, int op, ...){
+ int rc = SQLITE_OK;
+ va_list ap;
+ va_start(ap, op);
+ switch( op ){
+ case EXPERT_CONFIG_SAMPLE: {
+ int iVal = va_arg(ap, int);
+ if( iVal<0 ) iVal = 0;
+ if( iVal>100 ) iVal = 100;
+ p->iSample = iVal;
+ break;
+ }
+ default:
+ rc = SQLITE_NOTFOUND;
+ break;
+ }
+
+ va_end(ap);
+ return rc;
+}
+
+/*
+** Add an SQL statement to the analysis.
+*/
+int sqlite3_expert_sql(
+ sqlite3expert *p, /* From sqlite3_expert_new() */
+ const char *zSql, /* SQL statement to add */
+ char **pzErr /* OUT: Error message (if any) */
+){
+ IdxScan *pScanOrig = p->pScan;
+ IdxStatement *pStmtOrig = p->pStatement;
+ int rc = SQLITE_OK;
+ const char *zStmt = zSql;
+
+ if( p->bRun ) return SQLITE_MISUSE;
+
+ while( rc==SQLITE_OK && zStmt && zStmt[0] ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
+ if( rc==SQLITE_OK ){
+ if( pStmt ){
+ IdxStatement *pNew;
+ const char *z = sqlite3_sql(pStmt);
+ int n = STRLEN(z);
+ pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
+ if( rc==SQLITE_OK ){
+ pNew->zSql = (char*)&pNew[1];
+ memcpy(pNew->zSql, z, n+1);
+ pNew->pNext = p->pStatement;
+ if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
+ p->pStatement = pNew;
+ }
+ sqlite3_finalize(pStmt);
+ }
+ }else{
+ idxDatabaseError(p->dbv, pzErr);
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ idxScanFree(p->pScan, pScanOrig);
+ idxStatementFree(p->pStatement, pStmtOrig);
+ p->pScan = pScanOrig;
+ p->pStatement = pStmtOrig;
+ }
+
+ return rc;
+}
+
+int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
+ int rc;
+ IdxHashEntry *pEntry;
+
+ /* Do trigger processing to collect any extra IdxScan structures */
+ rc = idxProcessTriggers(p, pzErr);
+
+ /* Create candidate indexes within the in-memory database file */
+ if( rc==SQLITE_OK ){
+ rc = idxCreateCandidates(p);
+ }
+
+ /* Generate the stat1 data */
+ if( rc==SQLITE_OK ){
+ rc = idxPopulateStat1(p, pzErr);
+ }
+
+ /* Formulate the EXPERT_REPORT_CANDIDATES text */
+ for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
+ p->zCandidates = idxAppendText(&rc, p->zCandidates,
+ "%s;%s%s\n", pEntry->zVal,
+ pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
+ );
+ }
+
+ /* Figure out which of the candidate indexes are preferred by the query
+ ** planner and report the results to the user. */
+ if( rc==SQLITE_OK ){
+ rc = idxFindIndexes(p, pzErr);
+ }
+
+ if( rc==SQLITE_OK ){
+ p->bRun = 1;
+ }
+ return rc;
+}
+
+/*
+** Return the total number of statements that have been added to this
+** sqlite3expert using sqlite3_expert_sql().
+*/
+int sqlite3_expert_count(sqlite3expert *p){
+ int nRet = 0;
+ if( p->pStatement ) nRet = p->pStatement->iId+1;
+ return nRet;
+}
+
+/*
+** Return a component of the report.
+*/
+const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
+ const char *zRet = 0;
+ IdxStatement *pStmt;
+
+ if( p->bRun==0 ) return 0;
+ for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
+ switch( eReport ){
+ case EXPERT_REPORT_SQL:
+ if( pStmt ) zRet = pStmt->zSql;
+ break;
+ case EXPERT_REPORT_INDEXES:
+ if( pStmt ) zRet = pStmt->zIdx;
+ break;
+ case EXPERT_REPORT_PLAN:
+ if( pStmt ) zRet = pStmt->zEQP;
+ break;
+ case EXPERT_REPORT_CANDIDATES:
+ zRet = p->zCandidates;
+ break;
+ }
+ return zRet;
+}
+
+/*
+** Free an sqlite3expert object.
+*/
+void sqlite3_expert_destroy(sqlite3expert *p){
+ if( p ){
+ sqlite3_close(p->dbm);
+ sqlite3_close(p->dbv);
+ idxScanFree(p->pScan, 0);
+ idxStatementFree(p->pStatement, 0);
+ idxTableFree(p->pTable);
+ idxWriteFree(p->pWrite);
+ idxHashClear(&p->hIdx);
+ sqlite3_free(p->zCandidates);
+ sqlite3_free(p);
+ }
+}
+
+#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
+
+/************************* End ../ext/expert/sqlite3expert.c ********************/
+
+#if defined(SQLITE_ENABLE_SESSION)
+/*
+** State information for a single open session
+*/
+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",
+** saved so that it can be restored by ".explain off"
+*/
+typedef struct SavedModeInfo SavedModeInfo;
+struct SavedModeInfo {
+ int valid; /* Is there legit data in here? */
+ int mode; /* Mode prior to ".explain on" */
+ int showHeader; /* The ".header" setting prior to ".explain on" */
+ int colWidth[100]; /* Column widths prior to ".explain on" */
+};
+
+typedef struct ExpertInfo ExpertInfo;
+struct ExpertInfo {
+ sqlite3expert *pExpert;
+ int bVerbose;
+};
+
+/* A single line in the EQP output */
+typedef struct EQPGraphRow EQPGraphRow;
+struct EQPGraphRow {
+ int iEqpId; /* ID for this row */
+ int iParentId; /* ID of the parent row */
+ EQPGraphRow *pNext; /* Next row in sequence */
+ char zText[1]; /* Text to display for this row */
+};
+
+/* All EQP output is collected into an instance of the following */
+typedef struct EQPGraph EQPGraph;
+struct EQPGraph {
+ EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
+ EQPGraphRow *pLast; /* Last element of the pRow list */
+ char zPrefix[100]; /* Graph prefix */
+};
+
+/*
+** State information about the database connection is contained in an
+** instance of the following structure.
+*/
+typedef struct ShellState ShellState;
+struct ShellState {
+ sqlite3 *db; /* The database */
+ u8 autoExplain; /* Automatically turn on .explain mode */
+ u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
+ u8 autoEQPtest; /* autoEQP is in test mode */
+ u8 statsOn; /* True to display memory stats before each finalize */
+ u8 scanstatsOn; /* True to display scan stats before each finalize */
+ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
+ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
+ u8 nEqpLevel; /* Depth of the EQP output graph */
+ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
+ int outCount; /* Revert to stdout when reaching zero */
+ int cnt; /* Number of records displayed so far */
+ FILE *out; /* Write results here */
+ FILE *traceOut; /* Output for sqlite3_trace() */
+ int nErr; /* Number of errors seen */
+ int mode; /* An output mode setting */
+ int modePrior; /* Saved mode */
+ int cMode; /* temporary output mode for the current query */
+ int normalMode; /* Output mode before ".explain on" */
+ int writableSchema; /* True if PRAGMA writable_schema=ON */
+ int showHeader; /* True to show column names in List or Column mode */
+ int nCheck; /* Number of ".check" commands run */
+ unsigned shellFlgs; /* Various flags */
+ char *zDestTable; /* Name of destination table when MODE_Insert */
+ char *zTempFile; /* Temporary file that might need deleting */
+ char zTestcase[30]; /* Name of current test case */
+ char colSeparator[20]; /* Column separator character for several modes */
+ char rowSeparator[20]; /* Row separator character for MODE_Ascii */
+ char colSepPrior[20]; /* Saved column separator */
+ char rowSepPrior[20]; /* Saved row separator */
+ int colWidth[100]; /* Requested width of each column when in column mode*/
+ int actualWidth[100]; /* Actual width of each column */
+ char nullValue[20]; /* The text to print when a NULL comes back from
+ ** the database */
+ char outfile[FILENAME_MAX]; /* Filename for *out */
+ const char *zDbFilename; /* name of the database file */
+ char *zFreeOnClose; /* Filename to free when closing */
+ const char *zVfs; /* Name of VFS to use */
+ sqlite3_stmt *pStmt; /* Current statement if any. */
+ FILE *pLog; /* Write log output here */
+ int *aiIndent; /* Array of indents used in MODE_Explain */
+ int nIndent; /* Size of array aiIndent[] */
+ int iIndent; /* Index of current op in aiIndent[] */
+ EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
+#if defined(SQLITE_ENABLE_SESSION)
+ int nSession; /* Number of active sessions */
+ OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
+#endif
+ ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
+};
+
+
+/* Allowed values for ShellState.autoEQP
+*/
+#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
+#define AUTOEQP_on 1 /* Automatic EQP is on */
+#define AUTOEQP_trigger 2 /* On and also show plans for triggers */
+#define AUTOEQP_full 3 /* Show full EXPLAIN */
+
+/* Allowed values for ShellState.openMode
+*/
+#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
+#define SHELL_OPEN_NORMAL 1 /* Normal database file */
+#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
+#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
+#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
+#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
+
+/*
+** These are the allowed shellFlgs values
+*/
+#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
+#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
+#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
+#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
+#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
+#define SHFLG_CountChanges 0x00000020 /* .changes setting */
+#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
+
+/*
+** Macros for testing and setting shellFlgs
+*/
+#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
+#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
+#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
+
+/*
+** These are the allowed modes.
+*/
+#define MODE_Line 0 /* One column per line. Blank line between records */
+#define MODE_Column 1 /* One record per line in neat columns */
+#define MODE_List 2 /* One record per line with a separator */
+#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
+#define MODE_Html 4 /* Generate an XHTML table */
+#define MODE_Insert 5 /* Generate SQL "insert" statements */
+#define MODE_Quote 6 /* Quote values as for SQL */
+#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
+#define MODE_Csv 8 /* Quote strings, numbers are plain */
+#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
+#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
+#define MODE_Pretty 11 /* Pretty-print schemas */
+#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
+
+static const char *const modeDescr[] = {
+ "line",
+ "column",
+ "list",
+ "semi",
+ "html",
+ "insert",
+ "quote",
+ "tcl",
+ "csv",
+ "explain",
+ "ascii",
+ "prettyprint",
+ "eqp"
+};
+
+/*
+** These are the column/row/line separators used by the various
+** import/export modes.
+*/
+#define SEP_Column "|"
+#define SEP_Row "\n"
+#define SEP_Tab "\t"
+#define SEP_Space " "
+#define SEP_Comma ","
+#define SEP_CrLf "\r\n"
+#define SEP_Unit "\x1F"
+#define SEP_Record "\x1E"
+
+/*
+** A callback for the sqlite3_log() interface.
+*/
+static void shellLog(void *pArg, int iErrCode, const char *zMsg){
+ ShellState *p = (ShellState*)pArg;
+ if( p->pLog==0 ) return;
+ utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
+ fflush(p->pLog);
+}
+
+/*
+** SQL function: shell_putsnl(X)
+**
+** Write the text X to the screen (or whatever output is being directed)
+** adding a newline at the end, and then return X.
+*/
+static void shellPutsFunc(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
+ (void)nVal;
+ utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
+ sqlite3_result_value(pCtx, apVal[0]);
+}
+
+/*
+** SQL function: edit(VALUE)
+** edit(VALUE,EDITOR)
+**
+** These steps:
+**
+** (1) Write VALUE into a temporary file.
+** (2) Run program EDITOR on that temporary file.
+** (3) Read the temporary file back and return its content as the result.
+** (4) Delete the temporary file
+**
+** If the EDITOR argument is omitted, use the value in the VISUAL
+** environment variable. If still there is no EDITOR, through an error.
+**
+** Also throw an error if the EDITOR program returns a non-zero exit code.
+*/
+#ifndef SQLITE_NOHAVE_SYSTEM
+static void editFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const char *zEditor;
+ char *zTempFile = 0;
+ sqlite3 *db;
+ char *zCmd = 0;
+ int bBin;
+ int rc;
+ int hasCRNL = 0;
+ FILE *f = 0;
+ sqlite3_int64 sz;
+ sqlite3_int64 x;
+ unsigned char *p = 0;
+
+ if( argc==2 ){
+ zEditor = (const char*)sqlite3_value_text(argv[1]);
+ }else{
+ zEditor = getenv("VISUAL");
+ }
+ if( zEditor==0 ){
+ sqlite3_result_error(context, "no editor for edit()", -1);
+ return;
+ }
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ sqlite3_result_error(context, "NULL input to edit()", -1);
+ return;
+ }
+ db = sqlite3_context_db_handle(context);
+ zTempFile = 0;
+ sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
+ if( zTempFile==0 ){
+ sqlite3_uint64 r = 0;
+ sqlite3_randomness(sizeof(r), &r);
+ zTempFile = sqlite3_mprintf("temp%llx", r);
+ if( zTempFile==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ }
+ bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
+ /* When writing the file to be edited, do \n to \r\n conversions on systems
+ ** that want \r\n line endings */
+ f = fopen(zTempFile, bBin ? "wb" : "w");
+ if( f==0 ){
+ sqlite3_result_error(context, "edit() cannot open temp file", -1);
+ goto edit_func_end;
+ }
+ sz = sqlite3_value_bytes(argv[0]);
+ if( bBin ){
+ x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
+ }else{
+ const char *z = (const char*)sqlite3_value_text(argv[0]);
+ /* Remember whether or not the value originally contained \r\n */
+ if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
+ x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
+ }
+ fclose(f);
+ f = 0;
+ if( x!=sz ){
+ sqlite3_result_error(context, "edit() could not write the whole file", -1);
+ goto edit_func_end;
+ }
+ zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
+ if( zCmd==0 ){
+ sqlite3_result_error_nomem(context);
+ goto edit_func_end;
+ }
+ rc = system(zCmd);
+ sqlite3_free(zCmd);
+ if( rc ){
+ sqlite3_result_error(context, "EDITOR returned non-zero", -1);
+ goto edit_func_end;
+ }
+ f = fopen(zTempFile, "rb");
+ if( f==0 ){
+ sqlite3_result_error(context,
+ "edit() cannot reopen temp file after edit", -1);
+ goto edit_func_end;
+ }
+ fseek(f, 0, SEEK_END);
+ sz = ftell(f);
+ rewind(f);
+ p = sqlite3_malloc64( sz+(bBin==0) );
+ if( p==0 ){
+ sqlite3_result_error_nomem(context);
+ goto edit_func_end;
+ }
+ x = fread(p, 1, sz, f);
+ fclose(f);
+ f = 0;
+ if( x!=sz ){
+ sqlite3_result_error(context, "could not read back the whole file", -1);
+ goto edit_func_end;
+ }
+ if( bBin ){
+ sqlite3_result_blob64(context, p, sz, sqlite3_free);
+ }else{
+ sqlite3_int64 i, j;
+ if( hasCRNL ){
+ /* If the original contains \r\n then do no conversions back to \n */
+ j = sz;
+ }else{
+ /* If the file did not originally contain \r\n then convert any new
+ ** \r\n back into \n */
+ for(i=j=0; i<sz; i++){
+ if( p[i]=='\r' && p[i+1]=='\n' ) i++;
+ p[j++] = p[i];
+ }
+ sz = j;
+ p[sz] = 0;
+ }
+ sqlite3_result_text64(context, (const char*)p, sz,
+ sqlite3_free, SQLITE_UTF8);
+ }
+ p = 0;
+
+edit_func_end:
+ if( f ) fclose(f);
+ unlink(zTempFile);
+ sqlite3_free(zTempFile);
+ sqlite3_free(p);
+}
+#endif /* SQLITE_NOHAVE_SYSTEM */
+
+/*
+** Save or restore the current output mode
+*/
+static void outputModePush(ShellState *p){
+ p->modePrior = p->mode;
+ memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
+ memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
+}
+static void outputModePop(ShellState *p){
+ p->mode = p->modePrior;
+ memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
+ memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
+}
+
+/*
+** Output the given string as a hex-encoded blob (eg. X'1234' )
+*/
+static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
+ int i;
+ char *zBlob = (char *)pBlob;
+ raw_printf(out,"X'");
+ for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
+ raw_printf(out,"'");
+}
+
+/*
+** Find a string that is not found anywhere in z[]. Return a pointer
+** to that string.
+**
+** Try to use zA and zB first. If both of those are already found in z[]
+** then make up some string and store it in the buffer zBuf.
+*/
+static const char *unused_string(
+ const char *z, /* Result must not appear anywhere in z */
+ const char *zA, const char *zB, /* Try these first */
+ char *zBuf /* Space to store a generated string */
+){
+ unsigned i = 0;
+ if( strstr(z, zA)==0 ) return zA;
+ if( strstr(z, zB)==0 ) return zB;
+ do{
+ sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
+ }while( strstr(z,zBuf)!=0 );
+ return zBuf;
+}
+
+/*
+** Output the given string as a quoted string using SQL quoting conventions.
+**
+** See also: output_quoted_escaped_string()
+*/
+static void output_quoted_string(FILE *out, const char *z){
+ int i;
+ char c;
+ setBinaryMode(out, 1);
+ for(i=0; (c = z[i])!=0 && c!='\''; i++){}
+ if( c==0 ){
+ utf8_printf(out,"'%s'",z);
+ }else{
+ raw_printf(out, "'");
+ while( *z ){
+ for(i=0; (c = z[i])!=0 && c!='\''; i++){}
+ if( c=='\'' ) i++;
+ if( i ){
+ utf8_printf(out, "%.*s", i, z);
+ z += i;
+ }
+ if( c=='\'' ){
+ raw_printf(out, "'");
+ continue;
+ }
+ if( c==0 ){
+ break;
+ }
+ z++;
+ }
+ raw_printf(out, "'");
+ }
+ setTextMode(out, 1);
+}
+
+/*
+** Output the given string as a quoted string using SQL quoting conventions.
+** Additionallly , escape the "\n" and "\r" characters so that they do not
+** get corrupted by end-of-line translation facilities in some operating
+** systems.
+**
+** This is like output_quoted_string() but with the addition of the \r\n
+** escape mechanism.
+*/
+static void output_quoted_escaped_string(FILE *out, const char *z){
+ int i;
+ char c;
+ setBinaryMode(out, 1);
+ for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
+ if( c==0 ){
+ utf8_printf(out,"'%s'",z);
+ }else{
+ const char *zNL = 0;
+ const char *zCR = 0;
+ int nNL = 0;
+ int nCR = 0;
+ char zBuf1[20], zBuf2[20];
+ for(i=0; z[i]; i++){
+ if( z[i]=='\n' ) nNL++;
+ if( z[i]=='\r' ) nCR++;
+ }
+ if( nNL ){
+ raw_printf(out, "replace(");
+ zNL = unused_string(z, "\\n", "\\012", zBuf1);
+ }
+ if( nCR ){
+ raw_printf(out, "replace(");
+ zCR = unused_string(z, "\\r", "\\015", zBuf2);
+ }
+ raw_printf(out, "'");
+ while( *z ){
+ for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
+ if( c=='\'' ) i++;
+ if( i ){
+ utf8_printf(out, "%.*s", i, z);
+ z += i;
+ }
+ if( c=='\'' ){
+ raw_printf(out, "'");
+ continue;
+ }
+ if( c==0 ){
+ break;
+ }
+ z++;
+ if( c=='\n' ){
+ raw_printf(out, "%s", zNL);
+ continue;
+ }
+ raw_printf(out, "%s", zCR);
+ }
+ raw_printf(out, "'");
+ if( nCR ){
+ raw_printf(out, ",'%s',char(13))", zCR);
+ }
+ if( nNL ){
+ raw_printf(out, ",'%s',char(10))", zNL);
+ }
+ }
+ setTextMode(out, 1);
+}
+
+/*
+** Output the given string as a quoted according to C or TCL quoting rules.
+*/
+static void output_c_string(FILE *out, const char *z){
+ unsigned int c;
+ fputc('"', out);
+ while( (c = *(z++))!=0 ){
+ if( c=='\\' ){
+ fputc(c, out);
+ fputc(c, out);
+ }else if( c=='"' ){
+ fputc('\\', out);
+ fputc('"', out);
+ }else if( c=='\t' ){
+ fputc('\\', out);
+ fputc('t', out);
+ }else if( c=='\n' ){
+ fputc('\\', out);
+ fputc('n', out);
+ }else if( c=='\r' ){
+ fputc('\\', out);
+ fputc('r', out);
+ }else if( !isprint(c&0xff) ){
+ raw_printf(out, "\\%03o", c&0xff);
+ }else{
+ fputc(c, out);
+ }
+ }
+ fputc('"', out);
+}
+
+/*
+** Output the given string with characters that are special to
+** HTML escaped.
+*/
+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]!='\"'
+ && z[i]!='\'';
+ i++){}
+ if( i>0 ){
+ utf8_printf(out,"%.*s",i,z);
+ }
+ if( z[i]=='<' ){
+ raw_printf(out,"&lt;");
+ }else if( z[i]=='&' ){
+ raw_printf(out,"&amp;");
+ }else if( z[i]=='>' ){
+ raw_printf(out,"&gt;");
+ }else if( z[i]=='\"' ){
+ raw_printf(out,"&quot;");
+ }else if( z[i]=='\'' ){
+ raw_printf(out,"&#39;");
+ }else{
+ break;
+ }
+ z += i + 1;
+ }
+}
+
+/*
+** If a field contains any character identified by a 1 in the following
+** array, then the string must be quoted for CSV.
+*/
+static const char needCsvQuote[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+/*
+** Output a single term of CSV. Actually, p->colSeparator is used for
+** the separator, which may or may not be a comma. p->nullValue is
+** the null value. Strings are quoted if necessary. The separator
+** is only issued if bSep is true.
+*/
+static void output_csv(ShellState *p, const char *z, int bSep){
+ FILE *out = p->out;
+ if( z==0 ){
+ utf8_printf(out,"%s",p->nullValue);
+ }else{
+ int i;
+ int nSep = strlen30(p->colSeparator);
+ for(i=0; z[i]; i++){
+ if( needCsvQuote[((unsigned char*)z)[i]]
+ || (z[i]==p->colSeparator[0] &&
+ (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
+ i = 0;
+ break;
+ }
+ }
+ if( i==0 ){
+ char *zQuoted = sqlite3_mprintf("\"%w\"", z);
+ utf8_printf(out, "%s", zQuoted);
+ sqlite3_free(zQuoted);
+ }else{
+ utf8_printf(out, "%s", z);
+ }
+ }
+ if( bSep ){
+ utf8_printf(p->out, "%s", p->colSeparator);
+ }
+}
+
+/*
+** This routine runs when the user presses Ctrl-C
+*/
+static void interrupt_handler(int NotUsed){
+ UNUSED_PARAMETER(NotUsed);
+ seenInterrupt++;
+ if( seenInterrupt>2 ) exit(1);
+ if( globalDb ) sqlite3_interrupt(globalDb);
+}
+
+#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
+/*
+** This routine runs for console events (e.g. Ctrl-C) on Win32
+*/
+static BOOL WINAPI ConsoleCtrlHandler(
+ DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
+){
+ if( dwCtrlType==CTRL_C_EVENT ){
+ interrupt_handler(0);
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+/*
+** 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;
+ utf8_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;
+}
+#endif
+
+/*
+** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
+**
+** This routine converts some CREATE TABLE statements for shadow tables
+** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
+*/
+static void printSchemaLine(FILE *out, const char *z, const char *zTail){
+ if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
+ utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
+ }else{
+ utf8_printf(out, "%s%s", z, zTail);
+ }
+}
+static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
+ char c = z[n];
+ z[n] = 0;
+ printSchemaLine(out, z, zTail);
+ z[n] = c;
+}
+
+/*
+** Return true if string z[] has nothing but whitespace and comments to the
+** end of the first line.
+*/
+static int wsToEol(const char *z){
+ int i;
+ for(i=0; z[i]; i++){
+ if( z[i]=='\n' ) return 1;
+ if( IsSpace(z[i]) ) continue;
+ if( z[i]=='-' && z[i+1]=='-' ) return 1;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Add a new entry to the EXPLAIN QUERY PLAN data
+*/
+static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
+ EQPGraphRow *pNew;
+ int nText = strlen30(zText);
+ if( p->autoEQPtest ){
+ utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
+ }
+ pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
+ if( pNew==0 ) shell_out_of_memory();
+ pNew->iEqpId = iEqpId;
+ pNew->iParentId = p2;
+ memcpy(pNew->zText, zText, nText+1);
+ pNew->pNext = 0;
+ if( p->sGraph.pLast ){
+ p->sGraph.pLast->pNext = pNew;
+ }else{
+ p->sGraph.pRow = pNew;
+ }
+ p->sGraph.pLast = pNew;
+}
+
+/*
+** Free and reset the EXPLAIN QUERY PLAN data that has been collected
+** in p->sGraph.
+*/
+static void eqp_reset(ShellState *p){
+ EQPGraphRow *pRow, *pNext;
+ for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
+ pNext = pRow->pNext;
+ sqlite3_free(pRow);
+ }
+ memset(&p->sGraph, 0, sizeof(p->sGraph));
+}
+
+/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
+** pOld, or return the first such line if pOld is NULL
+*/
+static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
+ EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
+ while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
+ return pRow;
+}
+
+/* Render a single level of the graph that has iEqpId as its parent. Called
+** recursively to render sublevels.
+*/
+static void eqp_render_level(ShellState *p, int iEqpId){
+ EQPGraphRow *pRow, *pNext;
+ int n = strlen30(p->sGraph.zPrefix);
+ char *z;
+ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
+ pNext = eqp_next_row(p, iEqpId, pRow);
+ z = pRow->zText;
+ utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
+ if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
+ memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
+ eqp_render_level(p, pRow->iEqpId);
+ p->sGraph.zPrefix[n] = 0;
+ }
+ }
+}
+
+/*
+** Display and reset the EXPLAIN QUERY PLAN data
+*/
+static void eqp_render(ShellState *p){
+ EQPGraphRow *pRow = p->sGraph.pRow;
+ if( pRow ){
+ if( pRow->zText[0]=='-' ){
+ if( pRow->pNext==0 ){
+ eqp_reset(p);
+ return;
+ }
+ utf8_printf(p->out, "%s\n", pRow->zText+3);
+ p->sGraph.pRow = pRow->pNext;
+ sqlite3_free(pRow);
+ }else{
+ utf8_printf(p->out, "QUERY PLAN\n");
+ }
+ p->sGraph.zPrefix[0] = 0;
+ eqp_render_level(p, 0);
+ eqp_reset(p);
+ }
+}
+
+/*
+** This is the callback routine that the shell
+** invokes for each row of a query result.
+*/
+static int shell_callback(
+ void *pArg,
+ int nArg, /* Number of result columns */
+ char **azArg, /* Text of each result column */
+ char **azCol, /* Column names */
+ int *aiType /* Column types */
+){
+ int i;
+ ShellState *p = (ShellState*)pArg;
+
+ if( azArg==0 ) return 0;
+ switch( p->cMode ){
+ case MODE_Line: {
+ int w = 5;
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ int len = strlen30(azCol[i] ? azCol[i] : "");
+ if( len>w ) w = len;
+ }
+ if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
+ for(i=0; i<nArg; i++){
+ utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
+ azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
+ }
+ break;
+ }
+ case MODE_Explain:
+ case MODE_Column: {
+ static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
+ const int *colWidth;
+ int showHdr;
+ char *rowSep;
+ if( p->cMode==MODE_Column ){
+ colWidth = p->colWidth;
+ showHdr = p->showHeader;
+ rowSep = p->rowSeparator;
+ }else{
+ colWidth = aExplainWidths;
+ showHdr = 1;
+ rowSep = SEP_Row;
+ }
+ if( p->cnt++==0 ){
+ for(i=0; i<nArg; i++){
+ int w, n;
+ if( i<ArraySize(p->colWidth) ){
+ w = colWidth[i];
+ }else{
+ w = 0;
+ }
+ if( w==0 ){
+ w = strlenChar(azCol[i] ? azCol[i] : "");
+ if( w<10 ) w = 10;
+ n = strlenChar(azArg && azArg[i] ? azArg[i] : p->nullValue);
+ if( w<n ) w = n;
+ }
+ if( i<ArraySize(p->actualWidth) ){
+ p->actualWidth[i] = w;
+ }
+ if( showHdr ){
+ utf8_width_print(p->out, w, azCol[i]);
+ utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
+ }
+ }
+ if( showHdr ){
+ for(i=0; i<nArg; i++){
+ int w;
+ if( i<ArraySize(p->actualWidth) ){
+ w = p->actualWidth[i];
+ if( w<0 ) w = -w;
+ }else{
+ w = 10;
+ }
+ utf8_printf(p->out,"%-*.*s%s",w,w,
+ "----------------------------------------------------------"
+ "----------------------------------------------------------",
+ i==nArg-1 ? rowSep : " ");
+ }
+ }
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ int w;
+ if( i<ArraySize(p->actualWidth) ){
+ w = p->actualWidth[i];
+ }else{
+ w = 10;
+ }
+ if( p->cMode==MODE_Explain && azArg[i] && strlenChar(azArg[i])>w ){
+ w = strlenChar(azArg[i]);
+ }
+ if( i==1 && p->aiIndent && p->pStmt ){
+ if( p->iIndent<p->nIndent ){
+ utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
+ }
+ p->iIndent++;
+ }
+ utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
+ utf8_printf(p->out, "%s", i==nArg-1 ? rowSep : " ");
+ }
+ break;
+ }
+ case MODE_Semi: { /* .schema and .fullschema output */
+ printSchemaLine(p->out, azArg[0], ";\n");
+ 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( z[j-1]=='\r' ) z[j-1] = '\n';
+ 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++){ /* Copy changes from z[i] back to z[j] */
+ if( c==cEnd ){
+ cEnd = 0;
+ }else if( c=='"' || c=='\'' || c=='`' ){
+ cEnd = c;
+ }else if( c=='[' ){
+ cEnd = ']';
+ }else if( c=='-' && z[i+1]=='-' ){
+ cEnd = '\n';
+ }else if( c=='(' ){
+ nParen++;
+ }else if( c==')' ){
+ nParen--;
+ if( nLine>0 && nParen==0 && j>0 ){
+ printSchemaLineN(p->out, z, j, "\n");
+ j = 0;
+ }
+ }
+ z[j++] = c;
+ if( nParen==1 && cEnd==0
+ && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
+ ){
+ if( c=='\n' ) j--;
+ printSchemaLineN(p->out, z, j, "\n ");
+ j = 0;
+ nLine++;
+ while( IsSpace(z[i+1]) ){ i++; }
+ }
+ }
+ z[j] = 0;
+ }
+ printSchemaLine(p->out, z, ";\n");
+ sqlite3_free(z);
+ break;
+ }
+ case MODE_List: {
+ if( p->cnt++==0 && p->showHeader ){
+ for(i=0; i<nArg; i++){
+ utf8_printf(p->out,"%s%s",azCol[i],
+ i==nArg-1 ? p->rowSeparator : p->colSeparator);
+ }
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ char *z = azArg[i];
+ if( z==0 ) z = p->nullValue;
+ utf8_printf(p->out, "%s", z);
+ if( i<nArg-1 ){
+ utf8_printf(p->out, "%s", p->colSeparator);
+ }else{
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ }
+ }
+ break;
+ }
+ case MODE_Html: {
+ if( p->cnt++==0 && p->showHeader ){
+ raw_printf(p->out,"<TR>");
+ for(i=0; i<nArg; i++){
+ raw_printf(p->out,"<TH>");
+ output_html_string(p->out, azCol[i]);
+ raw_printf(p->out,"</TH>\n");
+ }
+ raw_printf(p->out,"</TR>\n");
+ }
+ if( azArg==0 ) break;
+ raw_printf(p->out,"<TR>");
+ for(i=0; i<nArg; i++){
+ raw_printf(p->out,"<TD>");
+ output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
+ raw_printf(p->out,"</TD>\n");
+ }
+ raw_printf(p->out,"</TR>\n");
+ break;
+ }
+ case MODE_Tcl: {
+ if( p->cnt++==0 && p->showHeader ){
+ for(i=0; i<nArg; i++){
+ output_c_string(p->out,azCol[i] ? azCol[i] : "");
+ if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
+ if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ break;
+ }
+ case MODE_Csv: {
+ 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);
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ }
+ if( nArg>0 ){
+ for(i=0; i<nArg; i++){
+ output_csv(p, azArg[i], i<nArg-1);
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ }
+ setTextMode(p->out, 1);
+ break;
+ }
+ case MODE_Insert: {
+ if( azArg==0 ) break;
+ utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
+ if( p->showHeader ){
+ raw_printf(p->out,"(");
+ for(i=0; i<nArg; i++){
+ if( i>0 ) raw_printf(p->out, ",");
+ if( quoteChar(azCol[i]) ){
+ char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
+ utf8_printf(p->out, "%s", z);
+ sqlite3_free(z);
+ }else{
+ raw_printf(p->out, "%s", azCol[i]);
+ }
+ }
+ raw_printf(p->out,")");
+ }
+ p->cnt++;
+ for(i=0; i<nArg; i++){
+ raw_printf(p->out, i>0 ? "," : " VALUES(");
+ if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
+ utf8_printf(p->out,"NULL");
+ }else if( aiType && aiType[i]==SQLITE_TEXT ){
+ if( ShellHasFlag(p, SHFLG_Newlines) ){
+ output_quoted_string(p->out, azArg[i]);
+ }else{
+ output_quoted_escaped_string(p->out, azArg[i]);
+ }
+ }else if( aiType && aiType[i]==SQLITE_INTEGER ){
+ utf8_printf(p->out,"%s", azArg[i]);
+ }else if( aiType && aiType[i]==SQLITE_FLOAT ){
+ char z[50];
+ double r = sqlite3_column_double(p->pStmt, i);
+ sqlite3_uint64 ur;
+ memcpy(&ur,&r,sizeof(r));
+ if( ur==0x7ff0000000000000LL ){
+ raw_printf(p->out, "1e999");
+ }else if( ur==0xfff0000000000000LL ){
+ raw_printf(p->out, "-1e999");
+ }else{
+ sqlite3_snprintf(50,z,"%!.20g", r);
+ raw_printf(p->out, "%s", z);
+ }
+ }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
+ const void *pBlob = sqlite3_column_blob(p->pStmt, i);
+ int nBlob = sqlite3_column_bytes(p->pStmt, i);
+ output_hex_blob(p->out, pBlob, nBlob);
+ }else if( isNumber(azArg[i], 0) ){
+ utf8_printf(p->out,"%s", azArg[i]);
+ }else if( ShellHasFlag(p, SHFLG_Newlines) ){
+ output_quoted_string(p->out, azArg[i]);
+ }else{
+ output_quoted_escaped_string(p->out, azArg[i]);
+ }
+ }
+ raw_printf(p->out,");\n");
+ break;
+ }
+ case MODE_Quote: {
+ if( azArg==0 ) break;
+ if( p->cnt==0 && p->showHeader ){
+ for(i=0; i<nArg; i++){
+ if( i>0 ) raw_printf(p->out, ",");
+ output_quoted_string(p->out, azCol[i]);
+ }
+ raw_printf(p->out,"\n");
+ }
+ p->cnt++;
+ for(i=0; i<nArg; i++){
+ if( i>0 ) raw_printf(p->out, ",");
+ if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
+ utf8_printf(p->out,"NULL");
+ }else if( aiType && aiType[i]==SQLITE_TEXT ){
+ output_quoted_string(p->out, azArg[i]);
+ }else if( aiType && aiType[i]==SQLITE_INTEGER ){
+ utf8_printf(p->out,"%s", azArg[i]);
+ }else if( aiType && aiType[i]==SQLITE_FLOAT ){
+ char z[50];
+ double r = sqlite3_column_double(p->pStmt, i);
+ sqlite3_snprintf(50,z,"%!.20g", r);
+ raw_printf(p->out, "%s", z);
+ }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
+ const void *pBlob = sqlite3_column_blob(p->pStmt, i);
+ int nBlob = sqlite3_column_bytes(p->pStmt, i);
+ output_hex_blob(p->out, pBlob, nBlob);
+ }else if( isNumber(azArg[i], 0) ){
+ utf8_printf(p->out,"%s", azArg[i]);
+ }else{
+ output_quoted_string(p->out, azArg[i]);
+ }
+ }
+ raw_printf(p->out,"\n");
+ break;
+ }
+ case MODE_Ascii: {
+ if( p->cnt++==0 && p->showHeader ){
+ for(i=0; i<nArg; i++){
+ if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
+ utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
+ utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
+ }
+ utf8_printf(p->out, "%s", p->rowSeparator);
+ break;
+ }
+ case MODE_EQP: {
+ eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+** This is the callback routine that the SQLite library
+** invokes for each row of a query result.
+*/
+static int callback(void *pArg, int nArg, char **azArg, char **azCol){
+ /* since we don't have type info, call the shell_callback with a NULL value */
+ return shell_callback(pArg, nArg, azArg, azCol, NULL);
+}
+
+/*
+** This is the callback routine from sqlite3_exec() that appends all
+** output onto the end of a ShellText object.
+*/
+static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
+ ShellText *p = (ShellText*)pArg;
+ int i;
+ UNUSED_PARAMETER(az);
+ if( azArg==0 ) return 0;
+ if( p->n ) appendText(p, "|", 0);
+ for(i=0; i<nArg; i++){
+ if( i ) appendText(p, ",", 0);
+ if( azArg[i] ) appendText(p, azArg[i], 0);
+ }
+ return 0;
+}
+
+/*
+** Generate an appropriate SELFTEST table in the main database.
+*/
+static void createSelftestTable(ShellState *p){
+ char *zErrMsg = 0;
+ sqlite3_exec(p->db,
+ "SAVEPOINT selftest_init;\n"
+ "CREATE TABLE IF NOT EXISTS selftest(\n"
+ " tno INTEGER PRIMARY KEY,\n" /* Test number */
+ " op TEXT,\n" /* Operator: memo run */
+ " cmd TEXT,\n" /* Command text */
+ " ans TEXT\n" /* Desired answer */
+ ");"
+ "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
+ "INSERT INTO [_shell$self](rowid,op,cmd)\n"
+ " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
+ " 'memo','Tests generated by --init');\n"
+ "INSERT INTO [_shell$self]\n"
+ " SELECT 'run',\n"
+ " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
+ "FROM sqlite_master ORDER BY 2'',224))',\n"
+ " hex(sha3_query('SELECT type,name,tbl_name,sql "
+ "FROM sqlite_master ORDER BY 2',224));\n"
+ "INSERT INTO [_shell$self]\n"
+ " SELECT 'run',"
+ " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
+ " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
+ " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
+ " FROM (\n"
+ " SELECT name FROM sqlite_master\n"
+ " WHERE type='table'\n"
+ " AND name<>'selftest'\n"
+ " AND coalesce(rootpage,0)>0\n"
+ " )\n"
+ " ORDER BY name;\n"
+ "INSERT INTO [_shell$self]\n"
+ " VALUES('run','PRAGMA integrity_check','ok');\n"
+ "INSERT INTO selftest(tno,op,cmd,ans)"
+ " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
+ "DROP TABLE [_shell$self];"
+ ,0,0,&zErrMsg);
+ if( zErrMsg ){
+ utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ }
+ sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
+}
+
+
+/*
+** Set the destination table field of the ShellState structure to
+** the name of the table given. Escape any quote characters in the
+** table name.
+*/
+static void set_table_name(ShellState *p, const char *zName){
+ int i, n;
+ char cQuote;
+ char *z;
+
+ if( p->zDestTable ){
+ free(p->zDestTable);
+ p->zDestTable = 0;
+ }
+ if( zName==0 ) return;
+ cQuote = quoteChar(zName);
+ n = strlen30(zName);
+ if( cQuote ) n += n+2;
+ z = p->zDestTable = malloc( n+1 );
+ if( z==0 ) shell_out_of_memory();
+ n = 0;
+ if( cQuote ) z[n++] = cQuote;
+ for(i=0; zName[i]; i++){
+ z[n++] = zName[i];
+ if( zName[i]==cQuote ) z[n++] = cQuote;
+ }
+ if( cQuote ) z[n++] = cQuote;
+ z[n] = 0;
+}
+
+
+/*
+** Execute a query statement that will generate SQL output. Print
+** the result columns, comma-separated, on a line and then add a
+** 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
+** "--" comment occurs at the end of the statement, the comment
+** won't consume the semicolon terminator.
+*/
+static int run_table_dump_query(
+ ShellState *p, /* Query context */
+ const char *zSelect, /* SELECT statement to extract content */
+ const char *zFirstRow /* Print before first row, if not NULL */
+){
+ sqlite3_stmt *pSelect;
+ int rc;
+ int nResult;
+ int i;
+ const char *z;
+ rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
+ if( rc!=SQLITE_OK || !pSelect ){
+ utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
+ sqlite3_errmsg(p->db));
+ if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
+ return rc;
+ }
+ rc = sqlite3_step(pSelect);
+ nResult = sqlite3_column_count(pSelect);
+ while( rc==SQLITE_ROW ){
+ if( zFirstRow ){
+ utf8_printf(p->out, "%s", zFirstRow);
+ zFirstRow = 0;
+ }
+ z = (const char*)sqlite3_column_text(pSelect, 0);
+ utf8_printf(p->out, "%s", z);
+ for(i=1; i<nResult; i++){
+ utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
+ }
+ if( z==0 ) z = "";
+ while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
+ if( z[0] ){
+ raw_printf(p->out, "\n;\n");
+ }else{
+ raw_printf(p->out, ";\n");
+ }
+ rc = sqlite3_step(pSelect);
+ }
+ rc = sqlite3_finalize(pSelect);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
+ sqlite3_errmsg(p->db));
+ if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
+ }
+ return rc;
+}
+
+/*
+** Allocate space and save off current error string.
+*/
+static char *save_err_msg(
+ sqlite3 *db /* Database to query */
+){
+ int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
+ char *zErrMsg = sqlite3_malloc(nErrMsg);
+ if( zErrMsg ){
+ memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
+ }
+ return zErrMsg;
+}
+
+#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 = strlen30(aTrans[i].zPattern);
+ if( strncmp(aTrans[i].zPattern, z, n)==0 ){
+ utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
+ break;
+ }
+ }
+ }
+ fclose(in);
+}
+#endif
+
+/*
+** Display a single line of status using 64-bit values.
+*/
+static void displayStatLine(
+ ShellState *p, /* The shell context */
+ char *zLabel, /* Label for this one line */
+ char *zFormat, /* Format for the result */
+ int iStatusCtrl, /* Which status to display */
+ int bReset /* True to reset the stats */
+){
+ sqlite3_int64 iCur = -1;
+ sqlite3_int64 iHiwtr = -1;
+ int i, nPercent;
+ char zLine[200];
+ sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
+ for(i=0, nPercent=0; zFormat[i]; i++){
+ if( zFormat[i]=='%' ) nPercent++;
+ }
+ if( nPercent>1 ){
+ sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
+ }else{
+ sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
+ }
+ raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
+}
+
+/*
+** Display memory stats.
+*/
+static int display_stats(
+ sqlite3 *db, /* Database to query */
+ ShellState *pArg, /* Pointer to ShellState */
+ int bReset /* True to reset the stats */
+){
+ int iCur;
+ int iHiwtr;
+ FILE *out;
+ if( pArg==0 || pArg->out==0 ) return 0;
+ out = pArg->out;
+
+ if( pArg->pStmt && (pArg->statsOn & 2) ){
+ int nCol, i, x;
+ sqlite3_stmt *pStmt = pArg->pStmt;
+ char z[100];
+ nCol = sqlite3_column_count(pStmt);
+ raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
+ for(i=0; i<nCol; i++){
+ sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
+#ifndef SQLITE_OMIT_DECLTYPE
+ sqlite3_snprintf(30, z+x, "declared type:");
+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
+#endif
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ sqlite3_snprintf(30, z+x, "database name:");
+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
+ sqlite3_snprintf(30, z+x, "table name:");
+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
+ sqlite3_snprintf(30, z+x, "origin name:");
+ utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
+#endif
+ }
+ }
+
+ displayStatLine(pArg, "Memory Used:",
+ "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
+ displayStatLine(pArg, "Number of Outstanding Allocations:",
+ "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
+ if( pArg->shellFlgs & SHFLG_Pagecache ){
+ displayStatLine(pArg, "Number of Pcache Pages Used:",
+ "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
+ }
+ displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
+ "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
+ displayStatLine(pArg, "Largest Allocation:",
+ "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
+ displayStatLine(pArg, "Largest Pcache Allocation:",
+ "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
+#ifdef YYTRACKMAXSTACKDEPTH
+ displayStatLine(pArg, "Deepest Parser Stack:",
+ "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
+#endif
+
+ if( db ){
+ if( pArg->shellFlgs & SHFLG_Lookaside ){
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
+ &iCur, &iHiwtr, bReset);
+ raw_printf(pArg->out,
+ "Lookaside Slots Used: %d (max %d)\n",
+ iCur, iHiwtr);
+ sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
+ &iCur, &iHiwtr, bReset);
+ raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
+ iHiwtr);
+ sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
+ &iCur, &iHiwtr, bReset);
+ raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
+ iHiwtr);
+ sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
+ &iCur, &iHiwtr, bReset);
+ raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
+ iHiwtr);
+ }
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
+ raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
+ iCur);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
+ 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);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
+ raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
+ iHiwtr = iCur = -1;
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
+ raw_printf(pArg->out, "Page cache spills: %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);
+ 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);
+ }
+
+ if( pArg->pStmt ){
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
+ bReset);
+ raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
+ raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
+ raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+ raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
+ raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
+ raw_printf(pArg->out, "Number of times run: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
+ raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
+ }
+
+#ifdef __linux__
+ displayLinuxIoStats(pArg->out);
+#endif
+
+ /* Do not remove this machine readable comment: extra-stats-output-here */
+
+ return 0;
+}
+
+/*
+** Display scan stats.
+*/
+static void display_scanstats(
+ sqlite3 *db, /* Database to query */
+ ShellState *pArg /* Pointer to ShellState */
+){
+#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
+ UNUSED_PARAMETER(db);
+ UNUSED_PARAMETER(pArg);
+#else
+ int i, k, n, mx;
+ raw_printf(pArg->out, "-------- scanstats --------\n");
+ mx = 0;
+ for(k=0; k<=mx; k++){
+ double rEstLoop = 1.0;
+ for(i=n=0; 1; i++){
+ sqlite3_stmt *p = pArg->pStmt;
+ sqlite3_int64 nLoop, nVisit;
+ double rEst;
+ int iSid;
+ const char *zExplain;
+ if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
+ break;
+ }
+ sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
+ if( iSid>mx ) mx = iSid;
+ if( iSid!=k ) continue;
+ if( n==0 ){
+ rEstLoop = (double)nLoop;
+ if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
+ }
+ n++;
+ sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
+ sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
+ 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,
+ " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
+ nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
+ );
+ }
+ }
+ raw_printf(pArg->out, "---------------------------\n");
+#endif
+}
+
+/*
+** Parameter azArray points to a zero-terminated array of strings. zStr
+** points to a single nul-terminated string. Return non-zero if zStr
+** is equal, according to strcmp(), to any of the strings in the array.
+** Otherwise, return zero.
+*/
+static int str_in_array(const char *zStr, const char *const *azArray){
+ int i;
+ for(i=0; azArray[i]; i++){
+ if( 0==strcmp(zStr, azArray[i]) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** 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.
+**
+** The indenting rules are:
+**
+** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
+** all opcodes that occur between the p2 jump destination and the opcode
+** itself by 2 spaces.
+**
+** * For each "Goto", if the jump destination is earlier in the program
+** and ends on one of:
+** Yield SeekGt SeekLt RowSetRead Rewind
+** or if the P1 parameter is one instead of zero,
+** then indent all opcodes between the earlier instruction
+** and "Goto" by 2 spaces.
+*/
+static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
+ const char *zSql; /* The text of the SQL statement */
+ const char *z; /* Used to check if this is an EXPLAIN */
+ int *abYield = 0; /* True if op is an OP_Yield */
+ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
+ int iOp; /* Index of operation in p->aiIndent[] */
+
+ const char *const azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
+ const char *const azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
+ "Rewind", 0 };
+ const char *const azGoto[] = { "Goto", 0 };
+
+ /* Try to figure out if this is really an EXPLAIN statement. If this
+ ** cannot be verified, return early. */
+ if( sqlite3_column_count(pSql)!=8 ){
+ p->cMode = p->mode;
+ return;
+ }
+ zSql = sqlite3_sql(pSql);
+ if( zSql==0 ) return;
+ for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
+ if( sqlite3_strnicmp(z, "explain", 7) ){
+ p->cMode = p->mode;
+ return;
+ }
+
+ for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
+ int i;
+ int iAddr = sqlite3_column_int(pSql, 0);
+ const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
+
+ /* Set p2 to the P2 field of the current opcode. Then, assuming that
+ ** p2 is an instruction address, set variable p2op to the index of that
+ ** instruction in the aiIndent[] array. p2 and p2op may be different if
+ ** the current instruction is part of a sub-program generated by an
+ ** SQL trigger or foreign key. */
+ int p2 = sqlite3_column_int(pSql, 3);
+ int p2op = (p2 + (iOp-iAddr));
+
+ /* Grow the p->aiIndent array as required */
+ if( iOp>=nAlloc ){
+ if( iOp==0 ){
+ /* Do further verfication that this is explain output. Abort if
+ ** it is not */
+ static const char *const explainCols[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
+ int jj;
+ for(jj=0; jj<ArraySize(explainCols); jj++){
+ if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
+ p->cMode = p->mode;
+ sqlite3_reset(pSql);
+ return;
+ }
+ }
+ }
+ nAlloc += 100;
+ p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
+ if( p->aiIndent==0 ) shell_out_of_memory();
+ abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
+ if( abYield==0 ) shell_out_of_memory();
+ }
+ abYield[iOp] = str_in_array(zOp, azYield);
+ p->aiIndent[iOp] = 0;
+ p->nIndent = iOp+1;
+
+ if( str_in_array(zOp, azNext) ){
+ for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
+ }
+ if( str_in_array(zOp, azGoto) && p2op<p->nIndent
+ && (abYield[p2op] || sqlite3_column_int(pSql, 2))
+ ){
+ for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
+ }
+ }
+
+ p->iIndent = 0;
+ sqlite3_free(abYield);
+ sqlite3_reset(pSql);
+}
+
+/*
+** Free the array allocated by explain_data_prepare().
+*/
+static void explain_data_delete(ShellState *p){
+ sqlite3_free(p->aiIndent);
+ p->aiIndent = 0;
+ p->nIndent = 0;
+ p->iIndent = 0;
+}
+
+/*
+** 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 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 ){
+ /* 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( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
+ rc = SQLITE_ABORT;
+ }else{
+ rc = sqlite3_step(pStmt);
+ }
+ }
+ } while( SQLITE_ROW == rc );
+ sqlite3_free(pData);
+ }
+ }
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** This function is called to process SQL if the previous shell command
+** was ".expert". It passes the SQL in the second argument directly to
+** the sqlite3expert object.
+**
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
+** code. In this case, (*pzErr) may be set to point to a buffer containing
+** an English language error message. It is the responsibility of the
+** caller to eventually free this buffer using sqlite3_free().
+*/
+static int expertHandleSQL(
+ ShellState *pState,
+ const char *zSql,
+ char **pzErr
+){
+ assert( pState->expert.pExpert );
+ assert( pzErr==0 || *pzErr==0 );
+ return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr);
+}
+
+/*
+** This function is called either to silently clean up the object
+** created by the ".expert" command (if bCancel==1), or to generate a
+** report from it and then clean it up (if bCancel==0).
+**
+** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
+** code. In this case, (*pzErr) may be set to point to a buffer containing
+** an English language error message. It is the responsibility of the
+** caller to eventually free this buffer using sqlite3_free().
+*/
+static int expertFinish(
+ ShellState *pState,
+ int bCancel,
+ char **pzErr
+){
+ int rc = SQLITE_OK;
+ sqlite3expert *p = pState->expert.pExpert;
+ assert( p );
+ assert( bCancel || pzErr==0 || *pzErr==0 );
+ if( bCancel==0 ){
+ FILE *out = pState->out;
+ int bVerbose = pState->expert.bVerbose;
+
+ rc = sqlite3_expert_analyze(p, pzErr);
+ if( rc==SQLITE_OK ){
+ int nQuery = sqlite3_expert_count(p);
+ int i;
+
+ if( bVerbose ){
+ const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
+ raw_printf(out, "-- Candidates -----------------------------\n");
+ raw_printf(out, "%s\n", zCand);
+ }
+ for(i=0; i<nQuery; i++){
+ const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
+ const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
+ const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
+ if( zIdx==0 ) zIdx = "(no new indexes)\n";
+ if( bVerbose ){
+ raw_printf(out, "-- Query %d --------------------------------\n",i+1);
+ raw_printf(out, "%s\n\n", zSql);
+ }
+ raw_printf(out, "%s\n", zIdx);
+ raw_printf(out, "%s\n", zEQP);
+ }
+ }
+ }
+ sqlite3_expert_destroy(p);
+ pState->expert.pExpert = 0;
+ return rc;
+}
+
+/*
+** Implementation of ".expert" dot command.
+*/
+static int expertDotCommand(
+ ShellState *pState, /* Current shell tool state */
+ char **azArg, /* Array of arguments passed to dot command */
+ int nArg /* Number of entries in azArg[] */
+){
+ int rc = SQLITE_OK;
+ char *zErr = 0;
+ int i;
+ int iSample = 0;
+
+ assert( pState->expert.pExpert==0 );
+ memset(&pState->expert, 0, sizeof(ExpertInfo));
+
+ for(i=1; rc==SQLITE_OK && i<nArg; i++){
+ char *z = azArg[i];
+ int n;
+ if( z[0]=='-' && z[1]=='-' ) z++;
+ n = strlen30(z);
+ if( n>=2 && 0==strncmp(z, "-verbose", n) ){
+ pState->expert.bVerbose = 1;
+ }
+ else if( n>=2 && 0==strncmp(z, "-sample", n) ){
+ if( i==(nArg-1) ){
+ raw_printf(stderr, "option requires an argument: %s\n", z);
+ rc = SQLITE_ERROR;
+ }else{
+ iSample = (int)integerValue(azArg[++i]);
+ if( iSample<0 || iSample>100 ){
+ raw_printf(stderr, "value out of range: %s\n", azArg[i]);
+ rc = SQLITE_ERROR;
+ }
+ }
+ }
+ else{
+ raw_printf(stderr, "unknown option: %s\n", z);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
+ if( pState->expert.pExpert==0 ){
+ raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
+ rc = SQLITE_ERROR;
+ }else{
+ sqlite3_expert_config(
+ pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
+ );
+ }
+ }
+
+ return rc;
+}
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** 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
+** and callback data argument.
+*/
+static int shell_exec(
+ ShellState *pArg, /* Pointer to ShellState */
+ const char *zSql, /* SQL to be evaluated */
+ char **pzErrMsg /* Error msg written here */
+){
+ sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
+ int rc = SQLITE_OK; /* Return Code */
+ int rc2;
+ const char *zLeftover; /* Tail of unprocessed SQL */
+ sqlite3 *db = pArg->db;
+
+ if( pzErrMsg ){
+ *pzErrMsg = NULL;
+ }
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( pArg->expert.pExpert ){
+ rc = expertHandleSQL(pArg, zSql, pzErrMsg);
+ return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
+ }
+#endif
+
+ 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 ){
+ *pzErrMsg = save_err_msg(db);
+ }
+ }else{
+ if( !pStmt ){
+ /* this happens for a comment or white-space */
+ zSql = zLeftover;
+ while( IsSpace(zSql[0]) ) zSql++;
+ continue;
+ }
+ zStmtSql = sqlite3_sql(pStmt);
+ if( zStmtSql==0 ) zStmtSql = "";
+ while( IsSpace(zStmtSql[0]) ) zStmtSql++;
+
+ /* save off the prepared statment handle and reset row count */
+ if( pArg ){
+ pArg->pStmt = pStmt;
+ pArg->cnt = 0;
+ }
+
+ /* echo the sql statement if echo on */
+ if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
+ utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
+ }
+
+ /* Show the EXPLAIN QUERY PLAN if .eqp is on */
+ if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
+ sqlite3_stmt *pExplain;
+ char *zEQP;
+ int triggerEQP = 0;
+ disable_debug_trace_modes();
+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
+ if( pArg->autoEQP>=AUTOEQP_trigger ){
+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
+ }
+ 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 ){
+ const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
+ int iEqpId = sqlite3_column_int(pExplain, 0);
+ int iParentId = sqlite3_column_int(pExplain, 1);
+ if( zEQPLine[0]=='-' ) eqp_render(pArg);
+ eqp_append(pArg, iEqpId, iParentId, zEQPLine);
+ }
+ eqp_render(pArg);
+ }
+ sqlite3_finalize(pExplain);
+ sqlite3_free(zEQP);
+ if( pArg->autoEQP>=AUTOEQP_full ){
+ /* 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);
+ explain_data_delete(pArg);
+ }
+ sqlite3_finalize(pExplain);
+ sqlite3_free(zEQP);
+ }
+ if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
+ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
+ /* Reprepare pStmt before reactiving trace modes */
+ sqlite3_finalize(pStmt);
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ if( pArg ) pArg->pStmt = pStmt;
+ }
+ restore_debug_trace_modes();
+ }
+
+ if( pArg ){
+ pArg->cMode = pArg->mode;
+ if( pArg->autoExplain ){
+ if( sqlite3_column_count(pStmt)==8
+ && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
+ ){
+ pArg->cMode = MODE_Explain;
+ }
+ if( sqlite3_column_count(pStmt)==4
+ && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){
+ pArg->cMode = MODE_EQP;
+ }
+ }
+
+ /* If the shell is currently in ".explain" mode, gather the extra
+ ** data required to add indents to the output.*/
+ if( pArg->cMode==MODE_Explain ){
+ explain_data_prepare(pArg, pStmt);
+ }
+ }
+
+ exec_prepared_stmt(pArg, pStmt);
+ explain_data_delete(pArg);
+ eqp_render(pArg);
+
+ /* print usage stats if stats on */
+ if( pArg && pArg->statsOn ){
+ display_stats(db, pArg, 0);
+ }
+
+ /* print loop-counters if required */
+ if( pArg && pArg->scanstatsOn ){
+ display_scanstats(db, pArg);
+ }
+
+ /* Finalize the statement just executed. If this fails, save a
+ ** copy of the error message. Otherwise, set zSql to point to the
+ ** next statement to execute. */
+ rc2 = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_NOMEM ) rc = rc2;
+ if( rc==SQLITE_OK ){
+ zSql = zLeftover;
+ while( IsSpace(zSql[0]) ) zSql++;
+ }else if( pzErrMsg ){
+ *pzErrMsg = save_err_msg(db);
+ }
+
+ /* clear saved stmt handle */
+ if( pArg ){
+ pArg->pStmt = NULL;
+ }
+ }
+ } /* end while */
+
+ return rc;
+}
+
+/*
+** Release memory previously allocated by tableColumnList().
+*/
+static void freeColumnList(char **azCol){
+ int i;
+ for(i=1; azCol[i]; i++){
+ sqlite3_free(azCol[i]);
+ }
+ /* azCol[0] is a static string */
+ sqlite3_free(azCol);
+}
+
+/*
+** Return a list of pointers to strings which are the names of all
+** columns in table zTab. The memory to hold the names is dynamically
+** allocated and must be released by the caller using a subsequent call
+** to freeColumnList().
+**
+** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
+** value that needs to be preserved, then azCol[0] is filled in with the
+** name of the rowid column.
+**
+** The first regular column in the table is azCol[1]. The list is terminated
+** by an entry with azCol[i]==0.
+*/
+static char **tableColumnList(ShellState *p, const char *zTab){
+ char **azCol = 0;
+ sqlite3_stmt *pStmt;
+ char *zSql;
+ int nCol = 0;
+ int nAlloc = 0;
+ int nPK = 0; /* Number of PRIMARY KEY columns seen */
+ int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
+ int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
+ int rc;
+
+ zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( rc ) return 0;
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ if( nCol>=nAlloc-2 ){
+ nAlloc = nAlloc*2 + nCol + 10;
+ azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
+ if( azCol==0 ) shell_out_of_memory();
+ }
+ azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
+ if( sqlite3_column_int(pStmt, 5) ){
+ nPK++;
+ if( nPK==1
+ && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
+ "INTEGER")==0
+ ){
+ isIPK = 1;
+ }else{
+ isIPK = 0;
+ }
+ }
+ }
+ sqlite3_finalize(pStmt);
+ if( azCol==0 ) return 0;
+ azCol[0] = 0;
+ azCol[nCol+1] = 0;
+
+ /* The decision of whether or not a rowid really needs to be preserved
+ ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
+ ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
+ ** rowids on tables where the rowid is inaccessible because there are other
+ ** columns in the table named "rowid", "_rowid_", and "oid".
+ */
+ if( preserveRowid && isIPK ){
+ /* If a single PRIMARY KEY column with type INTEGER was seen, then it
+ ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
+ ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
+ ** ROWID aliases. To distinguish these cases, check to see if
+ ** there is a "pk" entry in "PRAGMA index_list". There will be
+ ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
+ */
+ zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
+ " WHERE origin='pk'", zTab);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( rc ){
+ freeColumnList(azCol);
+ return 0;
+ }
+ rc = sqlite3_step(pStmt);
+ sqlite3_finalize(pStmt);
+ preserveRowid = rc==SQLITE_ROW;
+ }
+ if( preserveRowid ){
+ /* Only preserve the rowid if we can find a name to use for the
+ ** rowid */
+ static char *azRowid[] = { "rowid", "_rowid_", "oid" };
+ int i, j;
+ for(j=0; j<3; j++){
+ for(i=1; i<=nCol; i++){
+ if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
+ }
+ if( i>nCol ){
+ /* At this point, we know that azRowid[j] is not the name of any
+ ** ordinary column in the table. Verify that azRowid[j] is a valid
+ ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
+ ** tables will fail this last check */
+ rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
+ if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
+ break;
+ }
+ }
+ }
+ return azCol;
+}
+
+/*
+** Toggle the reverse_unordered_selects setting.
+*/
+static void toggleSelectOrder(sqlite3 *db){
+ sqlite3_stmt *pStmt = 0;
+ int iSetting = 0;
+ char zStmt[100];
+ sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
+ iSetting = sqlite3_column_int(pStmt, 0);
+ }
+ sqlite3_finalize(pStmt);
+ sqlite3_snprintf(sizeof(zStmt), zStmt,
+ "PRAGMA reverse_unordered_selects(%d)", !iSetting);
+ sqlite3_exec(db, zStmt, 0, 0, 0);
+}
+
+/*
+** This is a different callback routine used for dumping the database.
+** Each row received by this callback consists of a table name,
+** the table type ("index" or "table") and SQL to create the table.
+** This routine should print text sufficient to recreate the table.
+*/
+static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
+ int rc;
+ const char *zTable;
+ const char *zType;
+ const char *zSql;
+ ShellState *p = (ShellState *)pArg;
+
+ UNUSED_PARAMETER(azNotUsed);
+ if( nArg!=3 || azArg==0 ) return 0;
+ zTable = azArg[0];
+ zType = azArg[1];
+ zSql = azArg[2];
+
+ if( strcmp(zTable, "sqlite_sequence")==0 ){
+ raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
+ }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
+ raw_printf(p->out, "ANALYZE sqlite_master;\n");
+ }else if( strncmp(zTable, "sqlite_", 7)==0 ){
+ return 0;
+ }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
+ char *zIns;
+ if( !p->writableSchema ){
+ raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
+ p->writableSchema = 1;
+ }
+ zIns = sqlite3_mprintf(
+ "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
+ "VALUES('table','%q','%q',0,'%q');",
+ zTable, zTable, zSql);
+ utf8_printf(p->out, "%s\n", zIns);
+ sqlite3_free(zIns);
+ return 0;
+ }else{
+ printSchemaLine(p->out, zSql, ";\n");
+ }
+
+ if( strcmp(zType, "table")==0 ){
+ ShellText sSelect;
+ ShellText sTable;
+ char **azCol;
+ int i;
+ char *savedDestTable;
+ int savedMode;
+
+ azCol = tableColumnList(p, zTable);
+ if( azCol==0 ){
+ p->nErr++;
+ return 0;
+ }
+
+ /* Always quote the table name, even if it appears to be pure ascii,
+ ** in case it is a keyword. Ex: INSERT INTO "table" ... */
+ initText(&sTable);
+ appendText(&sTable, zTable, quoteChar(zTable));
+ /* If preserving the rowid, add a column list after the table name.
+ ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
+ ** instead of the usual "INSERT INTO tab VALUES(...)".
+ */
+ if( azCol[0] ){
+ appendText(&sTable, "(", 0);
+ appendText(&sTable, azCol[0], 0);
+ for(i=1; azCol[i]; i++){
+ appendText(&sTable, ",", 0);
+ appendText(&sTable, azCol[i], quoteChar(azCol[i]));
+ }
+ appendText(&sTable, ")", 0);
+ }
+
+ /* Build an appropriate SELECT statement */
+ initText(&sSelect);
+ appendText(&sSelect, "SELECT ", 0);
+ if( azCol[0] ){
+ appendText(&sSelect, azCol[0], 0);
+ appendText(&sSelect, ",", 0);
+ }
+ for(i=1; azCol[i]; i++){
+ appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
+ if( azCol[i+1] ){
+ appendText(&sSelect, ",", 0);
+ }
+ }
+ freeColumnList(azCol);
+ appendText(&sSelect, " FROM ", 0);
+ appendText(&sSelect, zTable, quoteChar(zTable));
+
+ savedDestTable = p->zDestTable;
+ savedMode = p->mode;
+ p->zDestTable = sTable.z;
+ p->mode = p->cMode = MODE_Insert;
+ rc = shell_exec(p, sSelect.z, 0);
+ if( (rc&0xff)==SQLITE_CORRUPT ){
+ raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
+ toggleSelectOrder(p->db);
+ shell_exec(p, sSelect.z, 0);
+ toggleSelectOrder(p->db);
+ }
+ p->zDestTable = savedDestTable;
+ p->mode = savedMode;
+ freeText(&sTable);
+ freeText(&sSelect);
+ if( rc ) p->nErr++;
+ }
+ return 0;
+}
+
+/*
+** Run zQuery. Use dump_callback() as the callback routine so that
+** the contents of the query are output as SQL statements.
+**
+** If we get a SQLITE_CORRUPT error, rerun the query after appending
+** "ORDER BY rowid DESC" to the end.
+*/
+static int run_schema_dump_query(
+ ShellState *p,
+ const char *zQuery
+){
+ int rc;
+ char *zErr = 0;
+ rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
+ if( rc==SQLITE_CORRUPT ){
+ char *zQ2;
+ int len = strlen30(zQuery);
+ raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
+ if( zErr ){
+ utf8_printf(p->out, "/****** %s ******/\n", zErr);
+ sqlite3_free(zErr);
+ zErr = 0;
+ }
+ zQ2 = malloc( len+100 );
+ if( zQ2==0 ) return rc;
+ sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
+ rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
+ if( rc ){
+ utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
+ }else{
+ rc = SQLITE_CORRUPT;
+ }
+ sqlite3_free(zErr);
+ free(zQ2);
+ }
+ return rc;
+}
+
+/*
+** Text of help messages.
+**
+** The help text for each individual command begins with a line that starts
+** with ".". Subsequent lines are supplimental information.
+**
+** There must be two or more spaces between the end of the command and the
+** start of the description of what that command does.
+*/
+static const char *(azHelp[]) = {
+#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+ ".archive ... Manage SQL archives",
+ " Each command must have exactly one of the following options:",
+ " -c, --create Create a new archive",
+ " -u, --update Update or add files to an existing archive",
+ " -t, --list List contents of archive",
+ " -x, --extract Extract files from archive",
+ " Optional arguments:",
+ " -v, --verbose Print each filename as it is processed",
+ " -f FILE, --file FILE Operate on archive FILE (default is current db)",
+ " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
+ " -C DIR, --directory DIR Change to directory DIR to read/extract files",
+ " -n, --dryrun Show the SQL that would have occurred",
+ " Examples:",
+ " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
+ " .ar -tf archive.sar # List members of archive.sar",
+ " .ar -xvf archive.sar # Verbosely extract files from archive.sar",
+ " See also:",
+ " http://sqlite.org/cli.html#sqlar_archive_support",
+#endif
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ ".auth ON|OFF Show authorizer callbacks",
+#endif
+ ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
+ " --append Use the appendvfs",
+ ".bail on|off Stop after hitting an error. Default OFF",
+ ".binary on|off Turn binary output on or off. Default OFF",
+ ".cd DIRECTORY Change the working directory to DIRECTORY",
+ ".changes on|off Show number of rows changed by SQL",
+ ".check GLOB Fail if output since .testcase does not match",
+ ".clone NEWDB Clone data into NEWDB from the existing database",
+ ".databases List names and files of attached databases",
+ ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
+ ".dbinfo ?DB? Show status information about the database",
+ ".dump ?TABLE? ... Render all database content as SQL",
+ " Options:",
+ " --preserve-rowids Include ROWID values in the output",
+ " --newlines Allow unescaped newline characters in output",
+ " TABLE is LIKE pattern for the tables to dump",
+ ".echo on|off Turn command echo on or off",
+ ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN",
+ ".excel Display the output of next command in a spreadsheet",
+ ".exit ?CODE? Exit this program with return-code CODE",
+ ".expert EXPERIMENTAL. Suggest indexes for specified queries",
+/* Because explain mode comes on automatically now, the ".explain" mode
+** is removed from the help screen. It is still supported for legacy, however */
+/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
+ ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
+ ".headers on|off Turn display of headers on or off",
+ ".help ?-all? ?PATTERN? Show help text for PATTERN",
+ ".import FILE TABLE Import data from FILE into TABLE",
+#ifndef SQLITE_OMIT_TEST_CONTROL
+ ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
+#endif
+ ".indexes ?TABLE? Show names of indexes",
+ " If TABLE is specified, only show indexes for",
+ " tables matching TABLE using the LIKE operator.",
+#ifdef SQLITE_ENABLE_IOTRACE
+ ".iotrace FILE Enable I/O diagnostic logging to FILE",
+#endif
+ ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
+ ".lint OPTIONS Report potential schema issues.",
+ " Options:",
+ " fkey-indexes Find missing foreign key indexes",
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ ".load FILE ?ENTRY? Load an extension library",
+#endif
+ ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
+ ".mode MODE ?TABLE? Set output mode",
+ " MODE is one of:",
+ " ascii Columns/rows delimited by 0x1F and 0x1E",
+ " csv Comma-separated values",
+ " column Left-aligned columns. (See .width)",
+ " html HTML <table> code",
+ " insert SQL insert statements for TABLE",
+ " line One value per line",
+ " list Values delimited by \"|\"",
+ " quote Escape answers as for SQL",
+ " tabs Tab-separated values",
+ " tcl TCL list elements",
+ ".nullvalue STRING Use STRING in place of NULL values",
+ ".once (-e|-x|FILE) Output for the next SQL command only to FILE",
+ " If FILE begins with '|' then open as a pipe",
+ " Other options:",
+ " -e Invoke system text editor",
+ " -x Open in a spreadsheet",
+ ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
+ " Options:",
+ " --append Use appendvfs to append database to the end of FILE",
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ " --deserialize Load into memory useing sqlite3_deserialize()",
+#endif
+ " --new Initialize FILE to an empty database",
+ " --readonly Open FILE readonly",
+ " --zip FILE is a ZIP archive",
+ ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
+ " If FILE begins with '|' then open it as a pipe.",
+ ".print STRING... Print literal STRING",
+ ".prompt MAIN CONTINUE Replace the standard prompts",
+ ".quit Exit this program",
+ ".read FILE Read input from FILE",
+ ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
+ ".save FILE Write in-memory database into FILE",
+ ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
+ ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
+ " Options:",
+ " --indent Try to pretty-print the schema",
+#ifdef SQLITE_DEBUG
+ ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
+ " Options:",
+ " --init Create a new SELFTEST table",
+ " -v Verbose output",
+#endif
+ ".separator COL ?ROW? Change the column and row separators",
+#if defined(SQLITE_ENABLE_SESSION)
+ ".session ?NAME? CMD ... Create or control sessions",
+ " Subcommands:",
+ " attach TABLE Attach TABLE",
+ " changeset FILE Write a changeset into FILE",
+ " close Close one session",
+ " enable ?BOOLEAN? Set or query the enable bit",
+ " filter GLOB... Reject tables matching GLOBs",
+ " indirect ?BOOLEAN? Mark or query the indirect status",
+ " isempty Query whether the session is empty",
+ " list List currently open session names",
+ " open DB NAME Open a new session on DB",
+ " patchset FILE Write a patchset into FILE",
+ " If ?NAME? is omitted, the first defined session is used.",
+#endif
+ ".sha3sum ... Compute a SHA3 hash of database content",
+ " Options:",
+ " --schema Also hash the sqlite_master table",
+ " --sha3-224 Use the sha3-224 algorithm",
+ " --sha3-256 Use the sha3-256 algorithm. This is the default.",
+ " --sha3-384 Use the sha3-384 algorithm",
+ " --sha3-512 Use the sha3-512 algorithm",
+ " Any other argument is a LIKE pattern for tables to hash",
+#ifndef SQLITE_NOHAVE_SYSTEM
+ ".shell CMD ARGS... Run CMD ARGS... in a system shell",
+#endif
+ ".show Show the current values for various settings",
+ ".stats ?on|off? Show stats or turn stats on or off",
+#ifndef SQLITE_NOHAVE_SYSTEM
+ ".system CMD ARGS... Run CMD ARGS... in a system shell",
+#endif
+ ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
+ ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
+ ".timeout MS Try opening locked tables for MS milliseconds",
+ ".timer on|off Turn SQL timer on or off",
+ ".trace FILE|off Output each SQL statement as it is run",
+ ".vfsinfo ?AUX? Information about the top-level VFS",
+ ".vfslist List all available VFSes",
+ ".vfsname ?AUX? Print the name of the VFS stack",
+ ".width NUM1 NUM2 ... Set column widths for \"column\" mode",
+ " Negative values right-justify",
+};
+
+/*
+** Output help text.
+**
+** zPattern describes the set of commands for which help text is provided.
+** If zPattern is NULL, then show all commands, but only give a one-line
+** description of each.
+**
+** Return the number of matches.
+*/
+static int showHelp(FILE *out, const char *zPattern){
+ int i = 0;
+ int j = 0;
+ int n = 0;
+ char *zPat;
+ if( zPattern==0
+ || zPattern[0]=='0'
+ || strcmp(zPattern,"-a")==0
+ || strcmp(zPattern,"-all")==0
+ ){
+ /* Show all commands, but only one line per command */
+ if( zPattern==0 ) zPattern = "";
+ for(i=0; i<ArraySize(azHelp); i++){
+ if( azHelp[i][0]=='.' || zPattern[0] ){
+ utf8_printf(out, "%s\n", azHelp[i]);
+ n++;
+ }
+ }
+ }else{
+ /* Look for commands that for which zPattern is an exact prefix */
+ zPat = sqlite3_mprintf(".%s*", zPattern);
+ for(i=0; i<ArraySize(azHelp); i++){
+ if( sqlite3_strglob(zPat, azHelp[i])==0 ){
+ utf8_printf(out, "%s\n", azHelp[i]);
+ j = i+1;
+ n++;
+ }
+ }
+ sqlite3_free(zPat);
+ if( n ){
+ if( n==1 ){
+ /* when zPattern is a prefix of exactly one command, then include the
+ ** details of that command, which should begin at offset j */
+ while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
+ utf8_printf(out, "%s\n", azHelp[j]);
+ j++;
+ }
+ }
+ return n;
+ }
+ /* Look for commands that contain zPattern anywhere. Show the complete
+ ** text of all commands that match. */
+ zPat = sqlite3_mprintf("%%%s%%", zPattern);
+ for(i=0; i<ArraySize(azHelp); i++){
+ if( azHelp[i][0]=='.' ) j = i;
+ if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
+ utf8_printf(out, "%s\n", azHelp[j]);
+ while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
+ j++;
+ utf8_printf(out, "%s\n", azHelp[j]);
+ }
+ i = j;
+ n++;
+ }
+ }
+ sqlite3_free(zPat);
+ }
+ return n;
+}
+
+/* Forward reference */
+static int process_input(ShellState *p, FILE *in);
+
+/*
+** Read the content of file zName into memory obtained from sqlite3_malloc64()
+** and return a pointer to the buffer. The caller is responsible for freeing
+** the memory.
+**
+** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
+** read.
+**
+** For convenience, a nul-terminator byte is always appended to the data read
+** from the file before the buffer is returned. This byte is not included in
+** the final value of (*pnByte), if applicable.
+**
+** NULL is returned if any error is encountered. The final value of *pnByte
+** is undefined in this case.
+*/
+static char *readFile(const char *zName){
+ FILE *in = fopen(zName, "rb");
+ size_t nIn;
+ size_t nRead;
+ char *pBuf;
+ if( in==0 ) return 0;
+ fseek(in, 0, SEEK_END);
+ nIn = ftell(in);
+ rewind(in);
+ pBuf = sqlite3_malloc( nIn+1 );
+ if( pBuf==0 ){ fclose(in); return 0; }
+ nRead = fread(pBuf, nIn, 1, in);
+ fclose(in);
+ if( nRead!=1 ){
+ sqlite3_free(pBuf);
+ return 0;
+ }
+ pBuf[nIn] = 0;
+ return pBuf;
+}
+
+#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
+
+/*
+** Try to deduce the type of file for zName based on its content. Return
+** one of the SHELL_OPEN_* constants.
+**
+** If the file does not exist or is empty but its name looks like a ZIP
+** archive and the dfltZip flag is true, then assume it is a ZIP archive.
+** Otherwise, assume an ordinary database regardless of the filename if
+** the type cannot be determined from content.
+*/
+int deduceDatabaseType(const char *zName, int dfltZip){
+ FILE *f = fopen(zName, "rb");
+ size_t n;
+ int rc = SHELL_OPEN_UNSPEC;
+ char zBuf[100];
+ if( f==0 ){
+ if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
+ return SHELL_OPEN_ZIPFILE;
+ }else{
+ return SHELL_OPEN_NORMAL;
+ }
+ }
+ n = fread(zBuf, 16, 1, f);
+ if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
+ fclose(f);
+ return SHELL_OPEN_NORMAL;
+ }
+ fseek(f, -25, SEEK_END);
+ n = fread(zBuf, 25, 1, f);
+ if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
+ rc = SHELL_OPEN_APPENDVFS;
+ }else{
+ fseek(f, -22, SEEK_END);
+ n = fread(zBuf, 22, 1, f);
+ if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
+ && zBuf[3]==0x06 ){
+ rc = SHELL_OPEN_ZIPFILE;
+ }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
+ rc = SHELL_OPEN_ZIPFILE;
+ }
+ }
+ fclose(f);
+ return rc;
+}
+
+/* Flags for open_db().
+**
+** The default behavior of open_db() is to exit(1) if the database fails to
+** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
+** but still returns without calling exit.
+**
+** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
+** ZIP archive if the file does not exist or is empty and its name matches
+** the *.zip pattern.
+*/
+#define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */
+#define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */
+
+/*
+** Make sure the database is open. If it is not, then open it. If
+** the database fails to open, print an error message and exit.
+*/
+static void open_db(ShellState *p, int openFlags){
+ if( p->db==0 ){
+ if( p->openMode==SHELL_OPEN_UNSPEC ){
+ if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
+ p->openMode = SHELL_OPEN_NORMAL;
+ }else{
+ p->openMode = (u8)deduceDatabaseType(p->zDbFilename,
+ (openFlags & OPEN_DB_ZIPFILE)!=0);
+ }
+ }
+ switch( p->openMode ){
+ case SHELL_OPEN_APPENDVFS: {
+ sqlite3_open_v2(p->zDbFilename, &p->db,
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
+ break;
+ }
+ case SHELL_OPEN_DESERIALIZE: {
+ sqlite3_open(0, &p->db);
+ break;
+ }
+ case SHELL_OPEN_ZIPFILE: {
+ sqlite3_open(":memory:", &p->db);
+ break;
+ }
+ case SHELL_OPEN_READONLY: {
+ sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
+ break;
+ }
+ case SHELL_OPEN_UNSPEC:
+ case SHELL_OPEN_NORMAL: {
+ sqlite3_open(p->zDbFilename, &p->db);
+ break;
+ }
+ }
+ globalDb = p->db;
+ if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
+ utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
+ p->zDbFilename, sqlite3_errmsg(p->db));
+ if( openFlags & OPEN_DB_KEEPALIVE ) return;
+ exit(1);
+ }
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ sqlite3_enable_load_extension(p->db, 1);
+#endif
+ sqlite3_fileio_init(p->db, 0, 0);
+ sqlite3_shathree_init(p->db, 0, 0);
+ sqlite3_completion_init(p->db, 0, 0);
+#ifdef SQLITE_HAVE_ZLIB
+ sqlite3_zipfile_init(p->db, 0, 0);
+ sqlite3_sqlar_init(p->db, 0, 0);
+#endif
+ sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
+ shellAddSchemaName, 0, 0);
+ sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
+ shellModuleSchema, 0, 0);
+ sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
+ shellPutsFunc, 0, 0);
+#ifndef SQLITE_NOHAVE_SYSTEM
+ sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
+ editFunc, 0, 0);
+ sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
+ editFunc, 0, 0);
+#endif
+ if( p->openMode==SHELL_OPEN_ZIPFILE ){
+ char *zSql = sqlite3_mprintf(
+ "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
+ sqlite3_exec(p->db, zSql, 0, 0, 0);
+ sqlite3_free(zSql);
+ }
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
+ int nData = 0;
+ unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
+ int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
+ SQLITE_DESERIALIZE_RESIZEABLE |
+ SQLITE_DESERIALIZE_FREEONCLOSE);
+ if( rc ){
+ utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
+ }
+ }
+#endif
+ }
+}
+
+/*
+** Attempt to close the databaes connection. Report errors.
+*/
+void close_db(sqlite3 *db){
+ int rc = sqlite3_close(db);
+ if( rc ){
+ utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
+ rc, sqlite3_errmsg(db));
+ }
+}
+
+#if HAVE_READLINE || HAVE_EDITLINE
+/*
+** Readline completion callbacks
+*/
+static char *readline_completion_generator(const char *text, int state){
+ static sqlite3_stmt *pStmt = 0;
+ char *zRet;
+ if( state==0 ){
+ char *zSql;
+ sqlite3_finalize(pStmt);
+ zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
+ " FROM completion(%Q) ORDER BY 1", text);
+ sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ }
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
+ zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
+ }else{
+ sqlite3_finalize(pStmt);
+ pStmt = 0;
+ zRet = 0;
+ }
+ return zRet;
+}
+static char **readline_completion(const char *zText, int iStart, int iEnd){
+ rl_attempted_completion_over = 1;
+ return rl_completion_matches(zText, readline_completion_generator);
+}
+
+#elif HAVE_LINENOISE
+/*
+** Linenoise completion callback
+*/
+static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
+ int nLine = strlen30(zLine);
+ int i, iStart;
+ sqlite3_stmt *pStmt = 0;
+ char *zSql;
+ char zBuf[1000];
+
+ if( nLine>sizeof(zBuf)-30 ) return;
+ if( zLine[0]=='.' || zLine[0]=='#') return;
+ for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
+ if( i==nLine-1 ) return;
+ iStart = i+1;
+ memcpy(zBuf, zLine, iStart);
+ zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
+ " FROM completion(%Q,%Q) ORDER BY 1",
+ &zLine[iStart], zLine);
+ sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
+ int nCompletion = sqlite3_column_bytes(pStmt, 0);
+ if( iStart+nCompletion < sizeof(zBuf)-1 ){
+ memcpy(zBuf+iStart, zCompletion, nCompletion+1);
+ linenoiseAddCompletion(lc, zBuf);
+ }
+ }
+ sqlite3_finalize(pStmt);
+}
+#endif
+
+/*
+** Do C-language style dequoting.
+**
+** \a -> alarm
+** \b -> backspace
+** \t -> tab
+** \n -> newline
+** \v -> vertical tab
+** \f -> form feed
+** \r -> carriage return
+** \s -> space
+** \" -> "
+** \' -> '
+** \\ -> backslash
+** \NNN -> ascii character NNN in octal
+*/
+static void resolve_backslashes(char *z){
+ int i, j;
+ char c;
+ while( *z && *z!='\\' ) z++;
+ for(i=j=0; (c = z[i])!=0; i++, j++){
+ if( c=='\\' && z[i+1]!=0 ){
+ c = z[++i];
+ if( c=='a' ){
+ c = '\a';
+ }else if( c=='b' ){
+ c = '\b';
+ }else if( c=='t' ){
+ c = '\t';
+ }else if( c=='n' ){
+ c = '\n';
+ }else if( c=='v' ){
+ c = '\v';
+ }else if( c=='f' ){
+ c = '\f';
+ }else if( c=='r' ){
+ c = '\r';
+ }else if( c=='"' ){
+ c = '"';
+ }else if( c=='\'' ){
+ c = '\'';
+ }else if( c=='\\' ){
+ c = '\\';
+ }else if( c>='0' && c<='7' ){
+ c -= '0';
+ if( z[i+1]>='0' && z[i+1]<='7' ){
+ i++;
+ c = (c<<3) + z[i] - '0';
+ if( z[i+1]>='0' && z[i+1]<='7' ){
+ i++;
+ c = (c<<3) + z[i] - '0';
+ }
+ }
+ }
+ }
+ z[j] = c;
+ }
+ if( j<i ) z[j] = 0;
+}
+
+/*
+** 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(const char *zArg){
+ int i;
+ if( zArg[0]=='0' && zArg[1]=='x' ){
+ for(i=2; hexDigitValue(zArg[i])>=0; i++){}
+ }else{
+ for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
+ }
+ if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
+ if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
+ return 1;
+ }
+ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
+ return 0;
+ }
+ utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
+ zArg);
+ return 0;
+}
+
+/*
+** Set or clear a shell flag according to a boolean value.
+*/
+static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
+ if( booleanValue(zArg) ){
+ ShellSetFlag(p, mFlag);
+ }else{
+ ShellClearFlag(p, mFlag);
+ }
+}
+
+/*
+** Close an output file, assuming it is not stderr or stdout
+*/
+static void output_file_close(FILE *f){
+ if( f && f!=stdout && f!=stderr ) fclose(f);
+}
+
+/*
+** Try to open an output file. The names "stdout" and "stderr" are
+** recognized and do the right thing. NULL is returned if the output
+** filename is "off".
+*/
+static FILE *output_file_open(const char *zFile, int bTextMode){
+ FILE *f;
+ if( strcmp(zFile,"stdout")==0 ){
+ f = stdout;
+ }else if( strcmp(zFile, "stderr")==0 ){
+ f = stderr;
+ }else if( strcmp(zFile, "off")==0 ){
+ f = 0;
+ }else{
+ f = fopen(zFile, bTextMode ? "w" : "wb");
+ if( f==0 ){
+ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
+ }
+ }
+ return f;
+}
+
+#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
+/*
+** A routine for handling output from sqlite3_trace().
+*/
+static int sql_trace_callback(
+ unsigned mType,
+ void *pArg,
+ void *pP,
+ void *pX
+){
+ FILE *f = (FILE*)pArg;
+ UNUSED_PARAMETER(mType);
+ UNUSED_PARAMETER(pP);
+ if( f ){
+ const char *z = (const char*)pX;
+ int i = strlen30(z);
+ while( i>0 && z[i-1]==';' ){ i--; }
+ utf8_printf(f, "%.*s;\n", i, z);
+ }
+ return 0;
+}
+#endif
+
+/*
+** A no-op routine that runs with the ".breakpoint" doc-command. This is
+** a useful spot to set a debugger breakpoint.
+*/
+static void test_breakpoint(void){
+ static int nCall = 0;
+ nCall++;
+}
+
+/*
+** An object used to read a CSV and other files for import.
+*/
+typedef struct ImportCtx ImportCtx;
+struct ImportCtx {
+ const char *zFile; /* Name of the input file */
+ FILE *in; /* Read the CSV text from this input stream */
+ char *z; /* Accumulated text for a field */
+ int n; /* Number of bytes in z */
+ int nAlloc; /* Space allocated for z[] */
+ int nLine; /* Current line number */
+ int bNotFirst; /* True if one or more bytes already read */
+ int cTerm; /* Character that terminated the most recent field */
+ int cColSep; /* The column separator character. (Usually ",") */
+ int cRowSep; /* The row separator character. (Usually "\n") */
+};
+
+/* Append a single byte to z[] */
+static void import_append_char(ImportCtx *p, int c){
+ if( p->n+1>=p->nAlloc ){
+ p->nAlloc += p->nAlloc + 100;
+ p->z = sqlite3_realloc(p->z, p->nAlloc);
+ if( p->z==0 ) shell_out_of_memory();
+ }
+ p->z[p->n++] = (char)c;
+}
+
+/* Read a single field of CSV text. Compatible with rfc4180 and extended
+** with the option of having a separator other than ",".
+**
+** + Input comes from p->in.
+** + Store results in p->z of length p->n. Space to hold p->z comes
+** from sqlite3_malloc64().
+** + Use p->cSep as the column separator. The default is ",".
+** + Use p->rSep as the row separator. The default is "\n".
+** + Keep track of the line number in p->nLine.
+** + Store the character that terminates the field in p->cTerm. Store
+** EOF on end-of-file.
+** + Report syntax errors on stderr
+*/
+static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
+ int c;
+ int cSep = p->cColSep;
+ int rSep = p->cRowSep;
+ p->n = 0;
+ c = fgetc(p->in);
+ if( c==EOF || seenInterrupt ){
+ p->cTerm = EOF;
+ return 0;
+ }
+ if( c=='"' ){
+ int pc, ppc;
+ int startLine = p->nLine;
+ int cQuote = c;
+ pc = ppc = 0;
+ while( 1 ){
+ c = fgetc(p->in);
+ if( c==rSep ) p->nLine++;
+ if( c==cQuote ){
+ if( pc==cQuote ){
+ pc = 0;
+ continue;
+ }
+ }
+ if( (c==cSep && pc==cQuote)
+ || (c==rSep && pc==cQuote)
+ || (c==rSep && pc=='\r' && ppc==cQuote)
+ || (c==EOF && pc==cQuote)
+ ){
+ do{ p->n--; }while( p->z[p->n]!=cQuote );
+ p->cTerm = c;
+ break;
+ }
+ if( pc==cQuote && c!='\r' ){
+ utf8_printf(stderr, "%s:%d: unescaped %c character\n",
+ p->zFile, p->nLine, cQuote);
+ }
+ if( c==EOF ){
+ utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
+ p->zFile, startLine, cQuote);
+ p->cTerm = c;
+ break;
+ }
+ import_append_char(p, c);
+ ppc = pc;
+ pc = c;
+ }
+ }else{
+ /* If this is the first field being parsed and it begins with the
+ ** UTF-8 BOM (0xEF BB BF) then skip the BOM */
+ if( (c&0xff)==0xef && p->bNotFirst==0 ){
+ import_append_char(p, c);
+ c = fgetc(p->in);
+ if( (c&0xff)==0xbb ){
+ import_append_char(p, c);
+ c = fgetc(p->in);
+ if( (c&0xff)==0xbf ){
+ p->bNotFirst = 1;
+ p->n = 0;
+ return csv_read_one_field(p);
+ }
+ }
+ }
+ while( c!=EOF && c!=cSep && c!=rSep ){
+ import_append_char(p, c);
+ c = fgetc(p->in);
+ }
+ if( c==rSep ){
+ p->nLine++;
+ if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
+ }
+ p->cTerm = c;
+ }
+ if( p->z ) p->z[p->n] = 0;
+ p->bNotFirst = 1;
+ return p->z;
+}
+
+/* Read a single field of ASCII delimited text.
+**
+** + Input comes from p->in.
+** + Store results in p->z of length p->n. Space to hold p->z comes
+** from sqlite3_malloc64().
+** + Use p->cSep as the column separator. The default is "\x1F".
+** + Use p->rSep as the row separator. The default is "\x1E".
+** + Keep track of the row number in p->nLine.
+** + Store the character that terminates the field in p->cTerm. Store
+** EOF on end-of-file.
+** + Report syntax errors on stderr
+*/
+static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
+ int c;
+ int cSep = p->cColSep;
+ int rSep = p->cRowSep;
+ p->n = 0;
+ c = fgetc(p->in);
+ if( c==EOF || seenInterrupt ){
+ p->cTerm = EOF;
+ return 0;
+ }
+ while( c!=EOF && c!=cSep && c!=rSep ){
+ import_append_char(p, c);
+ c = fgetc(p->in);
+ }
+ if( c==rSep ){
+ p->nLine++;
+ }
+ p->cTerm = c;
+ if( p->z ) p->z[p->n] = 0;
+ return p->z;
+}
+
+/*
+** Try to transfer data for table zTable. If an error is seen while
+** moving forward, try to go backwards. The backwards movement won't
+** work for WITHOUT ROWID tables.
+*/
+static void tryToCloneData(
+ ShellState *p,
+ sqlite3 *newDb,
+ const char *zTable
+){
+ sqlite3_stmt *pQuery = 0;
+ sqlite3_stmt *pInsert = 0;
+ char *zQuery = 0;
+ char *zInsert = 0;
+ int rc;
+ int i, j, n;
+ int nTable = strlen30(zTable);
+ int k = 0;
+ int cnt = 0;
+ const int spinRate = 10000;
+
+ zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error %d: %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_data_xfer;
+ }
+ n = sqlite3_column_count(pQuery);
+ zInsert = sqlite3_malloc(200 + nTable + n*3);
+ if( zInsert==0 ) shell_out_of_memory();
+ sqlite3_snprintf(200+nTable,zInsert,
+ "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
+ i = strlen30(zInsert);
+ for(j=1; j<n; j++){
+ memcpy(zInsert+i, ",?", 2);
+ i += 2;
+ }
+ memcpy(zInsert+i, ");", 3);
+ rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error %d: %s on [%s]\n",
+ sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
+ zQuery);
+ goto end_data_xfer;
+ }
+ for(k=0; k<2; k++){
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ for(i=0; i<n; i++){
+ switch( sqlite3_column_type(pQuery, i) ){
+ case SQLITE_NULL: {
+ sqlite3_bind_null(pInsert, i+1);
+ break;
+ }
+ case SQLITE_INTEGER: {
+ sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
+ break;
+ }
+ case SQLITE_FLOAT: {
+ sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
+ break;
+ }
+ case SQLITE_TEXT: {
+ sqlite3_bind_text(pInsert, i+1,
+ (const char*)sqlite3_column_text(pQuery,i),
+ -1, SQLITE_STATIC);
+ break;
+ }
+ case SQLITE_BLOB: {
+ sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
+ sqlite3_column_bytes(pQuery,i),
+ SQLITE_STATIC);
+ break;
+ }
+ }
+ } /* End for */
+ rc = sqlite3_step(pInsert);
+ if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
+ utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
+ sqlite3_errmsg(newDb));
+ }
+ sqlite3_reset(pInsert);
+ cnt++;
+ if( (cnt%spinRate)==0 ){
+ printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
+ fflush(stdout);
+ }
+ } /* End while */
+ if( rc==SQLITE_DONE ) break;
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+ zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
+ zTable);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
+ break;
+ }
+ } /* End for(k=0...) */
+
+end_data_xfer:
+ sqlite3_finalize(pQuery);
+ sqlite3_finalize(pInsert);
+ sqlite3_free(zQuery);
+ sqlite3_free(zInsert);
+}
+
+
+/*
+** Try to transfer all rows of the schema that match zWhere. For
+** each row, invoke xForEach() on the object defined by that row.
+** If an error is encountered while moving forward through the
+** sqlite_master table, try again moving backwards.
+*/
+static void tryToCloneSchema(
+ ShellState *p,
+ sqlite3 *newDb,
+ const char *zWhere,
+ void (*xForEach)(ShellState*,sqlite3*,const char*)
+){
+ sqlite3_stmt *pQuery = 0;
+ char *zQuery = 0;
+ int rc;
+ const unsigned char *zName;
+ const unsigned char *zSql;
+ char *zErrMsg = 0;
+
+ zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
+ " WHERE %s", zWhere);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_schema_xfer;
+ }
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ zName = sqlite3_column_text(pQuery, 0);
+ zSql = sqlite3_column_text(pQuery, 1);
+ printf("%s... ", zName); fflush(stdout);
+ sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }
+ if( xForEach ){
+ xForEach(p, newDb, (const char*)zName);
+ }
+ printf("done\n");
+ }
+ if( rc!=SQLITE_DONE ){
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+ zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
+ " WHERE %s ORDER BY rowid DESC", zWhere);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_schema_xfer;
+ }
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ zName = sqlite3_column_text(pQuery, 0);
+ zSql = sqlite3_column_text(pQuery, 1);
+ printf("%s... ", zName); fflush(stdout);
+ sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }
+ if( xForEach ){
+ xForEach(p, newDb, (const char*)zName);
+ }
+ printf("done\n");
+ }
+ }
+end_schema_xfer:
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+}
+
+/*
+** Open a new database file named "zNewDb". Try to recover as much information
+** as possible out of the main database (which might be corrupt) and write it
+** into zNewDb.
+*/
+static void tryToClone(ShellState *p, const char *zNewDb){
+ int rc;
+ sqlite3 *newDb = 0;
+ if( access(zNewDb,0)==0 ){
+ utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
+ return;
+ }
+ rc = sqlite3_open(zNewDb, &newDb);
+ if( rc ){
+ utf8_printf(stderr, "Cannot create output database: %s\n",
+ sqlite3_errmsg(newDb));
+ }else{
+ sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
+ sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
+ tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
+ tryToCloneSchema(p, newDb, "type!='table'", 0);
+ sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
+ sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
+ }
+ close_db(newDb);
+}
+
+/*
+** Change the output file back to stdout.
+**
+** If the p->doXdgOpen flag is set, that means the output was being
+** redirected to a temporary file named by p->zTempFile. In that case,
+** launch start/open/xdg-open on that temporary file.
+*/
+static void output_reset(ShellState *p){
+ if( p->outfile[0]=='|' ){
+#ifndef SQLITE_OMIT_POPEN
+ pclose(p->out);
+#endif
+ }else{
+ output_file_close(p->out);
+#ifndef SQLITE_NOHAVE_SYSTEM
+ if( p->doXdgOpen ){
+ const char *zXdgOpenCmd =
+#if defined(_WIN32)
+ "start";
+#elif defined(__APPLE__)
+ "open";
+#else
+ "xdg-open";
+#endif
+ char *zCmd;
+ zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
+ if( system(zCmd) ){
+ utf8_printf(stderr, "Failed: [%s]\n", zCmd);
+ }
+ sqlite3_free(zCmd);
+ outputModePop(p);
+ p->doXdgOpen = 0;
+ }
+#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
+ }
+ p->outfile[0] = 0;
+ p->out = stdout;
+}
+
+/*
+** Run an SQL command and return the single integer result.
+*/
+static int db_int(ShellState *p, const char *zSql){
+ sqlite3_stmt *pStmt;
+ int res = 0;
+ sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
+ res = sqlite3_column_int(pStmt,0);
+ }
+ sqlite3_finalize(pStmt);
+ return res;
+}
+
+/*
+** Convert a 2-byte or 4-byte big-endian integer into a native integer
+*/
+static unsigned int get2byteInt(unsigned char *a){
+ return (a[0]<<8) + a[1];
+}
+static unsigned int get4byteInt(unsigned char *a){
+ return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
+}
+
+/*
+** Implementation of the ".info" command.
+**
+** Return 1 on error, 2 to exit, and 0 otherwise.
+*/
+static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
+ static const struct { const char *zName; int ofst; } aField[] = {
+ { "file change counter:", 24 },
+ { "database page count:", 28 },
+ { "freelist page count:", 36 },
+ { "schema cookie:", 40 },
+ { "schema format:", 44 },
+ { "default cache size:", 48 },
+ { "autovacuum top root:", 52 },
+ { "incremental vacuum:", 64 },
+ { "text encoding:", 56 },
+ { "user version:", 60 },
+ { "application id:", 68 },
+ { "software version:", 96 },
+ };
+ static const struct { const char *zName; const char *zSql; } aQuery[] = {
+ { "number of tables:",
+ "SELECT count(*) FROM %s WHERE type='table'" },
+ { "number of indexes:",
+ "SELECT count(*) FROM %s WHERE type='index'" },
+ { "number of triggers:",
+ "SELECT count(*) FROM %s WHERE type='trigger'" },
+ { "number of views:",
+ "SELECT count(*) FROM %s WHERE type='view'" },
+ { "schema size:",
+ "SELECT total(length(sql)) FROM %s" },
+ };
+ int i;
+ unsigned iDataVersion;
+ char *zSchemaTab;
+ char *zDb = nArg>=2 ? azArg[1] : "main";
+ sqlite3_stmt *pStmt = 0;
+ unsigned char aHdr[100];
+ open_db(p, 0);
+ if( p->db==0 ) return 1;
+ sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
+ -1, &pStmt, 0);
+ sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
+ if( sqlite3_step(pStmt)==SQLITE_ROW
+ && sqlite3_column_bytes(pStmt,0)>100
+ ){
+ memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
+ sqlite3_finalize(pStmt);
+ }else{
+ raw_printf(stderr, "unable to read database header\n");
+ sqlite3_finalize(pStmt);
+ return 1;
+ }
+ i = get2byteInt(aHdr+16);
+ if( i==1 ) i = 65536;
+ utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
+ utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
+ utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
+ utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
+ for(i=0; i<ArraySize(aField); i++){
+ int ofst = aField[i].ofst;
+ unsigned int val = get4byteInt(aHdr + ofst);
+ 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)");
+ }
+ }
+ raw_printf(p->out, "\n");
+ }
+ if( zDb==0 ){
+ zSchemaTab = sqlite3_mprintf("main.sqlite_master");
+ }else if( strcmp(zDb,"temp")==0 ){
+ zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
+ }else{
+ zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
+ }
+ for(i=0; i<ArraySize(aQuery); i++){
+ char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
+ int val = db_int(p, zSql);
+ sqlite3_free(zSql);
+ utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
+ }
+ sqlite3_free(zSchemaTab);
+ sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
+ utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
+ return 0;
+}
+
+/*
+** Print the current sqlite3_errmsg() value to stderr and return 1.
+*/
+static int shellDatabaseError(sqlite3 *db){
+ const char *zErr = sqlite3_errmsg(db);
+ utf8_printf(stderr, "Error: %s\n", zErr);
+ return 1;
+}
+
+/*
+** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
+** if they match and FALSE (0) if they do not match.
+**
+** Globbing rules:
+**
+** '*' Matches any sequence of zero or more characters.
+**
+** '?' Matches exactly one character.
+**
+** [...] Matches one character from the enclosed list of
+** characters.
+**
+** [^...] Matches one character not in the enclosed list.
+**
+** '#' Matches any sequence of one or more digits with an
+** optional + or - sign in front
+**
+** ' ' Any span of whitespace matches any other span of
+** whitespace.
+**
+** Extra whitespace at the end of z[] is ignored.
+*/
+static int testcase_glob(const char *zGlob, const char *z){
+ int c, c2;
+ int invert;
+ int seen;
+
+ while( (c = (*(zGlob++)))!=0 ){
+ if( IsSpace(c) ){
+ if( !IsSpace(*z) ) return 0;
+ while( IsSpace(*zGlob) ) zGlob++;
+ while( IsSpace(*z) ) z++;
+ }else if( c=='*' ){
+ while( (c=(*(zGlob++))) == '*' || c=='?' ){
+ if( c=='?' && (*(z++))==0 ) return 0;
+ }
+ if( c==0 ){
+ return 1;
+ }else if( c=='[' ){
+ while( *z && testcase_glob(zGlob-1,z)==0 ){
+ z++;
+ }
+ return (*z)!=0;
+ }
+ while( (c2 = (*(z++)))!=0 ){
+ while( c2!=c ){
+ c2 = *(z++);
+ if( c2==0 ) return 0;
+ }
+ if( testcase_glob(zGlob,z) ) return 1;
+ }
+ return 0;
+ }else if( c=='?' ){
+ if( (*(z++))==0 ) return 0;
+ }else if( c=='[' ){
+ int prior_c = 0;
+ seen = 0;
+ invert = 0;
+ c = *(z++);
+ if( c==0 ) return 0;
+ c2 = *(zGlob++);
+ if( c2=='^' ){
+ invert = 1;
+ c2 = *(zGlob++);
+ }
+ if( c2==']' ){
+ if( c==']' ) seen = 1;
+ c2 = *(zGlob++);
+ }
+ while( c2 && c2!=']' ){
+ if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
+ c2 = *(zGlob++);
+ if( c>=prior_c && c<=c2 ) seen = 1;
+ prior_c = 0;
+ }else{
+ if( c==c2 ){
+ seen = 1;
+ }
+ prior_c = c2;
+ }
+ c2 = *(zGlob++);
+ }
+ if( c2==0 || (seen ^ invert)==0 ) return 0;
+ }else if( c=='#' ){
+ if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
+ if( !IsDigit(z[0]) ) return 0;
+ z++;
+ while( IsDigit(z[0]) ){ z++; }
+ }else{
+ if( c!=(*(z++)) ) return 0;
+ }
+ }
+ while( IsSpace(*z) ){ z++; }
+ return *z==0;
+}
+
+
+/*
+** 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;
+}
+
+/*
+** Delete a file.
+*/
+int shellDeleteFile(const char *zFilename){
+ int rc;
+#ifdef _WIN32
+ wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
+ rc = _wunlink(z);
+ sqlite3_free(z);
+#else
+ rc = unlink(zFilename);
+#endif
+ return rc;
+}
+
+/*
+** Try to delete the temporary file (if there is one) and free the
+** memory used to hold the name of the temp file.
+*/
+static void clearTempFile(ShellState *p){
+ if( p->zTempFile==0 ) return;
+ if( p->doXdgOpen ) return;
+ if( shellDeleteFile(p->zTempFile) ) return;
+ sqlite3_free(p->zTempFile);
+ p->zTempFile = 0;
+}
+
+/*
+** Create a new temp file name with the given suffix.
+*/
+static void newTempFile(ShellState *p, const char *zSuffix){
+ clearTempFile(p);
+ sqlite3_free(p->zTempFile);
+ p->zTempFile = 0;
+ if( p->db ){
+ sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
+ }
+ if( p->zTempFile==0 ){
+ sqlite3_uint64 r;
+ sqlite3_randomness(sizeof(r), &r);
+ p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
+ }else{
+ p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
+ }
+ if( p->zTempFile==0 ){
+ raw_printf(stderr, "out of memory\n");
+ exit(1);
+ }
+}
+
+
+/*
+** The implementation of SQL scalar function fkey_collate_clause(), used
+** by the ".lint fkey-indexes" command. This scalar function is always
+** called with four arguments - the parent table name, the parent column name,
+** the child table name and the child column name.
+**
+** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
+**
+** If either of the named tables or columns do not exist, this function
+** returns an empty string. An empty string is also returned if both tables
+** and columns exist but have the same default collation sequence. Or,
+** if both exist but the default collation sequences are different, this
+** function returns the string " COLLATE <parent-collation>", where
+** <parent-collation> is the default collation sequence of the parent column.
+*/
+static void shellFkeyCollateClause(
+ sqlite3_context *pCtx,
+ int nVal,
+ sqlite3_value **apVal
+){
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
+ const char *zParent;
+ const char *zParentCol;
+ const char *zParentSeq;
+ const char *zChild;
+ const char *zChildCol;
+ const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
+ int rc;
+
+ assert( nVal==4 );
+ zParent = (const char*)sqlite3_value_text(apVal[0]);
+ zParentCol = (const char*)sqlite3_value_text(apVal[1]);
+ zChild = (const char*)sqlite3_value_text(apVal[2]);
+ zChildCol = (const char*)sqlite3_value_text(apVal[3]);
+
+ sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
+ rc = sqlite3_table_column_metadata(
+ db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
+ );
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_table_column_metadata(
+ db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
+ );
+ }
+
+ if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
+ char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
+ sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
+ sqlite3_free(z);
+ }
+}
+
+
+/*
+** The implementation of dot-command ".lint fkey-indexes".
+*/
+static int lintFkeyIndexes(
+ ShellState *pState, /* Current shell tool state */
+ char **azArg, /* Array of arguments passed to dot command */
+ int nArg /* Number of entries in azArg[] */
+){
+ sqlite3 *db = pState->db; /* Database handle to query "main" db of */
+ FILE *out = pState->out; /* Stream to write non-error output to */
+ int bVerbose = 0; /* If -verbose is present */
+ int bGroupByParent = 0; /* If -groupbyparent is present */
+ int i; /* To iterate through azArg[] */
+ const char *zIndent = ""; /* How much to indent CREATE INDEX by */
+ int rc; /* Return code */
+ sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
+
+ /*
+ ** This SELECT statement returns one row for each foreign key constraint
+ ** in the schema of the main database. The column values are:
+ **
+ ** 0. The text of an SQL statement similar to:
+ **
+ ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?"
+ **
+ ** This SELECT is similar to the one that the foreign keys implementation
+ ** needs to run internally on child tables. If there is an index that can
+ ** be used to optimize this query, then it can also be used by the FK
+ ** implementation to optimize DELETE or UPDATE statements on the parent
+ ** table.
+ **
+ ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
+ ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
+ ** contains an index that can be used to optimize the query.
+ **
+ ** 2. Human readable text that describes the child table and columns. e.g.
+ **
+ ** "child_table(child_key1, child_key2)"
+ **
+ ** 3. Human readable text that describes the parent table and columns. e.g.
+ **
+ ** "parent_table(parent_key1, parent_key2)"
+ **
+ ** 4. A full CREATE INDEX statement for an index that could be used to
+ ** optimize DELETE or UPDATE statements on the parent table. e.g.
+ **
+ ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
+ **
+ ** 5. The name of the parent table.
+ **
+ ** These six values are used by the C logic below to generate the report.
+ */
+ const char *zSql =
+ "SELECT "
+ " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '"
+ " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
+ " || fkey_collate_clause("
+ " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
+ ", "
+ " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
+ " || group_concat('*=?', ' AND ') || ')'"
+ ", "
+ " s.name || '(' || group_concat(f.[from], ', ') || ')'"
+ ", "
+ " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
+ ", "
+ " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
+ " || ' ON ' || quote(s.name) || '('"
+ " || group_concat(quote(f.[from]) ||"
+ " fkey_collate_clause("
+ " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
+ " || ');'"
+ ", "
+ " f.[table] "
+ "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
+ "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
+ "GROUP BY s.name, f.id "
+ "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
+ ;
+ const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
+
+ for(i=2; i<nArg; i++){
+ int n = strlen30(azArg[i]);
+ if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
+ bVerbose = 1;
+ }
+ else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
+ bGroupByParent = 1;
+ zIndent = " ";
+ }
+ else{
+ raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
+ azArg[0], azArg[1]
+ );
+ return SQLITE_ERROR;
+ }
+ }
+
+ /* Register the fkey_collate_clause() SQL function */
+ rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
+ 0, shellFkeyCollateClause, 0, 0
+ );
+
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int(pSql, 1, bGroupByParent);
+ }
+
+ if( rc==SQLITE_OK ){
+ int rc2;
+ char *zPrev = 0;
+ while( SQLITE_ROW==sqlite3_step(pSql) ){
+ int res = -1;
+ sqlite3_stmt *pExplain = 0;
+ const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
+ const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
+ const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
+ const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
+ const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
+ const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
+
+ rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+ if( rc!=SQLITE_OK ) break;
+ if( SQLITE_ROW==sqlite3_step(pExplain) ){
+ const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
+ res = (
+ 0==sqlite3_strglob(zGlob, zPlan)
+ || 0==sqlite3_strglob(zGlobIPK, zPlan)
+ );
+ }
+ rc = sqlite3_finalize(pExplain);
+ if( rc!=SQLITE_OK ) break;
+
+ if( res<0 ){
+ raw_printf(stderr, "Error: internal error");
+ break;
+ }else{
+ if( bGroupByParent
+ && (bVerbose || res==0)
+ && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
+ ){
+ raw_printf(out, "-- Parent table %s\n", zParent);
+ sqlite3_free(zPrev);
+ zPrev = sqlite3_mprintf("%s", zParent);
+ }
+
+ if( res==0 ){
+ raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
+ }else if( bVerbose ){
+ raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
+ zIndent, zFrom, zTarget
+ );
+ }
+ }
+ }
+ sqlite3_free(zPrev);
+
+ if( rc!=SQLITE_OK ){
+ raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+ }
+
+ rc2 = sqlite3_finalize(pSql);
+ if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
+ rc = rc2;
+ raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+ }
+ }else{
+ raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+ }
+
+ return rc;
+}
+
+/*
+** Implementation of ".lint" dot command.
+*/
+static int lintDotCommand(
+ ShellState *pState, /* Current shell tool state */
+ char **azArg, /* Array of arguments passed to dot command */
+ int nArg /* Number of entries in azArg[] */
+){
+ int n;
+ n = (nArg>=2 ? strlen30(azArg[1]) : 0);
+ if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
+ return lintFkeyIndexes(pState, azArg, nArg);
+
+ usage:
+ raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
+ raw_printf(stderr, "Where sub-commands are:\n");
+ raw_printf(stderr, " fkey-indexes\n");
+ return SQLITE_ERROR;
+}
+
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+/*********************************************************************************
+** The ".archive" or ".ar" command.
+*/
+static void shellPrepare(
+ sqlite3 *db,
+ int *pRc,
+ const char *zSql,
+ sqlite3_stmt **ppStmt
+){
+ *ppStmt = 0;
+ if( *pRc==SQLITE_OK ){
+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
+ if( rc!=SQLITE_OK ){
+ raw_printf(stderr, "sql error: %s (%d)\n",
+ sqlite3_errmsg(db), sqlite3_errcode(db)
+ );
+ *pRc = rc;
+ }
+ }
+}
+
+static void shellPreparePrintf(
+ sqlite3 *db,
+ int *pRc,
+ sqlite3_stmt **ppStmt,
+ const char *zFmt,
+ ...
+){
+ *ppStmt = 0;
+ if( *pRc==SQLITE_OK ){
+ va_list ap;
+ char *z;
+ va_start(ap, zFmt);
+ z = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ if( z==0 ){
+ *pRc = SQLITE_NOMEM;
+ }else{
+ shellPrepare(db, pRc, z, ppStmt);
+ sqlite3_free(z);
+ }
+ }
+}
+
+static void shellFinalize(
+ int *pRc,
+ sqlite3_stmt *pStmt
+){
+ if( pStmt ){
+ sqlite3 *db = sqlite3_db_handle(pStmt);
+ int rc = sqlite3_finalize(pStmt);
+ if( *pRc==SQLITE_OK ){
+ if( rc!=SQLITE_OK ){
+ raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
+ }
+ *pRc = rc;
+ }
+ }
+}
+
+static void shellReset(
+ int *pRc,
+ sqlite3_stmt *pStmt
+){
+ int rc = sqlite3_reset(pStmt);
+ if( *pRc==SQLITE_OK ){
+ if( rc!=SQLITE_OK ){
+ sqlite3 *db = sqlite3_db_handle(pStmt);
+ raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
+ }
+ *pRc = rc;
+ }
+}
+/*
+** Structure representing a single ".ar" command.
+*/
+typedef struct ArCommand ArCommand;
+struct ArCommand {
+ u8 eCmd; /* An AR_CMD_* value */
+ u8 bVerbose; /* True if --verbose */
+ u8 bZip; /* True if the archive is a ZIP */
+ u8 bDryRun; /* True if --dry-run */
+ u8 bAppend; /* True if --append */
+ u8 fromCmdLine; /* Run from -A instead of .archive */
+ int nArg; /* Number of command arguments */
+ char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
+ const char *zFile; /* --file argument, or NULL */
+ const char *zDir; /* --directory argument, or NULL */
+ char **azArg; /* Array of command arguments */
+ ShellState *p; /* Shell state */
+ sqlite3 *db; /* Database containing the archive */
+};
+
+/*
+** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
+*/
+static int arUsage(FILE *f){
+ showHelp(f,"archive");
+ return SQLITE_ERROR;
+}
+
+/*
+** Print an error message for the .ar command to stderr and return
+** SQLITE_ERROR.
+*/
+static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
+ va_list ap;
+ char *z;
+ va_start(ap, zFmt);
+ z = sqlite3_vmprintf(zFmt, ap);
+ va_end(ap);
+ utf8_printf(stderr, "Error: %s\n", z);
+ if( pAr->fromCmdLine ){
+ utf8_printf(stderr, "Use \"-A\" for more help\n");
+ }else{
+ utf8_printf(stderr, "Use \".archive --help\" for more help\n");
+ }
+ sqlite3_free(z);
+ return SQLITE_ERROR;
+}
+
+/*
+** Values for ArCommand.eCmd.
+*/
+#define AR_CMD_CREATE 1
+#define AR_CMD_EXTRACT 2
+#define AR_CMD_LIST 3
+#define AR_CMD_UPDATE 4
+#define AR_CMD_HELP 5
+
+/*
+** Other (non-command) switches.
+*/
+#define AR_SWITCH_VERBOSE 6
+#define AR_SWITCH_FILE 7
+#define AR_SWITCH_DIRECTORY 8
+#define AR_SWITCH_APPEND 9
+#define AR_SWITCH_DRYRUN 10
+
+static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
+ switch( eSwitch ){
+ case AR_CMD_CREATE:
+ case AR_CMD_EXTRACT:
+ case AR_CMD_LIST:
+ case AR_CMD_UPDATE:
+ case AR_CMD_HELP:
+ if( pAr->eCmd ){
+ return arErrorMsg(pAr, "multiple command options");
+ }
+ pAr->eCmd = eSwitch;
+ break;
+
+ case AR_SWITCH_DRYRUN:
+ pAr->bDryRun = 1;
+ break;
+ case AR_SWITCH_VERBOSE:
+ pAr->bVerbose = 1;
+ break;
+ case AR_SWITCH_APPEND:
+ pAr->bAppend = 1;
+ /* Fall thru into --file */
+ case AR_SWITCH_FILE:
+ pAr->zFile = zArg;
+ break;
+ case AR_SWITCH_DIRECTORY:
+ pAr->zDir = zArg;
+ break;
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** Parse the command line for an ".ar" command. The results are written into
+** structure (*pAr). SQLITE_OK is returned if the command line is parsed
+** successfully, otherwise an error message is written to stderr and
+** SQLITE_ERROR returned.
+*/
+static int arParseCommand(
+ char **azArg, /* Array of arguments passed to dot command */
+ int nArg, /* Number of entries in azArg[] */
+ ArCommand *pAr /* Populate this object */
+){
+ struct ArSwitch {
+ const char *zLong;
+ char cShort;
+ u8 eSwitch;
+ u8 bArg;
+ } aSwitch[] = {
+ { "create", 'c', AR_CMD_CREATE, 0 },
+ { "extract", 'x', AR_CMD_EXTRACT, 0 },
+ { "list", 't', AR_CMD_LIST, 0 },
+ { "update", 'u', AR_CMD_UPDATE, 0 },
+ { "help", 'h', AR_CMD_HELP, 0 },
+ { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
+ { "file", 'f', AR_SWITCH_FILE, 1 },
+ { "append", 'a', AR_SWITCH_APPEND, 1 },
+ { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
+ { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
+ };
+ int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
+ struct ArSwitch *pEnd = &aSwitch[nSwitch];
+
+ if( nArg<=1 ){
+ utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
+ return arUsage(stderr);
+ }else{
+ char *z = azArg[1];
+ if( z[0]!='-' ){
+ /* Traditional style [tar] invocation */
+ int i;
+ int iArg = 2;
+ for(i=0; z[i]; i++){
+ const char *zArg = 0;
+ struct ArSwitch *pOpt;
+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
+ if( z[i]==pOpt->cShort ) break;
+ }
+ if( pOpt==pEnd ){
+ return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
+ }
+ if( pOpt->bArg ){
+ if( iArg>=nArg ){
+ return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
+ }
+ zArg = azArg[iArg++];
+ }
+ if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
+ }
+ pAr->nArg = nArg-iArg;
+ if( pAr->nArg>0 ){
+ pAr->azArg = &azArg[iArg];
+ }
+ }else{
+ /* Non-traditional invocation */
+ int iArg;
+ for(iArg=1; iArg<nArg; iArg++){
+ int n;
+ z = azArg[iArg];
+ if( z[0]!='-' ){
+ /* All remaining command line words are command arguments. */
+ pAr->azArg = &azArg[iArg];
+ pAr->nArg = nArg-iArg;
+ break;
+ }
+ n = strlen30(z);
+
+ if( z[1]!='-' ){
+ int i;
+ /* One or more short options */
+ for(i=1; i<n; i++){
+ const char *zArg = 0;
+ struct ArSwitch *pOpt;
+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
+ if( z[i]==pOpt->cShort ) break;
+ }
+ if( pOpt==pEnd ){
+ return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
+ }
+ if( pOpt->bArg ){
+ if( i<(n-1) ){
+ zArg = &z[i+1];
+ i = n;
+ }else{
+ if( iArg>=(nArg-1) ){
+ return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
+ }
+ zArg = azArg[++iArg];
+ }
+ }
+ if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
+ }
+ }else if( z[2]=='\0' ){
+ /* A -- option, indicating that all remaining command line words
+ ** are command arguments. */
+ pAr->azArg = &azArg[iArg+1];
+ pAr->nArg = nArg-iArg-1;
+ break;
+ }else{
+ /* A long option */
+ const char *zArg = 0; /* Argument for option, if any */
+ struct ArSwitch *pMatch = 0; /* Matching option */
+ struct ArSwitch *pOpt; /* Iterator */
+ for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
+ const char *zLong = pOpt->zLong;
+ if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
+ if( pMatch ){
+ return arErrorMsg(pAr, "ambiguous option: %s",z);
+ }else{
+ pMatch = pOpt;
+ }
+ }
+ }
+
+ if( pMatch==0 ){
+ return arErrorMsg(pAr, "unrecognized option: %s", z);
+ }
+ if( pMatch->bArg ){
+ if( iArg>=(nArg-1) ){
+ return arErrorMsg(pAr, "option requires an argument: %s", z);
+ }
+ zArg = azArg[++iArg];
+ }
+ if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
+ }
+ }
+ }
+ }
+
+ return SQLITE_OK;
+}
+
+/*
+** This function assumes that all arguments within the ArCommand.azArg[]
+** array refer to archive members, as for the --extract or --list commands.
+** It checks that each of them are present. If any specified file is not
+** present in the archive, an error is printed to stderr and an error
+** code returned. Otherwise, if all specified arguments are present in
+** the archive, SQLITE_OK is returned.
+**
+** This function strips any trailing '/' characters from each argument.
+** This is consistent with the way the [tar] command seems to work on
+** Linux.
+*/
+static int arCheckEntries(ArCommand *pAr){
+ int rc = SQLITE_OK;
+ if( pAr->nArg ){
+ int i, j;
+ sqlite3_stmt *pTest = 0;
+
+ shellPreparePrintf(pAr->db, &rc, &pTest,
+ "SELECT name FROM %s WHERE name=$name",
+ pAr->zSrcTable
+ );
+ j = sqlite3_bind_parameter_index(pTest, "$name");
+ for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
+ char *z = pAr->azArg[i];
+ int n = strlen30(z);
+ int bOk = 0;
+ while( n>0 && z[n-1]=='/' ) n--;
+ z[n] = '\0';
+ sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
+ if( SQLITE_ROW==sqlite3_step(pTest) ){
+ bOk = 1;
+ }
+ shellReset(&rc, pTest);
+ if( rc==SQLITE_OK && bOk==0 ){
+ utf8_printf(stderr, "not found in archive: %s\n", z);
+ rc = SQLITE_ERROR;
+ }
+ }
+ shellFinalize(&rc, pTest);
+ }
+ return rc;
+}
+
+/*
+** Format a WHERE clause that can be used against the "sqlar" table to
+** identify all archive members that match the command arguments held
+** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
+** The caller is responsible for eventually calling sqlite3_free() on
+** any non-NULL (*pzWhere) value.
+*/
+static void arWhereClause(
+ int *pRc,
+ ArCommand *pAr,
+ char **pzWhere /* OUT: New WHERE clause */
+){
+ char *zWhere = 0;
+ if( *pRc==SQLITE_OK ){
+ if( pAr->nArg==0 ){
+ zWhere = sqlite3_mprintf("1");
+ }else{
+ int i;
+ const char *zSep = "";
+ for(i=0; i<pAr->nArg; i++){
+ const char *z = pAr->azArg[i];
+ zWhere = sqlite3_mprintf(
+ "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
+ zWhere, zSep, z, strlen30(z)+1, z
+ );
+ if( zWhere==0 ){
+ *pRc = SQLITE_NOMEM;
+ break;
+ }
+ zSep = " OR ";
+ }
+ }
+ }
+ *pzWhere = zWhere;
+}
+
+/*
+** Implementation of .ar "lisT" command.
+*/
+static int arListCommand(ArCommand *pAr){
+ const char *zSql = "SELECT %s FROM %s WHERE %s";
+ const char *azCols[] = {
+ "name",
+ "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
+ };
+
+ char *zWhere = 0;
+ sqlite3_stmt *pSql = 0;
+ int rc;
+
+ rc = arCheckEntries(pAr);
+ arWhereClause(&rc, pAr, &zWhere);
+
+ shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
+ pAr->zSrcTable, zWhere);
+ if( pAr->bDryRun ){
+ utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
+ }else{
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
+ if( pAr->bVerbose ){
+ utf8_printf(pAr->p->out, "%s % 10d %s %s\n",
+ sqlite3_column_text(pSql, 0),
+ sqlite3_column_int(pSql, 1),
+ sqlite3_column_text(pSql, 2),
+ sqlite3_column_text(pSql, 3)
+ );
+ }else{
+ utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
+ }
+ }
+ }
+ shellFinalize(&rc, pSql);
+ sqlite3_free(zWhere);
+ return rc;
+}
+
+
+/*
+** Implementation of .ar "eXtract" command.
+*/
+static int arExtractCommand(ArCommand *pAr){
+ const char *zSql1 =
+ "SELECT "
+ " ($dir || name),"
+ " writefile(($dir || name), %s, mode, mtime) "
+ "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
+ " AND name NOT GLOB '*..[/\\]*'";
+
+ const char *azExtraArg[] = {
+ "sqlar_uncompress(data, sz)",
+ "data"
+ };
+
+ sqlite3_stmt *pSql = 0;
+ int rc = SQLITE_OK;
+ char *zDir = 0;
+ char *zWhere = 0;
+ int i, j;
+
+ /* If arguments are specified, check that they actually exist within
+ ** the archive before proceeding. And formulate a WHERE clause to
+ ** match them. */
+ rc = arCheckEntries(pAr);
+ arWhereClause(&rc, pAr, &zWhere);
+
+ if( rc==SQLITE_OK ){
+ if( pAr->zDir ){
+ zDir = sqlite3_mprintf("%s/", pAr->zDir);
+ }else{
+ zDir = sqlite3_mprintf("");
+ }
+ if( zDir==0 ) rc = SQLITE_NOMEM;
+ }
+
+ shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
+ azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
+ );
+
+ if( rc==SQLITE_OK ){
+ j = sqlite3_bind_parameter_index(pSql, "$dir");
+ sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
+
+ /* Run the SELECT statement twice. The first time, writefile() is called
+ ** for all archive members that should be extracted. The second time,
+ ** only for the directories. This is because the timestamps for
+ ** extracted directories must be reset after they are populated (as
+ ** populating them changes the timestamp). */
+ for(i=0; i<2; i++){
+ j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
+ sqlite3_bind_int(pSql, j, i);
+ if( pAr->bDryRun ){
+ utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
+ }else{
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
+ if( i==0 && pAr->bVerbose ){
+ utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
+ }
+ }
+ }
+ shellReset(&rc, pSql);
+ }
+ shellFinalize(&rc, pSql);
+ }
+
+ sqlite3_free(zDir);
+ sqlite3_free(zWhere);
+ return rc;
+}
+
+/*
+** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
+*/
+static int arExecSql(ArCommand *pAr, const char *zSql){
+ int rc;
+ if( pAr->bDryRun ){
+ utf8_printf(pAr->p->out, "%s\n", zSql);
+ rc = SQLITE_OK;
+ }else{
+ char *zErr = 0;
+ rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
+ if( zErr ){
+ utf8_printf(stdout, "ERROR: %s\n", zErr);
+ sqlite3_free(zErr);
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Implementation of .ar "create" and "update" commands.
+**
+** Create the "sqlar" table in the database if it does not already exist.
+** Then add each file in the azFile[] array to the archive. Directories
+** are added recursively. If argument bVerbose is non-zero, a message is
+** printed on stdout for each file archived.
+**
+** The create command is the same as update, except that it drops
+** any existing "sqlar" table before beginning.
+*/
+static int arCreateOrUpdateCommand(
+ ArCommand *pAr, /* Command arguments and options */
+ int bUpdate /* true for a --create. false for --update */
+){
+ const char *zCreate =
+ "CREATE TABLE IF NOT EXISTS sqlar(\n"
+ " name TEXT PRIMARY KEY, -- name of the file\n"
+ " mode INT, -- access permissions\n"
+ " mtime INT, -- last modification time\n"
+ " sz INT, -- original file size\n"
+ " data BLOB -- compressed content\n"
+ ")";
+ const char *zDrop = "DROP TABLE IF EXISTS sqlar";
+ const char *zInsertFmt[2] = {
+ "REPLACE INTO %s(name,mode,mtime,sz,data)\n"
+ " SELECT\n"
+ " %s,\n"
+ " mode,\n"
+ " mtime,\n"
+ " CASE substr(lsmode(mode),1,1)\n"
+ " WHEN '-' THEN length(data)\n"
+ " WHEN 'd' THEN 0\n"
+ " ELSE -1 END,\n"
+ " sqlar_compress(data)\n"
+ " FROM fsdir(%Q,%Q)\n"
+ " WHERE lsmode(mode) NOT LIKE '?%%';",
+ "REPLACE INTO %s(name,mode,mtime,data)\n"
+ " SELECT\n"
+ " %s,\n"
+ " mode,\n"
+ " mtime,\n"
+ " data\n"
+ " FROM fsdir(%Q,%Q)\n"
+ " WHERE lsmode(mode) NOT LIKE '?%%';"
+ };
+ int i; /* For iterating through azFile[] */
+ int rc; /* Return code */
+ const char *zTab = 0; /* SQL table into which to insert */
+ char *zSql;
+ char zTemp[50];
+
+ arExecSql(pAr, "PRAGMA page_size=512");
+ rc = arExecSql(pAr, "SAVEPOINT ar;");
+ if( rc!=SQLITE_OK ) return rc;
+ zTemp[0] = 0;
+ if( pAr->bZip ){
+ /* Initialize the zipfile virtual table, if necessary */
+ if( pAr->zFile ){
+ sqlite3_uint64 r;
+ sqlite3_randomness(sizeof(r),&r);
+ sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
+ zTab = zTemp;
+ zSql = sqlite3_mprintf(
+ "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
+ zTab, pAr->zFile
+ );
+ rc = arExecSql(pAr, zSql);
+ sqlite3_free(zSql);
+ }else{
+ zTab = "zip";
+ }
+ }else{
+ /* Initialize the table for an SQLAR */
+ zTab = "sqlar";
+ if( bUpdate==0 ){
+ rc = arExecSql(pAr, zDrop);
+ if( rc!=SQLITE_OK ) goto end_ar_transaction;
+ }
+ rc = arExecSql(pAr, zCreate);
+ }
+ for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
+ char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
+ pAr->bVerbose ? "shell_putsnl(name)" : "name",
+ pAr->azArg[i], pAr->zDir);
+ rc = arExecSql(pAr, zSql2);
+ sqlite3_free(zSql2);
+ }
+end_ar_transaction:
+ if( rc!=SQLITE_OK ){
+ arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
+ }else{
+ rc = arExecSql(pAr, "RELEASE ar;");
+ if( pAr->bZip && pAr->zFile ){
+ zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
+ arExecSql(pAr, zSql);
+ sqlite3_free(zSql);
+ }
+ }
+ return rc;
+}
+
+/*
+** Implementation of ".ar" dot command.
+*/
+static int arDotCommand(
+ ShellState *pState, /* Current shell tool state */
+ int fromCmdLine, /* True if -A command-line option, not .ar cmd */
+ char **azArg, /* Array of arguments passed to dot command */
+ int nArg /* Number of entries in azArg[] */
+){
+ ArCommand cmd;
+ int rc;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.fromCmdLine = fromCmdLine;
+ rc = arParseCommand(azArg, nArg, &cmd);
+ if( rc==SQLITE_OK ){
+ int eDbType = SHELL_OPEN_UNSPEC;
+ cmd.p = pState;
+ cmd.db = pState->db;
+ if( cmd.zFile ){
+ eDbType = deduceDatabaseType(cmd.zFile, 1);
+ }else{
+ eDbType = pState->openMode;
+ }
+ if( eDbType==SHELL_OPEN_ZIPFILE ){
+ if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
+ if( cmd.zFile==0 ){
+ cmd.zSrcTable = sqlite3_mprintf("zip");
+ }else{
+ cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
+ }
+ }
+ cmd.bZip = 1;
+ }else if( cmd.zFile ){
+ int flags;
+ if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
+ if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
+ flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
+ }else{
+ flags = SQLITE_OPEN_READONLY;
+ }
+ cmd.db = 0;
+ if( cmd.bDryRun ){
+ utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
+ eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
+ }
+ rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
+ eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(stderr, "cannot open file: %s (%s)\n",
+ cmd.zFile, sqlite3_errmsg(cmd.db)
+ );
+ goto end_ar_command;
+ }
+ sqlite3_fileio_init(cmd.db, 0, 0);
+ sqlite3_sqlar_init(cmd.db, 0, 0);
+ sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
+ shellPutsFunc, 0, 0);
+
+ }
+ if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
+ if( cmd.eCmd!=AR_CMD_CREATE
+ && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
+ ){
+ utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
+ rc = SQLITE_ERROR;
+ goto end_ar_command;
+ }
+ cmd.zSrcTable = sqlite3_mprintf("sqlar");
+ }
+
+ switch( cmd.eCmd ){
+ case AR_CMD_CREATE:
+ rc = arCreateOrUpdateCommand(&cmd, 0);
+ break;
+
+ case AR_CMD_EXTRACT:
+ rc = arExtractCommand(&cmd);
+ break;
+
+ case AR_CMD_LIST:
+ rc = arListCommand(&cmd);
+ break;
+
+ case AR_CMD_HELP:
+ arUsage(pState->out);
+ break;
+
+ default:
+ assert( cmd.eCmd==AR_CMD_UPDATE );
+ rc = arCreateOrUpdateCommand(&cmd, 1);
+ break;
+ }
+ }
+end_ar_command:
+ if( cmd.db!=pState->db ){
+ close_db(cmd.db);
+ }
+ sqlite3_free(cmd.zSrcTable);
+
+ return rc;
+}
+/* End of the ".archive" or ".ar" command logic
+**********************************************************************************/
+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
+
+
+/*
+** If an input line begins with "." then invoke this routine to
+** process that line.
+**
+** Return 1 on error, 2 to exit, and 0 otherwise.
+*/
+static int do_meta_command(char *zLine, ShellState *p){
+ int h = 1;
+ int nArg = 0;
+ int n, c;
+ int rc = 0;
+ char *azArg[50];
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( p->expert.pExpert ){
+ expertFinish(p, 1, 0);
+ }
+#endif
+
+ /* Parse the input line into tokens.
+ */
+ while( zLine[h] && nArg<ArraySize(azArg) ){
+ while( IsSpace(zLine[h]) ){ h++; }
+ if( zLine[h]==0 ) break;
+ if( zLine[h]=='\'' || zLine[h]=='"' ){
+ int delim = zLine[h++];
+ azArg[nArg++] = &zLine[h];
+ while( zLine[h] && zLine[h]!=delim ){
+ if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
+ h++;
+ }
+ if( zLine[h]==delim ){
+ zLine[h++] = 0;
+ }
+ if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
+ }else{
+ azArg[nArg++] = &zLine[h];
+ while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
+ if( zLine[h] ) zLine[h++] = 0;
+ resolve_backslashes(azArg[nArg-1]);
+ }
+ }
+
+ /* Process the input line.
+ */
+ if( nArg==0 ) return 0; /* no tokens, no error */
+ n = strlen30(azArg[0]);
+ c = azArg[0][0];
+ clearTempFile(p);
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ 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
+#endif
+
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+ if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
+ open_db(p, 0);
+ rc = arDotCommand(p, 0, azArg, nArg);
+ }else
+#endif
+
+ if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
+ || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
+ ){
+ const char *zDestFile = 0;
+ const char *zDb = 0;
+ sqlite3 *pDest;
+ sqlite3_backup *pBackup;
+ int j;
+ const char *zVfs = 0;
+ for(j=1; j<nArg; j++){
+ const char *z = azArg[j];
+ if( z[0]=='-' ){
+ if( z[1]=='-' ) z++;
+ if( strcmp(z, "-append")==0 ){
+ zVfs = "apndvfs";
+ }else
+ {
+ utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
+ return 1;
+ }
+ }else if( zDestFile==0 ){
+ zDestFile = azArg[j];
+ }else if( zDb==0 ){
+ zDb = zDestFile;
+ zDestFile = azArg[j];
+ }else{
+ raw_printf(stderr, "Usage: .backup ?DB? ?--append? FILENAME\n");
+ return 1;
+ }
+ }
+ if( zDestFile==0 ){
+ raw_printf(stderr, "missing FILENAME argument on .backup\n");
+ return 1;
+ }
+ if( zDb==0 ) zDb = "main";
+ rc = sqlite3_open_v2(zDestFile, &pDest,
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
+ close_db(pDest);
+ return 1;
+ }
+ open_db(p, 0);
+ pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
+ if( pBackup==0 ){
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+ close_db(pDest);
+ return 1;
+ }
+ while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
+ sqlite3_backup_finish(pBackup);
+ if( rc==SQLITE_DONE ){
+ rc = 0;
+ }else{
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+ rc = 1;
+ }
+ close_db(pDest);
+ }else
+
+ if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
+ if( nArg==2 ){
+ bail_on_error = booleanValue(azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .bail on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
+ if( nArg==2 ){
+ if( booleanValue(azArg[1]) ){
+ setBinaryMode(p->out, 1);
+ }else{
+ setTextMode(p->out, 1);
+ }
+ }else{
+ raw_printf(stderr, "Usage: .binary on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='c' && strcmp(azArg[0],"cd")==0 ){
+ if( nArg==2 ){
+#if defined(_WIN32) || defined(WIN32)
+ wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
+ rc = !SetCurrentDirectoryW(z);
+ sqlite3_free(z);
+#else
+ rc = chdir(azArg[1]);
+#endif
+ if( rc ){
+ utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
+ rc = 1;
+ }
+ }else{
+ raw_printf(stderr, "Usage: .cd DIRECTORY\n");
+ rc = 1;
+ }
+ }else
+
+ /* The undocumented ".breakpoint" command causes a call to the no-op
+ ** routine named test_breakpoint().
+ */
+ if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
+ test_breakpoint();
+ }else
+
+ if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
+ if( nArg==2 ){
+ setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .changes on|off\n");
+ rc = 1;
+ }
+ }else
+
+ /* Cancel output redirection, if it is currently set (by .testcase)
+ ** Then read the content of the testcase-out.txt file and compare against
+ ** azArg[1]. If there are differences, report an error and exit.
+ */
+ if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
+ char *zRes = 0;
+ output_reset(p);
+ if( nArg!=2 ){
+ raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
+ rc = 2;
+ }else if( (zRes = readFile("testcase-out.txt"))==0 ){
+ raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
+ rc = 2;
+ }else if( testcase_glob(azArg[1],zRes)==0 ){
+ utf8_printf(stderr,
+ "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
+ p->zTestcase, azArg[1], zRes);
+ rc = 1;
+ }else{
+ utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
+ p->nCheck++;
+ }
+ sqlite3_free(zRes);
+ }else
+
+ if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
+ if( nArg==2 ){
+ tryToClone(p, azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .clone FILENAME\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
+ ShellState data;
+ char *zErrMsg = 0;
+ open_db(p, 0);
+ memcpy(&data, p, sizeof(data));
+ data.showHeader = 0;
+ data.cMode = data.mode = MODE_List;
+ sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
+ data.cnt = 0;
+ sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
+ callback, &data, &zErrMsg);
+ if( zErrMsg ){
+ utf8_printf(stderr,"Error: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ rc = 1;
+ }
+ }else
+
+ if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
+ static const struct DbConfigChoices {
+ const char *zName;
+ int op;
+ } aDbConfig[] = {
+ { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
+ { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
+ { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
+ { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
+ { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
+ { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
+ { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
+ { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
+ };
+ int ii, v;
+ open_db(p, 0);
+ for(ii=0; ii<ArraySize(aDbConfig); ii++){
+ if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
+ if( nArg>=3 ){
+ sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
+ }
+ sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
+ utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
+ if( nArg>1 ) break;
+ }
+ if( nArg>1 && ii==ArraySize(aDbConfig) ){
+ utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
+ utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
+ }
+ }else
+
+ if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
+ rc = shell_dbinfo_command(p, nArg, azArg);
+ }else
+
+ if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
+ const char *zLike = 0;
+ int i;
+ int savedShowHeader = p->showHeader;
+ int savedShellFlags = p->shellFlgs;
+ ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
+ for(i=1; i<nArg; i++){
+ if( azArg[i][0]=='-' ){
+ const char *z = azArg[i]+1;
+ if( z[0]=='-' ) z++;
+ if( strcmp(z,"preserve-rowids")==0 ){
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+ raw_printf(stderr, "The --preserve-rowids option is not compatible"
+ " with SQLITE_OMIT_VIRTUALTABLE\n");
+ rc = 1;
+ goto meta_command_exit;
+#else
+ ShellSetFlag(p, SHFLG_PreserveRowid);
+#endif
+ }else
+ if( strcmp(z,"newlines")==0 ){
+ ShellSetFlag(p, SHFLG_Newlines);
+ }else
+ {
+ raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }else if( zLike ){
+ raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
+ "?--newlines? ?LIKE-PATTERN?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }else{
+ zLike = azArg[i];
+ }
+ }
+ open_db(p, 0);
+ /* When playing back a "dump", the content might appear in an order
+ ** which causes immediate foreign key constraints to be violated.
+ ** So disable foreign-key constraint enforcement to prevent problems. */
+ raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
+ raw_printf(p->out, "BEGIN TRANSACTION;\n");
+ p->writableSchema = 0;
+ p->showHeader = 0;
+ /* Set writable_schema=ON since doing so forces SQLite to initialize
+ ** as much of the schema as it can even if the sqlite_master table is
+ ** corrupt. */
+ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
+ p->nErr = 0;
+ if( zLike==0 ){
+ run_schema_dump_query(p,
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
+ );
+ run_schema_dump_query(p,
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE name=='sqlite_sequence'"
+ );
+ run_table_dump_query(p,
+ "SELECT sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
+ );
+ }else{
+ char *zSql;
+ zSql = sqlite3_mprintf(
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE tbl_name LIKE %Q AND type=='table'"
+ " AND sql NOT NULL", zLike);
+ run_schema_dump_query(p,zSql);
+ sqlite3_free(zSql);
+ zSql = sqlite3_mprintf(
+ "SELECT sql FROM sqlite_master "
+ "WHERE sql NOT NULL"
+ " AND type IN ('index','trigger','view')"
+ " AND tbl_name LIKE %Q", zLike);
+ run_table_dump_query(p, zSql, 0);
+ sqlite3_free(zSql);
+ }
+ if( p->writableSchema ){
+ raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
+ p->writableSchema = 0;
+ }
+ sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
+ sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
+ raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
+ p->showHeader = savedShowHeader;
+ p->shellFlgs = savedShellFlags;
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
+ if( nArg==2 ){
+ setOrClearFlag(p, SHFLG_Echo, azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .echo on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
+ if( nArg==2 ){
+ p->autoEQPtest = 0;
+ if( strcmp(azArg[1],"full")==0 ){
+ p->autoEQP = AUTOEQP_full;
+ }else if( strcmp(azArg[1],"trigger")==0 ){
+ p->autoEQP = AUTOEQP_trigger;
+ }else if( strcmp(azArg[1],"test")==0 ){
+ p->autoEQP = AUTOEQP_on;
+ p->autoEQPtest = 1;
+ }else{
+ p->autoEQP = (u8)booleanValue(azArg[1]);
+ }
+ }else{
+ raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
+ if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
+ rc = 2;
+ }else
+
+ /* The ".explain" command is automatic now. It is largely pointless. It
+ ** retained purely for backwards compatibility */
+ if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
+ int val = 1;
+ if( nArg>=2 ){
+ if( strcmp(azArg[1],"auto")==0 ){
+ val = 99;
+ }else{
+ val = booleanValue(azArg[1]);
+ }
+ }
+ if( val==1 && p->mode!=MODE_Explain ){
+ p->normalMode = p->mode;
+ p->mode = MODE_Explain;
+ p->autoExplain = 0;
+ }else if( val==0 ){
+ if( p->mode==MODE_Explain ) p->mode = p->normalMode;
+ p->autoExplain = 0;
+ }else if( val==99 ){
+ if( p->mode==MODE_Explain ) p->mode = p->normalMode;
+ p->autoExplain = 1;
+ }
+ }else
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
+ open_db(p, 0);
+ expertDotCommand(p, azArg, nArg);
+ }else
+#endif
+
+ if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
+ 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 ?--indent?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ open_db(p, 0);
+ rc = sqlite3_exec(p->db,
+ "SELECT sql FROM"
+ " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
+ " FROM sqlite_master UNION ALL"
+ " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
+ "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
+ "ORDER BY rowid",
+ callback, &data, &zErrMsg
+ );
+ if( rc==SQLITE_OK ){
+ sqlite3_stmt *pStmt;
+ rc = sqlite3_prepare_v2(p->db,
+ "SELECT rowid FROM sqlite_master"
+ " WHERE name GLOB 'sqlite_stat[134]'",
+ -1, &pStmt, 0);
+ doStats = sqlite3_step(pStmt)==SQLITE_ROW;
+ sqlite3_finalize(pStmt);
+ }
+ if( doStats==0 ){
+ raw_printf(p->out, "/* No STAT tables available */\n");
+ }else{
+ raw_printf(p->out, "ANALYZE sqlite_master;\n");
+ sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
+ callback, &data, &zErrMsg);
+ data.cMode = data.mode = MODE_Insert;
+ data.zDestTable = "sqlite_stat1";
+ shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
+ data.zDestTable = "sqlite_stat3";
+ shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
+ data.zDestTable = "sqlite_stat4";
+ shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
+ raw_printf(p->out, "ANALYZE sqlite_master;\n");
+ }
+ }else
+
+ if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
+ if( nArg==2 ){
+ p->showHeader = booleanValue(azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .headers on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
+ if( nArg>=2 ){
+ n = showHelp(p->out, azArg[1]);
+ if( n==0 ){
+ utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
+ }
+ }else{
+ showHelp(p->out, 0);
+ }
+ }else
+
+ if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
+ char *zTable; /* Insert data into this table */
+ char *zFile; /* Name of file to extra content from */
+ sqlite3_stmt *pStmt = NULL; /* A statement */
+ int nCol; /* Number of columns in the table */
+ int nByte; /* Number of bytes in an SQL string */
+ int i, j; /* Loop counters */
+ int needCommit; /* True to COMMIT or ROLLBACK at end */
+ int nSep; /* Number of bytes in p->colSeparator[] */
+ char *zSql; /* An SQL statement */
+ ImportCtx sCtx; /* Reader context */
+ char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
+ int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
+
+ if( nArg!=3 ){
+ raw_printf(stderr, "Usage: .import FILE TABLE\n");
+ goto meta_command_exit;
+ }
+ zFile = azArg[1];
+ zTable = azArg[2];
+ seenInterrupt = 0;
+ memset(&sCtx, 0, sizeof(sCtx));
+ open_db(p, 0);
+ nSep = strlen30(p->colSeparator);
+ if( nSep==0 ){
+ raw_printf(stderr,
+ "Error: non-null column separator required for import\n");
+ return 1;
+ }
+ if( nSep>1 ){
+ raw_printf(stderr, "Error: multi-character column separators not allowed"
+ " for import\n");
+ return 1;
+ }
+ nSep = strlen30(p->rowSeparator);
+ if( nSep==0 ){
+ raw_printf(stderr, "Error: non-null row separator required for import\n");
+ return 1;
+ }
+ if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
+ /* When importing CSV (only), if the row separator is set to the
+ ** default output row separator, change it to the default input
+ ** row separator. This avoids having to maintain different input
+ ** and output row separators. */
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ nSep = strlen30(p->rowSeparator);
+ }
+ if( nSep>1 ){
+ raw_printf(stderr, "Error: multi-character row separators not allowed"
+ " for import\n");
+ return 1;
+ }
+ sCtx.zFile = zFile;
+ sCtx.nLine = 1;
+ if( sCtx.zFile[0]=='|' ){
+#ifdef SQLITE_OMIT_POPEN
+ raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+ return 1;
+#else
+ sCtx.in = popen(sCtx.zFile+1, "r");
+ sCtx.zFile = "<pipe>";
+ xCloser = pclose;
+#endif
+ }else{
+ sCtx.in = fopen(sCtx.zFile, "rb");
+ xCloser = fclose;
+ }
+ if( p->mode==MODE_Ascii ){
+ xRead = ascii_read_one_field;
+ }else{
+ xRead = csv_read_one_field;
+ }
+ if( sCtx.in==0 ){
+ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
+ return 1;
+ }
+ sCtx.cColSep = p->colSeparator[0];
+ sCtx.cRowSep = p->rowSeparator[0];
+ zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
+ if( zSql==0 ){
+ xCloser(sCtx.in);
+ shell_out_of_memory();
+ }
+ nByte = strlen30(zSql);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
+ if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
+ char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
+ char cSep = '(';
+ while( xRead(&sCtx) ){
+ zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
+ cSep = ',';
+ if( sCtx.cTerm!=sCtx.cColSep ) break;
+ }
+ if( cSep=='(' ){
+ sqlite3_free(zCreate);
+ sqlite3_free(sCtx.z);
+ xCloser(sCtx.in);
+ utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
+ return 1;
+ }
+ zCreate = sqlite3_mprintf("%z\n)", zCreate);
+ rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
+ sqlite3_free(zCreate);
+ if( rc ){
+ utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
+ sqlite3_errmsg(p->db));
+ sqlite3_free(sCtx.z);
+ xCloser(sCtx.in);
+ return 1;
+ }
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ }
+ sqlite3_free(zSql);
+ if( rc ){
+ if (pStmt) sqlite3_finalize(pStmt);
+ utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
+ xCloser(sCtx.in);
+ return 1;
+ }
+ nCol = sqlite3_column_count(pStmt);
+ sqlite3_finalize(pStmt);
+ pStmt = 0;
+ if( nCol==0 ) return 0; /* no columns, no error */
+ zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
+ if( zSql==0 ){
+ xCloser(sCtx.in);
+ shell_out_of_memory();
+ }
+ sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
+ j = strlen30(zSql);
+ for(i=1; i<nCol; i++){
+ zSql[j++] = ',';
+ zSql[j++] = '?';
+ }
+ zSql[j++] = ')';
+ zSql[j] = 0;
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( rc ){
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+ if (pStmt) sqlite3_finalize(pStmt);
+ xCloser(sCtx.in);
+ return 1;
+ }
+ needCommit = sqlite3_get_autocommit(p->db);
+ if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
+ do{
+ int startLine = sCtx.nLine;
+ for(i=0; i<nCol; i++){
+ char *z = xRead(&sCtx);
+ /*
+ ** Did we reach end-of-file before finding any columns?
+ ** If so, stop instead of NULL filling the remaining columns.
+ */
+ if( z==0 && i==0 ) break;
+ /*
+ ** Did we reach end-of-file OR end-of-line before finding any
+ ** columns in ASCII mode? If so, stop instead of NULL filling
+ ** the remaining columns.
+ */
+ if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
+ sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
+ if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
+ utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
+ "filling the rest with NULL\n",
+ sCtx.zFile, startLine, nCol, i+1);
+ i += 2;
+ while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
+ }
+ }
+ if( sCtx.cTerm==sCtx.cColSep ){
+ do{
+ xRead(&sCtx);
+ i++;
+ }while( sCtx.cTerm==sCtx.cColSep );
+ utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
+ "extras ignored\n",
+ sCtx.zFile, startLine, nCol, i);
+ }
+ if( i>=nCol ){
+ sqlite3_step(pStmt);
+ rc = sqlite3_reset(pStmt);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
+ startLine, sqlite3_errmsg(p->db));
+ }
+ }
+ }while( sCtx.cTerm!=EOF );
+
+ xCloser(sCtx.in);
+ sqlite3_free(sCtx.z);
+ sqlite3_finalize(pStmt);
+ if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
+ }else
+
+#ifndef SQLITE_UNTESTABLE
+ if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
+ char *zSql;
+ char *zCollist = 0;
+ sqlite3_stmt *pStmt;
+ int tnum = 0;
+ int i;
+ if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
+ utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
+ " .imposter off\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ open_db(p, 0);
+ if( nArg==2 ){
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
+ goto meta_command_exit;
+ }
+ zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
+ " WHERE name='%q' AND type='index'", azArg[1]);
+ sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( sqlite3_step(pStmt)==SQLITE_ROW ){
+ tnum = sqlite3_column_int(pStmt, 0);
+ }
+ sqlite3_finalize(pStmt);
+ if( tnum==0 ){
+ utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ i = 0;
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ char zLabel[20];
+ const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
+ i++;
+ if( zCol==0 ){
+ if( sqlite3_column_int(pStmt,1)==-1 ){
+ zCol = "_ROWID_";
+ }else{
+ sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
+ zCol = zLabel;
+ }
+ }
+ if( zCollist==0 ){
+ zCollist = sqlite3_mprintf("\"%w\"", zCol);
+ }else{
+ zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
+ }
+ }
+ sqlite3_finalize(pStmt);
+ zSql = sqlite3_mprintf(
+ "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
+ azArg[2], zCollist, zCollist);
+ sqlite3_free(zCollist);
+ rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
+ }else{
+ utf8_printf(stdout, "%s;\n", zSql);
+ raw_printf(stdout,
+ "WARNING: writing to an imposter table will corrupt the index!\n"
+ );
+ }
+ }else{
+ raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
+ rc = 1;
+ }
+ sqlite3_free(zSql);
+ }else
+#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
+
+#ifdef SQLITE_ENABLE_IOTRACE
+ if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
+ SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
+ if( iotrace && iotrace!=stdout ) fclose(iotrace);
+ iotrace = 0;
+ if( nArg<2 ){
+ sqlite3IoTrace = 0;
+ }else if( strcmp(azArg[1], "-")==0 ){
+ sqlite3IoTrace = iotracePrintf;
+ iotrace = stdout;
+ }else{
+ iotrace = fopen(azArg[1], "w");
+ if( iotrace==0 ){
+ utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
+ sqlite3IoTrace = 0;
+ rc = 1;
+ }else{
+ sqlite3IoTrace = iotracePrintf;
+ }
+ }
+ }else
+#endif
+
+ if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
+ static const struct {
+ const char *zLimitName; /* Name of a limit */
+ int limitCode; /* Integer code for that limit */
+ } aLimit[] = {
+ { "length", SQLITE_LIMIT_LENGTH },
+ { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
+ { "column", SQLITE_LIMIT_COLUMN },
+ { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
+ { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
+ { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
+ { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
+ { "attached", SQLITE_LIMIT_ATTACHED },
+ { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
+ { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
+ { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
+ { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
+ };
+ int i, n2;
+ open_db(p, 0);
+ if( nArg==1 ){
+ for(i=0; i<ArraySize(aLimit); i++){
+ printf("%20s %d\n", aLimit[i].zLimitName,
+ sqlite3_limit(p->db, aLimit[i].limitCode, -1));
+ }
+ }else if( nArg>3 ){
+ raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }else{
+ int iLimit = -1;
+ n2 = strlen30(azArg[1]);
+ for(i=0; i<ArraySize(aLimit); i++){
+ if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
+ if( iLimit<0 ){
+ iLimit = i;
+ }else{
+ utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }
+ }
+ if( iLimit<0 ){
+ utf8_printf(stderr, "unknown limit: \"%s\"\n"
+ "enter \".limits\" with no arguments for a list.\n",
+ azArg[1]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ if( nArg==3 ){
+ sqlite3_limit(p->db, aLimit[iLimit].limitCode,
+ (int)integerValue(azArg[2]));
+ }
+ printf("%20s %d\n", aLimit[iLimit].zLimitName,
+ sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
+ }
+ }else
+
+ if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
+ open_db(p, 0);
+ lintDotCommand(p, azArg, nArg);
+ }else
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
+ const char *zFile, *zProc;
+ char *zErrMsg = 0;
+ if( nArg<2 ){
+ raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ zFile = azArg[1];
+ zProc = nArg>=3 ? azArg[2] : 0;
+ open_db(p, 0);
+ rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(stderr, "Error: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ rc = 1;
+ }
+ }else
+#endif
+
+ if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
+ if( nArg!=2 ){
+ raw_printf(stderr, "Usage: .log FILENAME\n");
+ rc = 1;
+ }else{
+ const char *zFile = azArg[1];
+ output_file_close(p->pLog);
+ p->pLog = output_file_open(zFile, 0);
+ }
+ }else
+
+ if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
+ const char *zMode = nArg>=2 ? azArg[1] : "";
+ int n2 = strlen30(zMode);
+ int c2 = zMode[0];
+ if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
+ p->mode = MODE_Line;
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
+ p->mode = MODE_Column;
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
+ p->mode = MODE_List;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
+ p->mode = MODE_Html;
+ }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
+ p->mode = MODE_Tcl;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
+ p->mode = MODE_Csv;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
+ }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
+ p->mode = MODE_List;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
+ }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
+ p->mode = MODE_Insert;
+ set_table_name(p, nArg>=3 ? azArg[2] : "table");
+ }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
+ p->mode = MODE_Quote;
+ }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
+ p->mode = MODE_Ascii;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
+ }else if( nArg==1 ){
+ raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
+ }else{
+ raw_printf(stderr, "Error: mode should be one of: "
+ "ascii column csv html insert line list quote tabs tcl\n");
+ rc = 1;
+ }
+ p->cMode = p->mode;
+ }else
+
+ if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
+ if( nArg==2 ){
+ sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
+ "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
+ }else{
+ raw_printf(stderr, "Usage: .nullvalue STRING\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
+ char *zNewFilename; /* Name of the database file to open */
+ int iName = 1; /* Index in azArg[] of the filename */
+ int newFlag = 0; /* True to delete file before opening */
+ /* Close the existing database */
+ session_close_all(p);
+ close_db(p->db);
+ p->db = 0;
+ p->zDbFilename = 0;
+ sqlite3_free(p->zFreeOnClose);
+ p->zFreeOnClose = 0;
+ p->openMode = SHELL_OPEN_UNSPEC;
+ /* Check for command-line arguments */
+ for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
+ const char *z = azArg[iName];
+ if( optionMatch(z,"new") ){
+ newFlag = 1;
+#ifdef SQLITE_HAVE_ZLIB
+ }else if( optionMatch(z, "zip") ){
+ p->openMode = SHELL_OPEN_ZIPFILE;
+#endif
+ }else if( optionMatch(z, "append") ){
+ p->openMode = SHELL_OPEN_APPENDVFS;
+ }else if( optionMatch(z, "readonly") ){
+ p->openMode = SHELL_OPEN_READONLY;
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ }else if( optionMatch(z, "deserialize") ){
+ p->openMode = SHELL_OPEN_DESERIALIZE;
+#endif
+ }else if( z[0]=='-' ){
+ utf8_printf(stderr, "unknown option: %s\n", z);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }
+ /* If a filename is specified, try to open it first */
+ zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
+ if( zNewFilename ){
+ if( newFlag ) shellDeleteFile(zNewFilename);
+ p->zDbFilename = zNewFilename;
+ open_db(p, OPEN_DB_KEEPALIVE);
+ if( p->db==0 ){
+ utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
+ sqlite3_free(zNewFilename);
+ }else{
+ p->zFreeOnClose = zNewFilename;
+ }
+ }
+ if( p->db==0 ){
+ /* As a fall-back open a TEMP database */
+ p->zDbFilename = 0;
+ open_db(p, 0);
+ }
+ }else
+
+ if( (c=='o'
+ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
+ || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
+ ){
+ const char *zFile = nArg>=2 ? azArg[1] : "stdout";
+ int bTxtMode = 0;
+ if( azArg[0][0]=='e' ){
+ /* Transform the ".excel" command into ".once -x" */
+ nArg = 2;
+ azArg[0] = "once";
+ zFile = azArg[1] = "-x";
+ n = 4;
+ }
+ if( nArg>2 ){
+ utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ if( n>1 && strncmp(azArg[0], "once", n)==0 ){
+ if( nArg<2 ){
+ raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ p->outCount = 2;
+ }else{
+ p->outCount = 0;
+ }
+ output_reset(p);
+ if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
+#ifndef SQLITE_NOHAVE_SYSTEM
+ if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
+ p->doXdgOpen = 1;
+ outputModePush(p);
+ if( zFile[1]=='x' ){
+ newTempFile(p, "csv");
+ p->mode = MODE_Csv;
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
+ }else{
+ newTempFile(p, "txt");
+ bTxtMode = 1;
+ }
+ zFile = p->zTempFile;
+ }
+#endif /* SQLITE_NOHAVE_SYSTEM */
+ if( zFile[0]=='|' ){
+#ifdef SQLITE_OMIT_POPEN
+ raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+ rc = 1;
+ p->out = stdout;
+#else
+ p->out = popen(zFile + 1, "w");
+ if( p->out==0 ){
+ utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
+ p->out = stdout;
+ rc = 1;
+ }else{
+ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
+ }
+#endif
+ }else{
+ p->out = output_file_open(zFile, bTxtMode);
+ if( p->out==0 ){
+ if( strcmp(zFile,"off")!=0 ){
+ utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
+ }
+ p->out = stdout;
+ rc = 1;
+ } else {
+ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
+ }
+ }
+ }else
+
+ if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
+ int i;
+ for(i=1; i<nArg; i++){
+ if( i>1 ) raw_printf(p->out, " ");
+ utf8_printf(p->out, "%s", azArg[i]);
+ }
+ raw_printf(p->out, "\n");
+ }else
+
+ if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
+ if( nArg >= 2) {
+ strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
+ }
+ if( nArg >= 3) {
+ strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
+ }
+ }else
+
+ if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
+ rc = 2;
+ }else
+
+ if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
+ FILE *alt;
+ if( nArg!=2 ){
+ raw_printf(stderr, "Usage: .read FILE\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ alt = fopen(azArg[1], "rb");
+ if( alt==0 ){
+ utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
+ rc = 1;
+ }else{
+ rc = process_input(p, alt);
+ fclose(alt);
+ }
+ }else
+
+ if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
+ const char *zSrcFile;
+ const char *zDb;
+ sqlite3 *pSrc;
+ sqlite3_backup *pBackup;
+ int nTimeout = 0;
+
+ if( nArg==2 ){
+ zSrcFile = azArg[1];
+ zDb = "main";
+ }else if( nArg==3 ){
+ zSrcFile = azArg[2];
+ zDb = azArg[1];
+ }else{
+ raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ rc = sqlite3_open(zSrcFile, &pSrc);
+ if( rc!=SQLITE_OK ){
+ utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
+ close_db(pSrc);
+ return 1;
+ }
+ open_db(p, 0);
+ pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
+ if( pBackup==0 ){
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+ close_db(pSrc);
+ return 1;
+ }
+ while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
+ || rc==SQLITE_BUSY ){
+ if( rc==SQLITE_BUSY ){
+ if( nTimeout++ >= 3 ) break;
+ sqlite3_sleep(100);
+ }
+ }
+ sqlite3_backup_finish(pBackup);
+ if( rc==SQLITE_DONE ){
+ rc = 0;
+ }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
+ raw_printf(stderr, "Error: source database is busy\n");
+ rc = 1;
+ }else{
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+ rc = 1;
+ }
+ close_db(pSrc);
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
+ if( nArg==2 ){
+ p->scanstatsOn = (u8)booleanValue(azArg[1]);
+#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
+ raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
+#endif
+ }else{
+ raw_printf(stderr, "Usage: .scanstats on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
+ ShellText sSelect;
+ ShellState data;
+ char *zErrMsg = 0;
+ const char *zDiv = "(";
+ const char *zName = 0;
+ int iSchema = 0;
+ int bDebug = 0;
+ int ii;
+
+ open_db(p, 0);
+ memcpy(&data, p, sizeof(data));
+ data.showHeader = 0;
+ data.cMode = data.mode = MODE_Semi;
+ initText(&sSelect);
+ for(ii=1; ii<nArg; ii++){
+ if( optionMatch(azArg[ii],"indent") ){
+ data.cMode = data.mode = MODE_Pretty;
+ }else if( optionMatch(azArg[ii],"debug") ){
+ bDebug = 1;
+ }else if( zName==0 ){
+ zName = azArg[ii];
+ }else{
+ raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }
+ if( zName!=0 ){
+ int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0;
+ if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){
+ char *new_argv[2], *new_colv[2];
+ new_argv[0] = sqlite3_mprintf(
+ "CREATE TABLE %s (\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")", isMaster ? "sqlite_master" : "sqlite_temp_master");
+ new_argv[1] = 0;
+ new_colv[0] = "sql";
+ new_colv[1] = 0;
+ callback(&data, 1, new_argv, new_colv);
+ sqlite3_free(new_argv[0]);
+ }
+ }
+ if( zDiv ){
+ sqlite3_stmt *pStmt = 0;
+ rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
+ -1, &pStmt, 0);
+ if( rc ){
+ utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+ sqlite3_finalize(pStmt);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ appendText(&sSelect, "SELECT sql FROM", 0);
+ iSchema = 0;
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
+ char zScNum[30];
+ sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
+ appendText(&sSelect, zDiv, 0);
+ zDiv = " UNION ALL ";
+ appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
+ if( sqlite3_stricmp(zDb, "main")!=0 ){
+ appendText(&sSelect, zDb, '"');
+ }else{
+ appendText(&sSelect, "NULL", 0);
+ }
+ appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
+ appendText(&sSelect, zScNum, 0);
+ appendText(&sSelect, " AS snum, ", 0);
+ appendText(&sSelect, zDb, '\'');
+ appendText(&sSelect, " AS sname FROM ", 0);
+ appendText(&sSelect, zDb, '"');
+ appendText(&sSelect, ".sqlite_master", 0);
+ }
+ sqlite3_finalize(pStmt);
+#ifdef SQLITE_INTROSPECTION_PRAGMAS
+ if( zName ){
+ appendText(&sSelect,
+ " UNION ALL SELECT shell_module_schema(name),"
+ " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
+ }
+#endif
+ appendText(&sSelect, ") WHERE ", 0);
+ if( zName ){
+ char *zQarg = sqlite3_mprintf("%Q", zName);
+ int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
+ strchr(zName, '[') != 0;
+ if( strchr(zName, '.') ){
+ appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
+ }else{
+ appendText(&sSelect, "lower(tbl_name)", 0);
+ }
+ appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
+ appendText(&sSelect, zQarg, 0);
+ if( !bGlob ){
+ appendText(&sSelect, " ESCAPE '\\' ", 0);
+ }
+ appendText(&sSelect, " AND ", 0);
+ sqlite3_free(zQarg);
+ }
+ appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
+ " ORDER BY snum, rowid", 0);
+ if( bDebug ){
+ utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
+ }else{
+ rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
+ }
+ freeText(&sSelect);
+ }
+ if( zErrMsg ){
+ utf8_printf(stderr,"Error: %s\n", zErrMsg);
+ sqlite3_free(zErrMsg);
+ rc = 1;
+ }else if( rc != SQLITE_OK ){
+ raw_printf(stderr,"Error: querying schema information\n");
+ rc = 1;
+ }else{
+ rc = 0;
+ }
+ }else
+
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
+ if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
+ sqlite3SelectTrace = (int)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:
+ showHelp(p->out, "session");
+ }else
+#endif
+
+#ifdef SQLITE_DEBUG
+ /* Undocumented commands for internal testing. Subject to change
+ ** without notice. */
+ if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
+ if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
+ int i, v;
+ for(i=1; i<nArg; i++){
+ v = booleanValue(azArg[i]);
+ utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
+ }
+ }
+ if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
+ int i; sqlite3_int64 v;
+ for(i=1; i<nArg; i++){
+ char zBuf[200];
+ v = integerValue(azArg[i]);
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
+ utf8_printf(p->out, "%s", zBuf);
+ }
+ }
+ }else
+#endif
+
+ if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
+ int bIsInit = 0; /* True to initialize the SELFTEST table */
+ int bVerbose = 0; /* Verbose output */
+ int bSelftestExists; /* True if SELFTEST already exists */
+ int i, k; /* Loop counters */
+ int nTest = 0; /* Number of tests runs */
+ int nErr = 0; /* Number of errors seen */
+ ShellText str; /* Answer for a query */
+ sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
+
+ open_db(p,0);
+ for(i=1; i<nArg; i++){
+ const char *z = azArg[i];
+ if( z[0]=='-' && z[1]=='-' ) z++;
+ if( strcmp(z,"-init")==0 ){
+ bIsInit = 1;
+ }else
+ if( strcmp(z,"-v")==0 ){
+ bVerbose++;
+ }else
+ {
+ utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
+ azArg[i], azArg[0]);
+ raw_printf(stderr, "Should be one of: --init -v\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }
+ if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
+ != SQLITE_OK ){
+ bSelftestExists = 0;
+ }else{
+ bSelftestExists = 1;
+ }
+ if( bIsInit ){
+ createSelftestTable(p);
+ bSelftestExists = 1;
+ }
+ initText(&str);
+ appendText(&str, "x", 0);
+ for(k=bSelftestExists; k>=0; k--){
+ if( k==1 ){
+ rc = sqlite3_prepare_v2(p->db,
+ "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
+ -1, &pStmt, 0);
+ }else{
+ rc = sqlite3_prepare_v2(p->db,
+ "VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
+ " (1,'run','PRAGMA integrity_check','ok')",
+ -1, &pStmt, 0);
+ }
+ if( rc ){
+ raw_printf(stderr, "Error querying the selftest table\n");
+ rc = 1;
+ sqlite3_finalize(pStmt);
+ goto meta_command_exit;
+ }
+ for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
+ int tno = sqlite3_column_int(pStmt, 0);
+ const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
+ const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
+ const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
+
+ k = 0;
+ if( bVerbose>0 ){
+ char *zQuote = sqlite3_mprintf("%q", zSql);
+ printf("%d: %s %s\n", tno, zOp, zSql);
+ sqlite3_free(zQuote);
+ }
+ if( strcmp(zOp,"memo")==0 ){
+ utf8_printf(p->out, "%s\n", zSql);
+ }else
+ if( strcmp(zOp,"run")==0 ){
+ char *zErrMsg = 0;
+ str.n = 0;
+ str.z[0] = 0;
+ rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
+ nTest++;
+ if( bVerbose ){
+ utf8_printf(p->out, "Result: %s\n", str.z);
+ }
+ if( rc || zErrMsg ){
+ nErr++;
+ rc = 1;
+ utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
+ sqlite3_free(zErrMsg);
+ }else if( strcmp(zAns,str.z)!=0 ){
+ nErr++;
+ rc = 1;
+ utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
+ utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
+ }
+ }else
+ {
+ utf8_printf(stderr,
+ "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
+ rc = 1;
+ break;
+ }
+ } /* End loop over rows of content from SELFTEST */
+ sqlite3_finalize(pStmt);
+ } /* End loop over k */
+ freeText(&str);
+ utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
+ if( nArg<2 || nArg>3 ){
+ raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
+ rc = 1;
+ }
+ if( nArg>=2 ){
+ sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
+ "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
+ }
+ if( nArg>=3 ){
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
+ "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
+ }
+ }else
+
+ if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
+ const char *zLike = 0; /* Which table to checksum. 0 means everything */
+ int i; /* Loop counter */
+ int bSchema = 0; /* Also hash the schema */
+ int bSeparate = 0; /* Hash each table separately */
+ int iSize = 224; /* Hash algorithm to use */
+ int bDebug = 0; /* Only show the query that would have run */
+ sqlite3_stmt *pStmt; /* For querying tables names */
+ char *zSql; /* SQL to be run */
+ char *zSep; /* Separator */
+ ShellText sSql; /* Complete SQL for the query to run the hash */
+ ShellText sQuery; /* Set of queries used to read all content */
+ open_db(p, 0);
+ for(i=1; i<nArg; i++){
+ const char *z = azArg[i];
+ if( z[0]=='-' ){
+ z++;
+ if( z[0]=='-' ) z++;
+ if( strcmp(z,"schema")==0 ){
+ bSchema = 1;
+ }else
+ if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
+ || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
+ ){
+ iSize = atoi(&z[5]);
+ }else
+ if( strcmp(z,"debug")==0 ){
+ bDebug = 1;
+ }else
+ {
+ utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
+ azArg[i], azArg[0]);
+ raw_printf(stderr, "Should be one of: --schema"
+ " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }else if( zLike ){
+ raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
+ rc = 1;
+ goto meta_command_exit;
+ }else{
+ zLike = z;
+ bSeparate = 1;
+ if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
+ }
+ }
+ if( bSchema ){
+ zSql = "SELECT lower(name) FROM sqlite_master"
+ " WHERE type='table' AND coalesce(rootpage,0)>1"
+ " UNION ALL SELECT 'sqlite_master'"
+ " ORDER BY 1 collate nocase";
+ }else{
+ zSql = "SELECT lower(name) FROM sqlite_master"
+ " WHERE type='table' AND coalesce(rootpage,0)>1"
+ " AND name NOT LIKE 'sqlite_%'"
+ " ORDER BY 1 collate nocase";
+ }
+ sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+ initText(&sQuery);
+ initText(&sSql);
+ appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
+ zSep = "VALUES(";
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
+ const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
+ if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
+ if( strncmp(zTab, "sqlite_",7)!=0 ){
+ appendText(&sQuery,"SELECT * FROM ", 0);
+ appendText(&sQuery,zTab,'"');
+ appendText(&sQuery," NOT INDEXED;", 0);
+ }else if( strcmp(zTab, "sqlite_master")==0 ){
+ appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_master"
+ " ORDER BY name;", 0);
+ }else if( strcmp(zTab, "sqlite_sequence")==0 ){
+ appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
+ " ORDER BY name;", 0);
+ }else if( strcmp(zTab, "sqlite_stat1")==0 ){
+ appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
+ " ORDER BY tbl,idx;", 0);
+ }else if( strcmp(zTab, "sqlite_stat3")==0
+ || strcmp(zTab, "sqlite_stat4")==0 ){
+ appendText(&sQuery, "SELECT * FROM ", 0);
+ appendText(&sQuery, zTab, 0);
+ appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
+ }
+ appendText(&sSql, zSep, 0);
+ appendText(&sSql, sQuery.z, '\'');
+ sQuery.n = 0;
+ appendText(&sSql, ",", 0);
+ appendText(&sSql, zTab, '\'');
+ zSep = "),(";
+ }
+ sqlite3_finalize(pStmt);
+ if( bSeparate ){
+ zSql = sqlite3_mprintf(
+ "%s))"
+ " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
+ " FROM [sha3sum$query]",
+ sSql.z, iSize);
+ }else{
+ zSql = sqlite3_mprintf(
+ "%s))"
+ " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
+ " FROM [sha3sum$query]",
+ sSql.z, iSize);
+ }
+ freeText(&sQuery);
+ freeText(&sSql);
+ if( bDebug ){
+ utf8_printf(p->out, "%s\n", zSql);
+ }else{
+ shell_exec(p, zSql, 0);
+ }
+ sqlite3_free(zSql);
+ }else
+
+#ifndef SQLITE_NOHAVE_SYSTEM
+ if( c=='s'
+ && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
+ ){
+ char *zCmd;
+ int i, x;
+ if( nArg<2 ){
+ raw_printf(stderr, "Usage: .system COMMAND\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
+ for(i=2; i<nArg; i++){
+ zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
+ zCmd, azArg[i]);
+ }
+ x = system(zCmd);
+ sqlite3_free(zCmd);
+ if( x ) raw_printf(stderr, "System command returns %d\n", x);
+ }else
+#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
+
+ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
+ static const char *const azBool[] = { "off", "on", "trigger", "full"};
+ 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",
+ azBool[ShellHasFlag(p, SHFLG_Echo)]);
+ 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", 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);
+ raw_printf(p->out, "\n");
+ utf8_printf(p->out,"%12.12s: %s\n","output",
+ strlen30(p->outfile) ? p->outfile : "stdout");
+ utf8_printf(p->out,"%12.12s: ", "colseparator");
+ output_c_string(p->out, p->colSeparator);
+ raw_printf(p->out, "\n");
+ 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", 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]);
+ }
+ raw_printf(p->out, "\n");
+ utf8_printf(p->out, "%12.12s: %s\n", "filename",
+ p->zDbFilename ? p->zDbFilename : "");
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
+ if( nArg==2 ){
+ p->statsOn = (u8)booleanValue(azArg[1]);
+ }else if( nArg==1 ){
+ display_stats(p->db, p, 0);
+ }else{
+ raw_printf(stderr, "Usage: .stats ?on|off?\n");
+ rc = 1;
+ }
+ }else
+
+ if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
+ || (c=='i' && (strncmp(azArg[0], "indices", n)==0
+ || strncmp(azArg[0], "indexes", n)==0) )
+ ){
+ sqlite3_stmt *pStmt;
+ char **azResult;
+ int nRow, nAlloc;
+ int ii;
+ ShellText s;
+ initText(&s);
+ open_db(p, 0);
+ rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
+ if( rc ){
+ sqlite3_finalize(pStmt);
+ return shellDatabaseError(p->db);
+ }
+
+ if( nArg>2 && c=='i' ){
+ /* It is an historical accident that the .indexes command shows an error
+ ** when called with the wrong number of arguments whereas the .tables
+ ** command does not. */
+ raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
+ rc = 1;
+ sqlite3_finalize(pStmt);
+ goto meta_command_exit;
+ }
+ for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
+ const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
+ if( zDbName==0 ) continue;
+ if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
+ if( sqlite3_stricmp(zDbName, "main")==0 ){
+ appendText(&s, "SELECT name FROM ", 0);
+ }else{
+ appendText(&s, "SELECT ", 0);
+ appendText(&s, zDbName, '\'');
+ appendText(&s, "||'.'||name FROM ", 0);
+ }
+ appendText(&s, zDbName, '"');
+ appendText(&s, ".sqlite_master ", 0);
+ if( c=='t' ){
+ appendText(&s," WHERE type IN ('table','view')"
+ " AND name NOT LIKE 'sqlite_%'"
+ " AND name LIKE ?1", 0);
+ }else{
+ appendText(&s," WHERE type='index'"
+ " AND tbl_name LIKE ?1", 0);
+ }
+ }
+ rc = sqlite3_finalize(pStmt);
+ appendText(&s, " ORDER BY 1", 0);
+ rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
+ freeText(&s);
+ if( rc ) return shellDatabaseError(p->db);
+
+ /* Run the SQL statement prepared by the above block. Store the results
+ ** as an array of nul-terminated strings in azResult[]. */
+ nRow = nAlloc = 0;
+ azResult = 0;
+ if( nArg>1 ){
+ sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
+ }
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ if( nRow>=nAlloc ){
+ char **azNew;
+ int n2 = nAlloc*2 + 10;
+ azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n2);
+ if( azNew==0 ) shell_out_of_memory();
+ nAlloc = n2;
+ azResult = azNew;
+ }
+ azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
+ if( 0==azResult[nRow] ) shell_out_of_memory();
+ nRow++;
+ }
+ if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
+ rc = shellDatabaseError(p->db);
+ }
+
+ /* Pretty-print the contents of array azResult[] to the output */
+ if( rc==0 && nRow>0 ){
+ int len, maxlen = 0;
+ int i, j;
+ int nPrintCol, nPrintRow;
+ for(i=0; i<nRow; i++){
+ len = strlen30(azResult[i]);
+ if( len>maxlen ) maxlen = len;
+ }
+ nPrintCol = 80/(maxlen+2);
+ if( nPrintCol<1 ) nPrintCol = 1;
+ nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
+ for(i=0; i<nPrintRow; i++){
+ for(j=i; j<nRow; j+=nPrintRow){
+ char *zSp = j<nPrintRow ? "" : " ";
+ utf8_printf(p->out, "%s%-*s", zSp, maxlen,
+ azResult[j] ? azResult[j]:"");
+ }
+ raw_printf(p->out, "\n");
+ }
+ }
+
+ for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
+ sqlite3_free(azResult);
+ }else
+
+ /* Begin redirecting output to the file "testcase-out.txt" */
+ if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
+ output_reset(p);
+ p->out = output_file_open("testcase-out.txt", 0);
+ if( p->out==0 ){
+ raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
+ }
+ if( nArg>=2 ){
+ sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
+ }else{
+ sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
+ }
+ }else
+
+#ifndef SQLITE_UNTESTABLE
+ if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
+ static const struct {
+ const char *zCtrlName; /* Name of a test-control option */
+ int ctrlCode; /* Integer code for that option */
+ const char *zUsage; /* Usage notes */
+ } aCtrl[] = {
+ { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
+ { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
+ /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
+ /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
+ { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
+ /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
+ { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
+ { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
+ { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
+ { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
+#ifdef YYCOVERAGE
+ { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
+#endif
+ { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
+ { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" },
+ { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
+ { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
+ { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" },
+ };
+ int testctrl = -1;
+ int iCtrl = -1;
+ int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
+ int isOk = 0;
+ int i, n2;
+ const char *zCmd = 0;
+
+ open_db(p, 0);
+ zCmd = nArg>=2 ? azArg[1] : "help";
+
+ /* The argument can optionally begin with "-" or "--" */
+ if( zCmd[0]=='-' && zCmd[1] ){
+ zCmd++;
+ if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
+ }
+
+ /* --help lists all test-controls */
+ if( strcmp(zCmd,"help")==0 ){
+ utf8_printf(p->out, "Available test-controls:\n");
+ for(i=0; i<ArraySize(aCtrl); i++){
+ utf8_printf(p->out, " .testctrl %s %s\n",
+ aCtrl[i].zCtrlName, aCtrl[i].zUsage);
+ }
+ rc = 1;
+ goto meta_command_exit;
+ }
+
+ /* convert testctrl text option to value. allow any unique prefix
+ ** of the option name, or a numerical value. */
+ n2 = strlen30(zCmd);
+ for(i=0; i<ArraySize(aCtrl); i++){
+ if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
+ if( testctrl<0 ){
+ testctrl = aCtrl[i].ctrlCode;
+ iCtrl = i;
+ }else{
+ utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
+ "Use \".testctrl --help\" for help\n", zCmd);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }
+ }
+ if( testctrl<0 ){
+ utf8_printf(stderr,"Error: unknown test-control: %s\n"
+ "Use \".testctrl --help\" for help\n", zCmd);
+ }else{
+ switch(testctrl){
+
+ /* sqlite3_test_control(int, db, int) */
+ case SQLITE_TESTCTRL_OPTIMIZATIONS:
+ case SQLITE_TESTCTRL_RESERVE:
+ if( nArg==3 ){
+ int opt = (int)strtol(azArg[2], 0, 0);
+ rc2 = sqlite3_test_control(testctrl, p->db, opt);
+ isOk = 3;
+ }
+ break;
+
+ /* sqlite3_test_control(int) */
+ case SQLITE_TESTCTRL_PRNG_SAVE:
+ case SQLITE_TESTCTRL_PRNG_RESTORE:
+ case SQLITE_TESTCTRL_PRNG_RESET:
+ case SQLITE_TESTCTRL_BYTEORDER:
+ if( nArg==2 ){
+ rc2 = sqlite3_test_control(testctrl);
+ isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
+ }
+ break;
+
+ /* sqlite3_test_control(int, uint) */
+ case SQLITE_TESTCTRL_PENDING_BYTE:
+ if( nArg==3 ){
+ unsigned int opt = (unsigned int)integerValue(azArg[2]);
+ rc2 = sqlite3_test_control(testctrl, opt);
+ isOk = 3;
+ }
+ break;
+
+ /* sqlite3_test_control(int, int) */
+ case SQLITE_TESTCTRL_ASSERT:
+ case SQLITE_TESTCTRL_ALWAYS:
+ if( nArg==3 ){
+ int opt = booleanValue(azArg[2]);
+ rc2 = sqlite3_test_control(testctrl, opt);
+ isOk = 1;
+ }
+ break;
+
+ /* sqlite3_test_control(int, int) */
+ case SQLITE_TESTCTRL_LOCALTIME_FAULT:
+ case SQLITE_TESTCTRL_NEVER_CORRUPT:
+ if( nArg==3 ){
+ int opt = booleanValue(azArg[2]);
+ rc2 = sqlite3_test_control(testctrl, opt);
+ isOk = 3;
+ }
+ break;
+
+ case SQLITE_TESTCTRL_IMPOSTER:
+ if( nArg==5 ){
+ rc2 = sqlite3_test_control(testctrl, p->db,
+ azArg[2],
+ integerValue(azArg[3]),
+ integerValue(azArg[4]));
+ isOk = 3;
+ }
+ break;
+
+#ifdef YYCOVERAGE
+ case SQLITE_TESTCTRL_PARSER_COVERAGE:
+ if( nArg==2 ){
+ sqlite3_test_control(testctrl, p->out);
+ isOk = 3;
+ }
+#endif
+ }
+ }
+ if( isOk==0 && iCtrl>=0 ){
+ utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage);
+ rc = 1;
+ }else if( isOk==1 ){
+ raw_printf(p->out, "%d\n", rc2);
+ }else if( isOk==2 ){
+ raw_printf(p->out, "0x%08x\n", rc2);
+ }
+ }else
+#endif /* !defined(SQLITE_UNTESTABLE) */
+
+ if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
+ 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]);
+ if( enableTimer && !HAS_TIMER ){
+ raw_printf(stderr, "Error: timer not available on this system.\n");
+ enableTimer = 0;
+ }
+ }else{
+ raw_printf(stderr, "Usage: .timer on|off\n");
+ rc = 1;
+ }
+ }else
+
+ if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
+ open_db(p, 0);
+ if( nArg!=2 ){
+ raw_printf(stderr, "Usage: .trace FILE|off\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ output_file_close(p->traceOut);
+ p->traceOut = output_file_open(azArg[1], 0);
+#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
+ if( p->traceOut==0 ){
+ sqlite3_trace_v2(p->db, 0, 0, 0);
+ }else{
+ sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
+ }
+#endif
+ }else
+
+#if SQLITE_USER_AUTHENTICATION
+ if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
+ if( nArg<2 ){
+ raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ open_db(p, 0);
+ if( strcmp(azArg[1],"login")==0 ){
+ if( nArg!=4 ){
+ raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3]));
+ if( rc ){
+ utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
+ rc = 1;
+ }
+ }else if( strcmp(azArg[1],"add")==0 ){
+ if( nArg!=5 ){
+ raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
+ booleanValue(azArg[4]));
+ if( rc ){
+ raw_printf(stderr, "User-Add failed: %d\n", rc);
+ rc = 1;
+ }
+ }else if( strcmp(azArg[1],"edit")==0 ){
+ if( nArg!=5 ){
+ raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
+ booleanValue(azArg[4]));
+ if( rc ){
+ raw_printf(stderr, "User-Edit failed: %d\n", rc);
+ rc = 1;
+ }
+ }else if( strcmp(azArg[1],"delete")==0 ){
+ if( nArg!=3 ){
+ raw_printf(stderr, "Usage: .user delete USER\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ rc = sqlite3_user_delete(p->db, azArg[2]);
+ if( rc ){
+ raw_printf(stderr, "User-Delete failed: %d\n", rc);
+ rc = 1;
+ }
+ }else{
+ raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }else
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+ if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
+ utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
+ sqlite3_libversion(), sqlite3_sourceid());
+#if SQLITE_HAVE_ZLIB
+ utf8_printf(p->out, "zlib version %s\n", zlibVersion());
+#endif
+#define CTIMEOPT_VAL_(opt) #opt
+#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+#if defined(__clang__) && defined(__clang_major__)
+ utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
+ CTIMEOPT_VAL(__clang_minor__) "."
+ CTIMEOPT_VAL(__clang_patchlevel__) "\n");
+#elif defined(_MSC_VER)
+ utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
+#elif defined(__GNUC__) && defined(__VERSION__)
+ utf8_printf(p->out, "gcc-" __VERSION__ "\n");
+#endif
+ }else
+
+ if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
+ const char *zDbName = nArg==2 ? azArg[1] : "main";
+ sqlite3_vfs *pVfs = 0;
+ if( p->db ){
+ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
+ if( pVfs ){
+ utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
+ raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
+ raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
+ raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
+ }
+ }
+ }else
+
+ if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
+ sqlite3_vfs *pVfs;
+ sqlite3_vfs *pCurrent = 0;
+ if( p->db ){
+ sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
+ }
+ for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
+ utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
+ pVfs==pCurrent ? " <--- CURRENT" : "");
+ raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
+ raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
+ raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
+ if( pVfs->pNext ){
+ raw_printf(p->out, "-----------------------------------\n");
+ }
+ }
+ }else
+
+ if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
+ const char *zDbName = nArg==2 ? azArg[1] : "main";
+ char *zVfsName = 0;
+ if( p->db ){
+ sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
+ if( zVfsName ){
+ utf8_printf(p->out, "%s\n", zVfsName);
+ sqlite3_free(zVfsName);
+ }
+ }
+ }else
+
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
+ if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
+ sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
+ }else
+#endif
+
+ if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
+ int j;
+ assert( nArg<=ArraySize(azArg) );
+ for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
+ p->colWidth[j-1] = (int)integerValue(azArg[j]);
+ }
+ }else
+
+ {
+ utf8_printf(stderr, "Error: unknown command or invalid arguments: "
+ " \"%s\". Enter \".help\" for help\n", azArg[0]);
+ rc = 1;
+ }
+
+meta_command_exit:
+ if( p->outCount ){
+ p->outCount--;
+ if( p->outCount==0 ) output_reset(p);
+ }
+ return rc;
+}
+
+/*
+** Return TRUE if a semicolon occurs anywhere in the first N characters
+** of string z[].
+*/
+static int line_contains_semicolon(const char *z, int N){
+ int i;
+ for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
+ return 0;
+}
+
+/*
+** Test to see if a line consists entirely of whitespace.
+*/
+static int _all_whitespace(const char *z){
+ for(; *z; z++){
+ if( IsSpace(z[0]) ) continue;
+ if( *z=='/' && z[1]=='*' ){
+ z += 2;
+ while( *z && (*z!='*' || z[1]!='/') ){ z++; }
+ if( *z==0 ) return 0;
+ z++;
+ continue;
+ }
+ if( *z=='-' && z[1]=='-' ){
+ z += 2;
+ while( *z && *z!='\n' ){ z++; }
+ if( *z==0 ) return 1;
+ continue;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Return TRUE if the line typed in is an SQL command terminator other
+** than a semi-colon. The SQL Server style "go" command is understood
+** as is the Oracle "/".
+*/
+static int line_is_command_terminator(const char *zLine){
+ while( IsSpace(zLine[0]) ){ zLine++; };
+ if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
+ return 1; /* Oracle */
+ }
+ if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
+ && _all_whitespace(&zLine[2]) ){
+ return 1; /* SQL Server */
+ }
+ return 0;
+}
+
+/*
+** We need a default sqlite3_complete() implementation to use in case
+** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
+** any arbitrary text is a complete SQL statement. This is not very
+** user-friendly, but it does seem to work.
+*/
+#ifdef SQLITE_OMIT_COMPLETE
+int sqlite3_complete(const char *zSql){ return 1; }
+#endif
+
+/*
+** Return true if zSql is a complete SQL statement. Return false if it
+** ends in the middle of a string literal or C-style comment.
+*/
+static int line_is_complete(char *zSql, int nSql){
+ int rc;
+ if( zSql==0 ) return 1;
+ zSql[nSql] = ';';
+ zSql[nSql+1] = 0;
+ rc = sqlite3_complete(zSql);
+ zSql[nSql] = 0;
+ return rc;
+}
+
+/*
+** Run a single line of SQL. Return the number of errors.
+*/
+static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
+ int rc;
+ char *zErrMsg = 0;
+
+ open_db(p, 0);
+ if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
+ BEGIN_TIMER;
+ rc = shell_exec(p, zSql, &zErrMsg);
+ END_TIMER;
+ if( rc || zErrMsg ){
+ char zPrefix[100];
+ if( in!=0 || !stdin_is_interactive ){
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix,
+ "Error: near line %d:", startline);
+ }else{
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
+ }
+ if( zErrMsg!=0 ){
+ utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }else{
+ utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
+ }
+ return 1;
+ }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
+ raw_printf(p->out, "changes: %3d total_changes: %d\n",
+ sqlite3_changes(p->db), sqlite3_total_changes(p->db));
+ }
+ return 0;
+}
+
+
+/*
+** Read input from *in and process it. If *in==0 then input
+** is interactive - the user is typing it it. Otherwise, input
+** is coming from a file or device. A prompt is issued and history
+** is saved only if input is interactive. An interrupt signal will
+** cause this routine to exit immediately, unless input is interactive.
+**
+** Return the number of errors.
+*/
+static int process_input(ShellState *p, FILE *in){
+ char *zLine = 0; /* A single input line */
+ char *zSql = 0; /* Accumulated SQL text */
+ int nLine; /* Length of current line */
+ int nSql = 0; /* Bytes of zSql[] used */
+ int nAlloc = 0; /* Allocated zSql[] space */
+ int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
+ int rc; /* Error code */
+ int errCnt = 0; /* Number of errors seen */
+ int lineno = 0; /* Current line number */
+ int startline = 0; /* Line number for start of current input */
+
+ while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
+ fflush(p->out);
+ zLine = one_input_line(in, zLine, nSql>0);
+ if( zLine==0 ){
+ /* End of input */
+ if( in==0 && stdin_is_interactive ) printf("\n");
+ break;
+ }
+ if( seenInterrupt ){
+ if( in!=0 ) break;
+ seenInterrupt = 0;
+ }
+ lineno++;
+ if( nSql==0 && _all_whitespace(zLine) ){
+ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+ continue;
+ }
+ if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
+ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+ if( zLine[0]=='.' ){
+ rc = do_meta_command(zLine, p);
+ if( rc==2 ){ /* exit requested */
+ break;
+ }else if( rc ){
+ errCnt++;
+ }
+ }
+ continue;
+ }
+ if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
+ memcpy(zLine,";",2);
+ }
+ nLine = strlen30(zLine);
+ if( nSql+nLine+2>=nAlloc ){
+ nAlloc = nSql+nLine+100;
+ zSql = realloc(zSql, nAlloc);
+ if( zSql==0 ) shell_out_of_memory();
+ }
+ nSqlPrior = nSql;
+ if( nSql==0 ){
+ int i;
+ for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
+ assert( nAlloc>0 && zSql!=0 );
+ memcpy(zSql, zLine+i, nLine+1-i);
+ startline = lineno;
+ nSql = nLine-i;
+ }else{
+ zSql[nSql++] = '\n';
+ memcpy(zSql+nSql, zLine, nLine+1);
+ nSql += nLine;
+ }
+ if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
+ && sqlite3_complete(zSql) ){
+ errCnt += runOneSqlLine(p, zSql, in, startline);
+ nSql = 0;
+ if( p->outCount ){
+ output_reset(p);
+ p->outCount = 0;
+ }else{
+ clearTempFile(p);
+ }
+ }else if( nSql && _all_whitespace(zSql) ){
+ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
+ nSql = 0;
+ }
+ }
+ if( nSql && !_all_whitespace(zSql) ){
+ errCnt += runOneSqlLine(p, zSql, in, startline);
+ }
+ free(zSql);
+ free(zLine);
+ return errCnt>0;
+}
+
+/*
+** Return a pathname which is the user's home directory. A
+** 0 return indicates an error of some kind.
+*/
+static char *find_home_dir(int clearFlag){
+ static char *home_dir = NULL;
+ if( clearFlag ){
+ free(home_dir);
+ home_dir = 0;
+ return 0;
+ }
+ if( home_dir ) return home_dir;
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
+ && !defined(__RTP__) && !defined(_WRS_KERNEL)
+ {
+ struct passwd *pwent;
+ uid_t uid = getuid();
+ if( (pwent=getpwuid(uid)) != NULL) {
+ home_dir = pwent->pw_dir;
+ }
+ }
+#endif
+
+#if defined(_WIN32_WCE)
+ /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
+ */
+ home_dir = "/";
+#else
+
+#if defined(_WIN32) || defined(WIN32)
+ if (!home_dir) {
+ home_dir = getenv("USERPROFILE");
+ }
+#endif
+
+ if (!home_dir) {
+ home_dir = getenv("HOME");
+ }
+
+#if defined(_WIN32) || defined(WIN32)
+ if (!home_dir) {
+ char *zDrive, *zPath;
+ int n;
+ zDrive = getenv("HOMEDRIVE");
+ zPath = getenv("HOMEPATH");
+ if( zDrive && zPath ){
+ n = strlen30(zDrive) + strlen30(zPath) + 1;
+ home_dir = malloc( n );
+ if( home_dir==0 ) return 0;
+ sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
+ return home_dir;
+ }
+ home_dir = "c:\\";
+ }
+#endif
+
+#endif /* !_WIN32_WCE */
+
+ if( home_dir ){
+ int n = strlen30(home_dir) + 1;
+ char *z = malloc( n );
+ if( z ) memcpy(z, home_dir, n);
+ home_dir = z;
+ }
+
+ return home_dir;
+}
+
+/*
+** Read input from the file given by sqliterc_override. Or if that
+** parameter is NULL, take input from ~/.sqliterc
+**
+** Returns the number of errors.
+*/
+static void process_sqliterc(
+ ShellState *p, /* Configuration data */
+ const char *sqliterc_override /* Name of config file. NULL to use default */
+){
+ char *home_dir = NULL;
+ const char *sqliterc = sqliterc_override;
+ char *zBuf = 0;
+ FILE *in = NULL;
+
+ if (sqliterc == NULL) {
+ home_dir = find_home_dir(0);
+ if( home_dir==0 ){
+ raw_printf(stderr, "-- warning: cannot find home directory;"
+ " cannot read ~/.sqliterc\n");
+ return;
+ }
+ zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
+ sqliterc = zBuf;
+ }
+ in = fopen(sqliterc,"rb");
+ if( in ){
+ if( stdin_is_interactive ){
+ utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
+ }
+ process_input(p,in);
+ fclose(in);
+ }
+ sqlite3_free(zBuf);
+}
+
+/*
+** Show available command line options
+*/
+static const char zOptions[] =
+#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+ " -A ARGS... run \".archive ARGS\" and exit\n"
+#endif
+ " -append append the database to the end of the file\n"
+ " -ascii set output mode to 'ascii'\n"
+ " -bail stop after hitting an error\n"
+ " -batch force batch I/O\n"
+ " -column set output mode to 'column'\n"
+ " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
+ " -csv set output mode to 'csv'\n"
+ " -echo print commands before execution\n"
+ " -init FILENAME read/process named file\n"
+ " -[no]header turn headers on or off\n"
+#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
+ " -heap SIZE Size of heap for memsys3 or memsys5\n"
+#endif
+ " -help show this message\n"
+ " -html set output mode to HTML\n"
+ " -interactive force interactive I/O\n"
+ " -line set output mode to 'line'\n"
+ " -list set output mode to 'list'\n"
+#ifndef SQLITE_OMIT_LOOKASIDE
+ " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
+#endif
+ " -mmap N default mmap size set to N\n"
+#ifdef SQLITE_ENABLE_MULTIPLEX
+ " -multiplex enable the multiplexor VFS\n"
+#endif
+ " -newline SEP set output row separator. Default: '\\n'\n"
+ " -nullvalue TEXT set text string for NULL values. Default ''\n"
+ " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
+ " -quote set output mode to 'quote'\n"
+ " -readonly open the database read-only\n"
+ " -scanstats print scan stats before each finalize\n"
+ " -separator SEP set output column separator. Default: '|'\n"
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ " -sorterref SIZE sorter references threshold size\n"
+#endif
+ " -stats print memory stats before each finalize\n"
+ " -version show SQLite version\n"
+ " -vfs NAME use NAME as the default VFS\n"
+#ifdef SQLITE_ENABLE_VFSTRACE
+ " -vfstrace enable tracing of all VFS calls\n"
+#endif
+#ifdef SQLITE_HAVE_ZLIB
+ " -zip open the file as a ZIP Archive\n"
+#endif
+;
+static void usage(int showDetail){
+ utf8_printf(stderr,
+ "Usage: %s [OPTIONS] FILENAME [SQL]\n"
+ "FILENAME is the name of an SQLite database. A new database is created\n"
+ "if the file does not previously exist.\n", Argv0);
+ if( showDetail ){
+ utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
+ }else{
+ raw_printf(stderr, "Use the -help option for additional information\n");
+ }
+ exit(1);
+}
+
+/*
+** Internal check: Verify that the SQLite is uninitialized. Print a
+** error message if it is initialized.
+*/
+static void verify_uninitialized(void){
+ if( sqlite3_config(-1)==SQLITE_MISUSE ){
+ utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
+ " initialization.\n");
+ }
+}
+
+/*
+** Initialize the state information in data
+*/
+static void main_init(ShellState *data) {
+ memset(data, 0, sizeof(*data));
+ data->normalMode = data->cMode = data->mode = MODE_List;
+ data->autoExplain = 1;
+ memcpy(data->colSeparator,SEP_Column, 2);
+ memcpy(data->rowSeparator,SEP_Row, 2);
+ data->showHeader = 0;
+ data->shellFlgs = SHFLG_Lookaside;
+ verify_uninitialized();
+ sqlite3_config(SQLITE_CONFIG_URI, 1);
+ sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
+ sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
+ sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
+ sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
+}
+
+/*
+** Output text to the console in a font that attracts extra attention.
+*/
+#ifdef _WIN32
+static void printBold(const char *zText){
+ HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
+ CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
+ GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
+ SetConsoleTextAttribute(out,
+ FOREGROUND_RED|FOREGROUND_INTENSITY
+ );
+ printf("%s", zText);
+ SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
+}
+#else
+static void printBold(const char *zText){
+ printf("\033[1m%s\033[0m", zText);
+}
+#endif
+
+/*
+** Get the argument to an --option. Throw an error and die if no argument
+** is available.
+*/
+static char *cmdline_option_value(int argc, char **argv, int i){
+ if( i==argc ){
+ utf8_printf(stderr, "%s: Error: missing argument to %s\n",
+ argv[0], argv[argc-1]);
+ exit(1);
+ }
+ return argv[i];
+}
+
+#if defined(_WIN32) && defined(__MSVCRT__) && !defined(main)
+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;
+ int i;
+ int rc = 0;
+ int warnInmemoryDb = 0;
+ int readStdin = 1;
+ int nCmd = 0;
+ char **azCmd = 0;
+ const char *zVfs = 0; /* Value of -vfs command-line option */
+#if !SQLITE_SHELL_IS_UTF8
+ char **argvToFree = 0;
+ int argcToFree = 0;
+#endif
+
+ setBinaryMode(stdin, 0);
+ setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+ stdin_is_interactive = isatty(0);
+ stdout_is_console = isatty(1);
+
+#if !defined(_WIN32_WCE)
+ if( getenv("SQLITE_DEBUG_BREAK") ){
+ if( isatty(0) && isatty(2) ){
+ fprintf(stderr,
+ "attach debugger to process %d and press any key to continue.\n",
+ GETPID());
+ fgetc(stdin);
+ }else{
+#if defined(_WIN32) || defined(WIN32)
+ DebugBreak();
+#elif defined(SIGTRAP)
+ raise(SIGTRAP);
+#endif
+ }
+ }
+#endif
+
+#if USE_SYSTEM_SQLITE+0!=1
+ if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
+ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
+ sqlite3_sourceid(), SQLITE_SOURCE_ID);
+ exit(1);
+ }
+#endif
+ main_init(&data);
+
+ /* On Windows, we must translate command-line arguments into UTF-8.
+ ** The SQLite memory allocator subsystem has to be enabled in order to
+ ** do this. But we want to run an sqlite3_shutdown() afterwards so that
+ ** subsequent sqlite3_config() calls will work. So copy all results into
+ ** memory that does not come from the SQLite memory allocator.
+ */
+#if !SQLITE_SHELL_IS_UTF8
+ sqlite3_initialize();
+ argvToFree = malloc(sizeof(argv[0])*argc*2);
+ argcToFree = argc;
+ argv = argvToFree + argc;
+ if( argv==0 ) shell_out_of_memory();
+ for(i=0; i<argc; i++){
+ char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
+ int n;
+ if( z==0 ) shell_out_of_memory();
+ n = (int)strlen(z);
+ argv[i] = malloc( n+1 );
+ if( argv[i]==0 ) shell_out_of_memory();
+ memcpy(argv[i], z, n+1);
+ argvToFree[i] = argv[i];
+ sqlite3_free(z);
+ }
+ sqlite3_shutdown();
+#endif
+
+ assert( argc>=1 && argv && argv[0] );
+ Argv0 = argv[0];
+
+ /* Make sure we have a valid signal handler early, before anything
+ ** else is done.
+ */
+#ifdef SIGINT
+ signal(SIGINT, interrupt_handler);
+#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
+ SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
+#endif
+
+#ifdef SQLITE_SHELL_DBNAME_PROC
+ {
+ /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
+ ** of a C-function that will provide the name of the database file. Use
+ ** this compile-time option to embed this shell program in larger
+ ** applications. */
+ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
+ SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
+ warnInmemoryDb = 0;
+ }
+#endif
+
+ /* Do an initial pass through the command-line argument to locate
+ ** the name of the database file, the name of the initialization file,
+ ** the size of the alternative malloc heap,
+ ** and the first command to execute.
+ */
+ verify_uninitialized();
+ for(i=1; i<argc; i++){
+ char *z;
+ z = argv[i];
+ if( z[0]!='-' ){
+ if( data.zDbFilename==0 ){
+ data.zDbFilename = z;
+ }else{
+ /* Excesss arguments are interpreted as SQL (or dot-commands) and
+ ** mean that nothing is read from stdin */
+ readStdin = 0;
+ nCmd++;
+ azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
+ if( azCmd==0 ) shell_out_of_memory();
+ azCmd[nCmd-1] = z;
+ }
+ }
+ if( z[1]=='-' ) z++;
+ if( strcmp(z,"-separator")==0
+ || strcmp(z,"-nullvalue")==0
+ || strcmp(z,"-newline")==0
+ || strcmp(z,"-cmd")==0
+ ){
+ (void)cmdline_option_value(argc, argv, ++i);
+ }else if( strcmp(z,"-init")==0 ){
+ 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
+ ** we do the actual processing of arguments later in a second pass.
+ */
+ stdin_is_interactive = 0;
+ }else if( strcmp(z,"-heap")==0 ){
+#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
+ const char *zSize;
+ sqlite3_int64 szHeap;
+
+ zSize = cmdline_option_value(argc, argv, ++i);
+ szHeap = integerValue(zSize);
+ if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
+ sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
+#else
+ (void)cmdline_option_value(argc, argv, ++i);
+#endif
+ }else if( strcmp(z,"-pagecache")==0 ){
+ int n, sz;
+ sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
+ if( sz>70000 ) sz = 70000;
+ if( sz<0 ) sz = 0;
+ n = (int)integerValue(cmdline_option_value(argc,argv,++i));
+ sqlite3_config(SQLITE_CONFIG_PAGECACHE,
+ (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
+ data.shellFlgs |= SHFLG_Pagecache;
+ }else if( strcmp(z,"-lookaside")==0 ){
+ int n, sz;
+ sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
+ if( sz<0 ) sz = 0;
+ n = (int)integerValue(cmdline_option_value(argc,argv,++i));
+ if( n<0 ) n = 0;
+ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
+ if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
+#ifdef SQLITE_ENABLE_VFSTRACE
+ }else if( strcmp(z,"-vfstrace")==0 ){
+ extern int vfstrace_register(
+ const char *zTraceName,
+ const char *zOldVfsName,
+ int (*xOut)(const char*,void*),
+ void *pOutArg,
+ int makeDefault
+ );
+ vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
+#endif
+#ifdef SQLITE_ENABLE_MULTIPLEX
+ }else if( strcmp(z,"-multiplex")==0 ){
+ extern int sqlite3_multiple_initialize(const char*,int);
+ sqlite3_multiplex_initialize(0, 1);
+#endif
+ }else if( strcmp(z,"-mmap")==0 ){
+ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+ sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ }else if( strcmp(z,"-sorterref")==0 ){
+ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+ sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
+#endif
+ }else if( strcmp(z,"-vfs")==0 ){
+ zVfs = cmdline_option_value(argc, argv, ++i);
+#ifdef SQLITE_HAVE_ZLIB
+ }else if( strcmp(z,"-zip")==0 ){
+ data.openMode = SHELL_OPEN_ZIPFILE;
+#endif
+ }else if( strcmp(z,"-append")==0 ){
+ data.openMode = SHELL_OPEN_APPENDVFS;
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ }else if( strcmp(z,"-deserialize")==0 ){
+ data.openMode = SHELL_OPEN_DESERIALIZE;
+#endif
+ }else if( strcmp(z,"-readonly")==0 ){
+ data.openMode = SHELL_OPEN_READONLY;
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+ }else if( strncmp(z, "-A",2)==0 ){
+ /* All remaining command-line arguments are passed to the ".archive"
+ ** command, so ignore them */
+ break;
+#endif
+ }
+ }
+ verify_uninitialized();
+
+
+#ifdef SQLITE_SHELL_INIT_PROC
+ {
+ /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
+ ** of a C-function that will perform initialization actions on SQLite that
+ ** occur just before or after sqlite3_initialize(). Use this compile-time
+ ** option to embed this shell program in larger applications. */
+ extern void SQLITE_SHELL_INIT_PROC(void);
+ SQLITE_SHELL_INIT_PROC();
+ }
+#else
+ /* All the sqlite3_config() calls have now been made. So it is safe
+ ** to call sqlite3_initialize() and process any command line -vfs option. */
+ sqlite3_initialize();
+#endif
+
+ if( zVfs ){
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
+ if( pVfs ){
+ sqlite3_vfs_register(pVfs, 1);
+ }else{
+ utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
+ exit(1);
+ }
+ }
+
+ if( data.zDbFilename==0 ){
+#ifndef SQLITE_OMIT_MEMORYDB
+ data.zDbFilename = ":memory:";
+ warnInmemoryDb = argc==1;
+#else
+ utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
+ return 1;
+#endif
+ }
+ data.out = stdout;
+ sqlite3_appendvfs_init(0,0,0);
+
+ /* Go ahead and open the database file if it already exists. If the
+ ** file does not exist, delay opening it. This prevents empty database
+ ** files from being created if a user mistypes the database name argument
+ ** to the sqlite command-line tool.
+ */
+ if( access(data.zDbFilename, 0)==0 ){
+ open_db(&data, 0);
+ }
+
+ /* Process the initialization file if there is one. If no -init option
+ ** is given on the command line, look for a file named ~/.sqliterc and
+ ** try to process it.
+ */
+ process_sqliterc(&data,zInitFile);
+
+ /* Make a second pass through the command-line argument and set
+ ** options. This second pass is delayed until after the initialization
+ ** file is processed so that the command-line arguments will override
+ ** settings in the initialization file.
+ */
+ for(i=1; i<argc; i++){
+ char *z = argv[i];
+ if( z[0]!='-' ) continue;
+ if( z[1]=='-' ){ z++; }
+ if( strcmp(z,"-init")==0 ){
+ i++;
+ }else if( strcmp(z,"-html")==0 ){
+ data.mode = MODE_Html;
+ }else if( strcmp(z,"-list")==0 ){
+ data.mode = MODE_List;
+ }else if( strcmp(z,"-quote")==0 ){
+ data.mode = MODE_Quote;
+ }else if( strcmp(z,"-line")==0 ){
+ data.mode = MODE_Line;
+ }else if( strcmp(z,"-column")==0 ){
+ data.mode = MODE_Column;
+ }else if( strcmp(z,"-csv")==0 ){
+ data.mode = MODE_Csv;
+ memcpy(data.colSeparator,",",2);
+#ifdef SQLITE_HAVE_ZLIB
+ }else if( strcmp(z,"-zip")==0 ){
+ data.openMode = SHELL_OPEN_ZIPFILE;
+#endif
+ }else if( strcmp(z,"-append")==0 ){
+ data.openMode = SHELL_OPEN_APPENDVFS;
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ }else if( strcmp(z,"-deserialize")==0 ){
+ data.openMode = SHELL_OPEN_DESERIALIZE;
+#endif
+ }else if( strcmp(z,"-readonly")==0 ){
+ data.openMode = SHELL_OPEN_READONLY;
+ }else if( strcmp(z,"-ascii")==0 ){
+ data.mode = MODE_Ascii;
+ sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
+ SEP_Unit);
+ sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
+ SEP_Record);
+ }else if( strcmp(z,"-separator")==0 ){
+ sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
+ "%s",cmdline_option_value(argc,argv,++i));
+ }else if( strcmp(z,"-newline")==0 ){
+ sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
+ "%s",cmdline_option_value(argc,argv,++i));
+ }else if( strcmp(z,"-nullvalue")==0 ){
+ sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
+ "%s",cmdline_option_value(argc,argv,++i));
+ }else if( strcmp(z,"-header")==0 ){
+ data.showHeader = 1;
+ }else if( strcmp(z,"-noheader")==0 ){
+ data.showHeader = 0;
+ }else if( strcmp(z,"-echo")==0 ){
+ ShellSetFlag(&data, SHFLG_Echo);
+ }else if( strcmp(z,"-eqp")==0 ){
+ data.autoEQP = AUTOEQP_on;
+ }else if( strcmp(z,"-eqpfull")==0 ){
+ data.autoEQP = AUTOEQP_full;
+ }else if( strcmp(z,"-stats")==0 ){
+ data.statsOn = 1;
+ }else if( strcmp(z,"-scanstats")==0 ){
+ data.scanstatsOn = 1;
+ }else if( strcmp(z,"-backslash")==0 ){
+ /* Undocumented command-line option: -backslash
+ ** Causes C-style backslash escapes to be evaluated in SQL statements
+ ** prior to sending the SQL into SQLite. Useful for injecting
+ ** crazy bytes in the middle of SQL statements for testing and debugging.
+ */
+ ShellSetFlag(&data, SHFLG_Backslash);
+ }else if( strcmp(z,"-bail")==0 ){
+ bail_on_error = 1;
+ }else if( strcmp(z,"-version")==0 ){
+ printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
+ return 0;
+ }else if( strcmp(z,"-interactive")==0 ){
+ stdin_is_interactive = 1;
+ }else if( strcmp(z,"-batch")==0 ){
+ stdin_is_interactive = 0;
+ }else if( strcmp(z,"-heap")==0 ){
+ i++;
+ }else if( strcmp(z,"-pagecache")==0 ){
+ i+=2;
+ }else if( strcmp(z,"-lookaside")==0 ){
+ i+=2;
+ }else if( strcmp(z,"-mmap")==0 ){
+ i++;
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ }else if( strcmp(z,"-sorterref")==0 ){
+ i++;
+#endif
+ }else if( strcmp(z,"-vfs")==0 ){
+ i++;
+#ifdef SQLITE_ENABLE_VFSTRACE
+ }else if( strcmp(z,"-vfstrace")==0 ){
+ i++;
+#endif
+#ifdef SQLITE_ENABLE_MULTIPLEX
+ }else if( strcmp(z,"-multiplex")==0 ){
+ i++;
+#endif
+ }else if( strcmp(z,"-help")==0 ){
+ usage(1);
+ }else if( strcmp(z,"-cmd")==0 ){
+ /* Run commands that follow -cmd first and separately from commands
+ ** that simply appear on the command-line. This seems goofy. It would
+ ** be better if all commands ran in the order that they appear. But
+ ** we retain the goofy behavior for historical compatibility. */
+ if( i==argc-1 ) break;
+ z = cmdline_option_value(argc,argv,++i);
+ if( z[0]=='.' ){
+ rc = do_meta_command(z, &data);
+ if( rc && bail_on_error ) return rc==2 ? 0 : rc;
+ }else{
+ open_db(&data, 0);
+ rc = shell_exec(&data, z, &zErrMsg);
+ if( zErrMsg!=0 ){
+ utf8_printf(stderr,"Error: %s\n", zErrMsg);
+ if( bail_on_error ) return rc!=0 ? rc : 1;
+ }else if( rc!=0 ){
+ utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
+ if( bail_on_error ) return rc;
+ }
+ }
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+ }else if( strncmp(z, "-A", 2)==0 ){
+ if( nCmd>0 ){
+ utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
+ " with \"%s\"\n", z);
+ return 1;
+ }
+ open_db(&data, OPEN_DB_ZIPFILE);
+ if( z[2] ){
+ argv[i] = &z[2];
+ arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
+ }else{
+ arDotCommand(&data, 1, argv+i, argc-i);
+ }
+ readStdin = 0;
+ break;
+#endif
+ }else{
+ utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
+ raw_printf(stderr,"Use -help for a list of options.\n");
+ return 1;
+ }
+ data.cMode = data.mode;
+ }
+
+ if( !readStdin ){
+ /* Run all arguments that do not begin with '-' as if they were separate
+ ** command-line inputs, except for the argToSkip argument which contains
+ ** the database filename.
+ */
+ for(i=0; i<nCmd; i++){
+ if( azCmd[i][0]=='.' ){
+ rc = do_meta_command(azCmd[i], &data);
+ if( rc ) return rc==2 ? 0 : rc;
+ }else{
+ open_db(&data, 0);
+ rc = shell_exec(&data, azCmd[i], &zErrMsg);
+ if( zErrMsg!=0 ){
+ utf8_printf(stderr,"Error: %s\n", zErrMsg);
+ return rc!=0 ? rc : 1;
+ }else if( rc!=0 ){
+ utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
+ return rc;
+ }
+ }
+ }
+ free(azCmd);
+ }else{
+ /* Run commands received from standard input
+ */
+ if( stdin_is_interactive ){
+ char *zHome;
+ char *zHistory;
+ int nHistory;
+ printf(
+ "SQLite version %s %.19s\n" /*extra-version-info*/
+ "Enter \".help\" for usage hints.\n",
+ sqlite3_libversion(), sqlite3_sourceid()
+ );
+ if( warnInmemoryDb ){
+ printf("Connected to a ");
+ printBold("transient in-memory database");
+ printf(".\nUse \".open FILENAME\" to reopen on a "
+ "persistent database.\n");
+ }
+ zHistory = getenv("SQLITE_HISTORY");
+ if( zHistory ){
+ zHistory = strdup(zHistory);
+ }else if( (zHome = find_home_dir(0))!=0 ){
+ nHistory = strlen30(zHome) + 20;
+ if( (zHistory = malloc(nHistory))!=0 ){
+ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+ }
+ }
+ if( zHistory ){ shell_read_history(zHistory); }
+#if HAVE_READLINE || HAVE_EDITLINE
+ rl_attempted_completion_function = readline_completion;
+#elif HAVE_LINENOISE
+ linenoiseSetCompletionCallback(linenoise_completion);
+#endif
+ rc = process_input(&data, 0);
+ if( zHistory ){
+ shell_stifle_history(2000);
+ shell_write_history(zHistory);
+ free(zHistory);
+ }
+ }else{
+ rc = process_input(&data, stdin);
+ }
+ }
+ set_table_name(&data, 0);
+ if( data.db ){
+ session_close_all(&data);
+ close_db(data.db);
+ }
+ sqlite3_free(data.zFreeOnClose);
+ find_home_dir(1);
+ output_reset(&data);
+ data.doXdgOpen = 0;
+ clearTempFile(&data);
+#if !SQLITE_SHELL_IS_UTF8
+ for(i=0; i<argcToFree; i++) free(argvToFree[i]);
+ free(argvToFree);
+#endif
+ /* Clear the global data structure so that valgrind will detect memory
+ ** leaks */
+ memset(&data, 0, sizeof(data));
+ return rc;
+}
diff --git a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/spaceanal.tcl b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/spaceanal.tcl
index e8bcb19..dea4448 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/spaceanal.tcl
+++ b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/spaceanal.tcl
@@ -3,10 +3,12 @@
exec tclsh "$0" ${1+"$@"}
package require sqlite3
-# Run this TCL script using "testfixture" in order get a report that shows
-# how much disk space is used by a particular data to actually store data
+# Run this TCL script using an SQLite-enabled TCL interpreter to get a report
+# on how much disk space is used by a particular data to actually store data
# versus how much space is unused.
#
+# The dbstat virtual table is required.
+#
if {[catch {
@@ -152,6 +154,17 @@ if {$flags(-debug)} {
db trace ::dbtrace
}
+# Make sure all required compile-time options are available
+#
+if {![db exists {SELECT 1 FROM pragma_compile_options
+ WHERE compile_options='ENABLE_DBSTAT_VTAB'}]} {
+ puts "The SQLite database engine linked with this application\
+ lacks required capabilities. Recompile using the\
+ -DSQLITE_ENABLE_DBSTAT_VTAB compile-time option to fix\
+ this problem."
+ exit 1
+}
+
db eval {SELECT count(*) FROM sqlite_master}
set pageSize [expr {wide([db one {PRAGMA page_size}])}]
diff --git a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.c b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.c
index 240b71b..a4f8995 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.c
+++ b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.21.0. By combining all the individual C code files into this
+** version 3.25.3. 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
@@ -55,6 +55,12 @@
#define CTIMEOPT_VAL_(opt) #opt
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This
+** option requires a separate macro because legal values contain a single
+** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */
+#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2
+#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt)
+
/*
** An array of names of all compile-time options. This array should
** be sorted A-Z.
@@ -138,7 +144,7 @@ static const char * const sqlite3azCompileOpt[] = {
"DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
#endif
#ifdef SQLITE_DEFAULT_LOOKASIDE
- "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE),
+ "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
#endif
#if SQLITE_DEFAULT_MEMSTATUS
"DEFAULT_MEMSTATUS",
@@ -213,7 +219,7 @@ static const char * const sqlite3azCompileOpt[] = {
"ENABLE_BATCH_ATOMIC_WRITE",
#endif
#if SQLITE_ENABLE_CEROD
- "ENABLE_CEROD",
+ "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
#if SQLITE_ENABLE_COLUMN_METADATA
"ENABLE_COLUMN_METADATA",
@@ -227,6 +233,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_CURSOR_HINTS
"ENABLE_CURSOR_HINTS",
#endif
+#if SQLITE_ENABLE_DBPAGE_VTAB
+ "ENABLE_DBPAGE_VTAB",
+#endif
#if SQLITE_ENABLE_DBSTAT_VTAB
"ENABLE_DBSTAT_VTAB",
#endif
@@ -254,6 +263,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_FTS5
"ENABLE_FTS5",
#endif
+#if SQLITE_ENABLE_GEOPOLY
+ "ENABLE_GEOPOLY",
+#endif
#if SQLITE_ENABLE_HIDDEN_COLUMNS
"ENABLE_HIDDEN_COLUMNS",
#endif
@@ -308,6 +320,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_SNAPSHOT
"ENABLE_SNAPSHOT",
#endif
+#if SQLITE_ENABLE_SORTER_REFERENCES
+ "ENABLE_SORTER_REFERENCES",
+#endif
#if SQLITE_ENABLE_SQLLOG
"ENABLE_SQLLOG",
#endif
@@ -1145,9 +1160,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.21.0"
-#define SQLITE_VERSION_NUMBER 3021000
-#define SQLITE_SOURCE_ID "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827"
+#define SQLITE_VERSION "3.25.3"
+#define SQLITE_VERSION_NUMBER 3025003
+#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1492,6 +1507,9 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
+#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@@ -1524,17 +1542,22 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
+#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
+#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
+#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -1902,7 +1925,8 @@ struct sqlite3_io_methods {
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
-** write ahead log and shared memory files used for transaction control
+** write ahead log ([WAL file]) and shared memory
+** files used for transaction control
** are automatically deleted when the latest connection to the database
** closes. Setting persistent WAL mode causes those files to persist after
** close. Persisting the files is useful when other processes that do not
@@ -2082,6 +2106,32 @@ struct sqlite3_io_methods {
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
+** a file lock using the xLock or xShmLock methods of the VFS to wait
+** for up to M milliseconds before failing, where M is the single
+** unsigned integer parameter.
+**
+** <li>[[SQLITE_FCNTL_DATA_VERSION]]
+** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
+** a database file. The argument is a pointer to a 32-bit unsigned integer.
+** The "data version" for the pager is written into the pointer. The
+** "data version" changes whenever any change occurs to the corresponding
+** database file, either through SQL statements on the same database
+** connection or through transactions committed by separate database
+** connections possibly in other processes. The [sqlite3_total_changes()]
+** interface can be used to find if any database on the connection has changed,
+** but that interface responds to changes on TEMP as well as MAIN and does
+** not provide a mechanism to detect changes to MAIN only. Also, the
+** [sqlite3_total_changes()] interface responds to internal changes only and
+** omits changes made by other database connections. The
+** [PRAGMA data_version] command provide a mechanism to detect changes to
+** a single attached database that occur due to other database connections,
+** but omits changes implemented by the database connection on which it is
+** called. This file control is the only mechanism to detect changes that
+** happen either internally or externally and that are associated with
+** a particular attached database.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -2116,6 +2166,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
+#define SQLITE_FCNTL_LOCK_TIMEOUT 34
+#define SQLITE_FCNTL_DATA_VERSION 35
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -2153,12 +2205,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
+** Note that the structure
+** of the sqlite3_vfs object changes in the transition from
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@@ -2937,6 +2995,22 @@ struct sqlite3_mem_methods {
** I/O required to support statement rollback.
** The default value for this setting is controlled by the
** [SQLITE_STMTJRNL_SPILL] compile-time option.
+**
+** [[SQLITE_CONFIG_SORTERREF_SIZE]]
+** <dt>SQLITE_CONFIG_SORTERREF_SIZE
+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
+** of type (int) - the new value of the sorter-reference size threshold.
+** Usually, when SQLite uses an external sort to order records according
+** to an ORDER BY clause, all fields required by the caller are present in the
+** sorted records. However, if SQLite determines based on the declared type
+** of a table column that its values are likely to be very large - larger
+** than the configured sorter-reference size threshold - then a reference
+** is stored in each sorted record and the required column values loaded
+** from the database as records are returned in sorted order. The default
+** value for this option is to never use this optimization. Specifying a
+** negative value for this option restores the default behaviour.
+** This option is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2966,6 +3040,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
+#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3068,8 +3143,9 @@ struct sqlite3_mem_methods {
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
** override this behaviour. The first parameter passed to this operation
-** is an integer - non-zero to disable checkpoints-on-close, or zero (the
-** default) to enable them. The second parameter is a pointer to an integer
+** is an integer - positive to disable checkpoints-on-close, or zero (the
+** default) to enable them, and 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 checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
** </dd>
@@ -3083,8 +3159,45 @@ struct sqlite3_mem_methods {
** slower. But the QPSG has the advantage of more predictable behavior. With
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
+** The first argument to this setting is an integer which is 0 to disable
+** the QPSG, positive to enable QPSG, 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 the QPSG is disabled or enabled
+** following this call.
** </dd>
**
+** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
+** positive to enable output for trigger programs, or zero to disable it,
+** 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 output-for-triggers has been disabled - 0 if
+** it is not disabled, 1 if it is.
+** </dd>
+**
+** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
+** [VACUUM] in order to reset a database back to an empty database
+** with no schema and no content. The following process works even for
+** a badly corrupted database file:
+** <ol>
+** <li> If the database connection is newly opened, make sure it has read the
+** database schema by preparing then discarding some query against the
+** database, or calling sqlite3_table_column_metadata(), ignoring any
+** errors. This step is only necessary if the application desires to keep
+** the database in WAL mode after the reset if it was in WAL mode before
+** the reset.
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
+** </ol>
+** Because resetting a database is destructive and irreversible, the
+** process requires the use of this obscure API and multiple steps to help
+** ensure that it does not happen by accident.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -3095,7 +3208,9 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -3223,12 +3338,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** program, the value returned reflects the number of rows modified by the
** previous INSERT, UPDATE or DELETE statement within the same trigger.
**
-** See also the [sqlite3_total_changes()] interface, the
-** [count_changes pragma], and the [changes() SQL function].
-**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_total_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** </ul>
*/
SQLITE_API sqlite3_uint64 sqlite3_changes(sqlite3*);
#define sqlite3_changes(db) ((int)(sqlite3_changes)(db))
@@ -3248,13 +3368,26 @@ SQLITE_API sqlite3_uint64 sqlite3_changes(sqlite3*);
** count, but those made as part of REPLACE constraint resolution are
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
** are not counted.
-**
-** See also the [sqlite3_changes()] interface, the
-** [count_changes pragma], and the [total_changes() SQL function].
**
+** This the [sqlite3_total_changes(D)] interface only reports the number
+** of rows that changed due to SQL statement run against database
+** connection D. Any changes by other database connections are ignored.
+** To detect changes against a database file from other database
+** connections use the [PRAGMA data_version] command or the
+** [SQLITE_FCNTL_DATA_VERSION] [file control].
+**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
+** </ul>
*/
SQLITE_API sqlite3_uint64 sqlite3_total_changes(sqlite3*);
#define sqlite3_total_changes(db) ((int)(sqlite3_total_changes)(db))
@@ -3505,16 +3638,16 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
-** These routines understand most of the common K&R formatting options,
-** plus some additional non-standard formats, detailed below.
-** Note that some of the more obscure formatting options from recent
-** C-library standards are omitted from this implementation.
+** These routines understand most of the common formatting options from
+** the standard library printf()
+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
+** See the [built-in printf()] documentation for details.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
+** results into memory obtained from [sqlite3_malloc64()].
** The strings returned by these two routines should be
** released by [sqlite3_free()]. ^Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
@@ -3538,71 +3671,7 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** All of the usual printf() formatting options apply. In addition, there
-** is are "%q", "%Q", "%w" and "%z" options.
-**
-** ^(The %q option works like %s in that it substitutes a nul-terminated
-** string from the argument list. But %q also doubles every '\'' character.
-** %q is designed for use inside a string literal.)^ By doubling each '\''
-** character it escapes that character and allows it to be inserted into
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** ^(The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes).)^ So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** ^(The "%w" formatting option is like "%q" except that it expects to
-** be contained within double-quotes instead of single quotes, and it
-** escapes the double-quote character instead of the single-quote
-** character.)^ The "%w" formatting option is intended for safely inserting
-** table and column names into a constructed SQL statement.
-**
-** ^(The "%z" formatting option works like "%s" but with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string.)^
+** See also: [built-in printf()], [printf() SQL function]
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
@@ -3960,8 +4029,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The third argument
-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@@ -4376,13 +4445,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
** [database connection] D failed, then the sqlite3_errcode(D) interface
** returns the numeric [result code] or [extended result code] for that
** API call.
-** If the most recent API call was successful,
-** then the return value from sqlite3_errcode() is undefined.
** ^The sqlite3_extended_errcode()
** interface is the same except that it always returns the
** [extended result code] even when extended result codes are
** disabled.
**
+** The values returned by sqlite3_errcode() and/or
+** sqlite3_extended_errcode() might change with each API call.
+** Except, there are some interfaces that are guaranteed to never
+** change the value of the error code. The error-code preserving
+** interfaces are:
+**
+** <ul>
+** <li> sqlite3_errcode()
+** <li> sqlite3_extended_errcode()
+** <li> sqlite3_errmsg()
+** <li> sqlite3_errmsg16()
+** </ul>
+**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** ^(Memory to hold the error message string is managed internally.
@@ -4668,13 +4748,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** </li>
+** </ol>
**
** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
** the extra prepFlags parameter, which is a bit array consisting of zero or
** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
** sqlite3_prepare_v2() interface works exactly the same as
** sqlite3_prepare_v3() with a zero prepFlags parameter.
-** </ol>
*/
SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
@@ -5536,11 +5616,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
-** ^(If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].)^
+** As long as the input parameters are correct, these routines will only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_column_blob()
+** <li> sqlite3_column_text()
+** <li> sqlite3_column_text16()
+** <li> sqlite3_column_bytes()
+** <li> sqlite3_column_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
*/
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
@@ -5617,11 +5711,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only differences between
-** these routines are the text encoding expected for
-** the second parameter (the name of the function being created)
-** and the presence or absence of a destructor callback for
-** the application data pointer.
+** of existing SQL functions or aggregates. The only differences between
+** the three "sqlite3_create_function*" routines are the text encoding
+** expected for the second parameter (the name of the function being
+** created) and the presence or absence of a destructor callback for
+** the application data pointer. Function sqlite3_create_window_function()
+** is similar, but allows the user to supply the extra callback functions
+** needed by [aggregate window functions].
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added. ^If an application uses more than one database
@@ -5667,7 +5763,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
**
-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
+** ^The sixth, seventh and eighth parameters passed to the three
+** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
@@ -5676,15 +5773,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** SQL function or aggregate, pass NULL pointers for all three function
** callbacks.
**
-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
-** then it is destructor for the application data pointer.
-** The destructor is invoked when the function is deleted, either by being
-** overloaded or when the database connection closes.)^
-** ^The destructor is also invoked if the call to
-** sqlite3_create_function_v2() fails.
-** ^When the destructor callback of the tenth parameter is invoked, it
-** is passed a single argument which is a copy of the application data
-** pointer which was the fifth parameter to sqlite3_create_function_v2().
+** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue
+** and xInverse) passed to sqlite3_create_window_function are pointers to
+** C-language callbacks that implement the new function. xStep and xFinal
+** must both be non-NULL. xValue and xInverse may either both be NULL, in
+** which case a regular aggregate function is created, or must both be
+** non-NULL, in which case the new function may be used as either an aggregate
+** or aggregate window function. More details regarding the implementation
+** of aggregate window functions are
+** [user-defined window functions|available here].
+**
+** ^(If the final parameter to sqlite3_create_function_v2() or
+** sqlite3_create_window_function() is not NULL, then it is destructor for
+** the application data pointer. The destructor is invoked when the function
+** is deleted, either by being overloaded or when the database connection
+** closes.)^ ^The destructor is also invoked if the call to
+** sqlite3_create_function_v2() fails. ^When the destructor callback is
+** invoked, it is passed a single argument which is a copy of the application
+** data pointer which was the fifth parameter to sqlite3_create_function_v2().
**
** ^It is permitted to register multiple implementations of the same
** functions with the same name but with either differing numbers of
@@ -5737,6 +5843,18 @@ SQLITE_API int sqlite3_create_function_v2(
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*)
);
+SQLITE_API int sqlite3_create_window_function(
+ sqlite3 *db,
+ const char *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void *pApp,
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
+ void(*xDestroy)(void*)
+);
/*
** CAPI3REF: Text Encodings
@@ -5807,6 +5925,9 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@@ -5855,6 +5976,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -5863,6 +5997,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
+**
+** As long as the input parameter is correct, these routines can only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_value_blob()
+** <li> sqlite3_value_text()
+** <li> sqlite3_value_text16()
+** <li> sqlite3_value_text16le()
+** <li> sqlite3_value_text16be()
+** <li> sqlite3_value_bytes()
+** <li> sqlite3_value_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API double sqlite3_value_double(sqlite3_value*);
@@ -5877,6 +6033,7 @@ SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -6546,6 +6703,41 @@ char *sqlite3_temp_directory;
char *sqlite3_data_directory;
/*
+** CAPI3REF: Win32 Specific Interface
+**
+** These interfaces are available only on Windows. The
+** [sqlite3_win32_set_directory] interface is used to set the value associated
+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
+** zValue, depending on the value of the type parameter. The zValue parameter
+** should be NULL to cause the previous value to be freed via [sqlite3_free];
+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
+** prior to being used. The [sqlite3_win32_set_directory] interface returns
+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
+** or [SQLITE_NOMEM] if memory could not be allocated. The value of the
+** [sqlite3_data_directory] variable is intended to act as a replacement for
+** the current directory on the sub-platforms of Win32 where that concept is
+** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and
+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
+** sqlite3_win32_set_directory interface except the string parameter must be
+** UTF-8 or UTF-16, respectively.
+*/
+SQLITE_API int sqlite3_win32_set_directory(
+ unsigned long type, /* Identifier for directory being set or reset */
+ void *zValue /* New value for directory being set or reset */
+);
+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
+
+/*
+** CAPI3REF: Win32 Directory Types
+**
+** These macros are only available on Windows. They define the allowed values
+** for the type argument to the [sqlite3_win32_set_directory] interface.
+*/
+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1
+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2
+
+/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
** METHOD: sqlite3
@@ -7278,6 +7470,10 @@ struct sqlite3_index_info {
/*
** CAPI3REF: Virtual Table Scan Flags
+**
+** Virtual table implementations are allowed to set the
+** [sqlite3_index_info].idxFlags field to some combination of
+** these bits.
*/
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
@@ -7303,6 +7499,7 @@ struct sqlite3_index_info {
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
#define SQLITE_INDEX_CONSTRAINT_IS 72
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -7979,6 +8176,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
** METHOD: sqlite3
+** KEYWORDS: {file control}
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
@@ -7993,11 +8191,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** the xFileControl method. ^The return value of the xFileControl
** method becomes the return value of this routine.
**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
+** A few opcodes for [sqlite3_file_control()] are handled directly
+** by the SQLite core and never invoke the
+** sqlite3_io_methods.xFileControl method.
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
-** case is a short-circuit path which does not actually invoke the
-** underlying sqlite3_io_methods.xFileControl method.
+** the space pointed to by the 4th parameter. The
+** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
+** the [sqlite3_file] object associated with the journal file instead of
+** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns
+** a pointer to the underlying [sqlite3_vfs] object for the file.
+** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
+** from the pager.
**
** ^If the second parameter (zDbName) does not match the name of any
** open database file, then SQLITE_ERROR is returned. ^This error
@@ -8007,7 +8212,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
+** See also: [file control opcodes]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
@@ -8053,7 +8258,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
-#define SQLITE_TESTCTRL_ISKEYWORD 16
+#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
@@ -8064,7 +8269,191 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_LAST 25
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
+
+/*
+** CAPI3REF: SQL Keyword Checking
+**
+** These routines provide access to the set of SQL language keywords
+** recognized by SQLite. Applications can uses these routines to determine
+** whether or not a specific identifier needs to be escaped (for example,
+** by enclosing in double-quotes) so as not to confuse the parser.
+**
+** The sqlite3_keyword_count() interface returns the number of distinct
+** keywords understood by SQLite.
+**
+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** makes *Z point to that keyword expressed as UTF8 and writes the number
+** of bytes in the keyword into *L. The string that *Z points to is not
+** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
+** or L are NULL or invalid pointers then calls to
+** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
+**
+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
+** if it is and zero if not.
+**
+** The parser used by SQLite is forgiving. It is often possible to use
+** a keyword as an identifier as long as such use does not result in a
+** parsing ambiguity. For example, the statement
+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
+** creates a new table named "BEGIN" with three columns named
+** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid
+** using keywords as identifiers. Common techniques used to avoid keyword
+** name collisions include:
+** <ul>
+** <li> Put all identifier names inside double-quotes. This is the official
+** SQL way to escape identifier names.
+** <li> Put identifier names inside &#91;...&#93;. This is not standard SQL,
+** but it is what SQL Server does and so lots of programmers use this
+** technique.
+** <li> Begin every identifier with the letter "Z" as no SQL keywords start
+** with "Z".
+** <li> Include a digit somewhere in every identifier name.
+** </ul>
+**
+** Note that the number of keywords understood by SQLite can depend on
+** compile-time options. For example, "VACUUM" is not a keyword if
+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also,
+** new keywords may be added to future releases of SQLite.
+*/
+SQLITE_API int sqlite3_keyword_count(void);
+SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
+SQLITE_API int sqlite3_keyword_check(const char*,int);
+
+/*
+** CAPI3REF: Dynamic String Object
+** KEYWORDS: {dynamic string}
+**
+** An instance of the sqlite3_str object contains a dynamically-sized
+** string under construction.
+**
+** The lifecycle of an sqlite3_str object is as follows:
+** <ol>
+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
+** <li> ^Text is appended to the sqlite3_str object using various
+** methods, such as [sqlite3_str_appendf()].
+** <li> ^The sqlite3_str object is destroyed and the string it created
+** is returned using the [sqlite3_str_finish()] interface.
+** </ol>
+*/
+typedef struct sqlite3_str sqlite3_str;
+
+/*
+** CAPI3REF: Create A New Dynamic String Object
+** CONSTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_new(D)] interface allocates and initializes
+** a new [sqlite3_str] object. To avoid memory leaks, the object returned by
+** [sqlite3_str_new()] must be freed by a subsequent call to
+** [sqlite3_str_finish(X)].
+**
+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
+** valid [sqlite3_str] object, though in the event of an out-of-memory
+** error the returned object might be a special singleton that will
+** silently reject new text, always return SQLITE_NOMEM from
+** [sqlite3_str_errcode()], always return 0 for
+** [sqlite3_str_length()], and always return NULL from
+** [sqlite3_str_finish(X)]. It is always safe to use the value
+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
+** to any of the other [sqlite3_str] methods.
+**
+** The D parameter to [sqlite3_str_new(D)] may be NULL. If the
+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
+** length of the string contained in the [sqlite3_str] object will be
+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
+** of [SQLITE_MAX_LENGTH].
+*/
+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
+
+/*
+** CAPI3REF: Finalize A Dynamic String
+** DESTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
+** that contains the constructed string. The calling application should
+** pass the returned value to [sqlite3_free()] to avoid a memory leak.
+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
+** errors were encountered during construction of the string. ^The
+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
+** string in [sqlite3_str] object X is zero bytes long.
+*/
+SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
+
+/*
+** CAPI3REF: Add Content To A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces add content to an sqlite3_str object previously obtained
+** from [sqlite3_str_new()].
+**
+** ^The [sqlite3_str_appendf(X,F,...)] and
+** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
+** functionality of SQLite to append formatted text onto the end of
+** [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
+** onto the end of the [sqlite3_str] object X. N must be non-negative.
+** S must contain at least N non-zero bytes of content. To append a
+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
+** method instead.
+**
+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
+** zero-terminated string S onto the end of [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
+** single-byte character C onto the end of [sqlite3_str] object X.
+** ^This method can be used, for example, to add whitespace indentation.
+**
+** ^The [sqlite3_str_reset(X)] method resets the string under construction
+** inside [sqlite3_str] object X back to zero bytes in length.
+**
+** These methods do not return a result code. ^If an error occurs, that fact
+** is recorded in the [sqlite3_str] object and can be recovered by a
+** subsequent call to [sqlite3_str_errcode(X)].
+*/
+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
+SQLITE_API void sqlite3_str_reset(sqlite3_str*);
+
+/*
+** CAPI3REF: Status Of A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces return the current status of an [sqlite3_str] object.
+**
+** ^If any prior errors have occurred while constructing the dynamic string
+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
+** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns
+** [SQLITE_NOMEM] following any out-of-memory error, or
+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
+**
+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
+** of the dynamic string under construction in [sqlite3_str] object X.
+** ^The length returned by [sqlite3_str_length(X)] does not include the
+** zero-termination byte.
+**
+** ^The [sqlite3_str_value(X)] method returns a pointer to the current
+** content of the dynamic string under construction in X. The value
+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
+** and might be freed or altered by any subsequent method on the same
+** [sqlite3_str] object. Applications must not used the pointer returned
+** [sqlite3_str_value(X)] after any subsequent method call on the same
+** object. ^Applications may change the content of the string returned
+** by [sqlite3_str_value(X)] as long as they do not write into any bytes
+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
+** write any byte after any subsequent sqlite3_str method call.
+*/
+SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
+SQLITE_API int sqlite3_str_length(sqlite3_str*);
+SQLITE_API char *sqlite3_str_value(sqlite3_str*);
/*
** CAPI3REF: SQLite Runtime Status
@@ -8299,6 +8688,15 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
+** <dd>This parameter returns the number of dirty cache entries that have
+** been written to disk in the middle of a transaction due to the page
+** cache overflowing. Transactions are more efficient if they are written
+** to disk all at once. When pages spill mid-transaction, that introduces
+** additional overhead. This parameter can be used help identify
+** inefficiencies that can be resolve by increasing the cache size.
+** </dd>
+**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
@@ -8318,7 +8716,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
-#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_CACHE_SPILL 12
+#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
/*
@@ -9319,6 +9718,40 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** method of a [virtual table], then it returns true if and only if the
+** column is being fetched as part of an UPDATE operation during which the
+** column value will not change. Applications might use this to substitute
+** a return value that is less expensive to compute and that the corresponding
+** [xUpdate] method understands as a "no-change" value.
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+** the column is not changed by the UPDATE statement, then the xColumn
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
+** method of a [virtual table].
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
+** structure passed to xBestIndex. This function returns a pointer to a buffer
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -9588,7 +10021,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
/*
** CAPI3REF: Database Snapshot
** KEYWORDS: {snapshot} {sqlite3_snapshot}
-** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
** database for some specific point in history.
@@ -9605,11 +10037,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
** version of the database file so that it is possible to later open a new read
** transaction that sees that historical version of the database rather than
** the most recent version.
-**
-** The constructor for this object is [sqlite3_snapshot_get()]. The
-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
-** to an historical snapshot (if possible). The destructor for
-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
typedef struct sqlite3_snapshot {
unsigned char hidden[48];
@@ -9617,7 +10044,7 @@ typedef struct sqlite3_snapshot {
/*
** CAPI3REF: Record A Database Snapshot
-** EXPERIMENTAL
+** CONSTRUCTOR: sqlite3_snapshot
**
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
** new [sqlite3_snapshot] object that records the current state of
@@ -9633,7 +10060,7 @@ typedef struct sqlite3_snapshot {
** in this case.
**
** <ul>
-** <li> The database handle must be in [autocommit mode].
+** <li> The database handle must not be in [autocommit mode].
**
** <li> Schema S of [database connection] D must be a [WAL mode] database.
**
@@ -9656,7 +10083,7 @@ typedef struct sqlite3_snapshot {
** to avoid a memory leak.
**
** The [sqlite3_snapshot_get()] interface is only available when the
-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
sqlite3 *db,
@@ -9666,24 +10093,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
/*
** CAPI3REF: Start a read transaction on an historical snapshot
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
+**
+** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
+** transaction or upgrades an existing one 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, the database connection must not be in
+** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
+** is already a read transaction open on schema S, then the database handle
+** must have no active statements (SELECT statements that have been passed
+** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()).
+** SQLITE_ERROR is returned if either of these conditions is violated, or
+** if schema S does not exist, or if the snapshot object is invalid.
+**
+** ^A call to sqlite3_snapshot_open() will fail to open if the specified
+** snapshot has been overwritten by a [checkpoint]. In this case
+** SQLITE_ERROR_SNAPSHOT is returned.
+**
+** If there is already a read transaction open when this function is
+** invoked, then the same read transaction remains open (on the same
+** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
+** is returned. If another error code - for example SQLITE_PROTOCOL or an
+** SQLITE_IOERR error code - is returned, then the final state of the
+** read transaction is undefined. If SQLITE_OK is returned, then the
+** read transaction is now open on database 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 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
@@ -9694,7 +10132,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** 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.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
sqlite3 *db,
@@ -9704,20 +10142,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
/*
** CAPI3REF: Destroy a snapshot
-** EXPERIMENTAL
+** DESTRUCTOR: sqlite3_snapshot
**
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
** The application must eventually free every [sqlite3_snapshot] object
** using this routine to avoid a memory leak.
**
** The [sqlite3_snapshot_free()] interface is only available when the
-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** CAPI3REF: Compare the ages of two snapshot handles.
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
**
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
** of two valid snapshot handles.
@@ -9736,6 +10174,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
** 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.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
sqlite3_snapshot *p1,
@@ -9744,27 +10185,152 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
/*
** CAPI3REF: Recover snapshots from a wal file
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
**
-** If all connections disconnect from a database file but do not perform
-** a checkpoint, the existing wal file is opened along with the database
-** file the next time the database is opened. At this point it is only
-** possible to successfully call sqlite3_snapshot_open() to open the most
-** recent snapshot of the database (the one at the head of the wal file),
-** even though the wal file may contain other valid snapshots for which
-** clients have sqlite3_snapshot handles.
+** If a [WAL file] remains on disk after all database connections close
+** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
+** or because the last process to have the database opened exited without
+** calling [sqlite3_close()]) and a new connection is subsequently opened
+** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
+** will only be able to open the last transaction added to the WAL file
+** even though the WAL file contains other valid transactions.
**
-** This function attempts to scan the wal file associated with database zDb
+** This function attempts to scan the WAL file associated with database zDb
** of database handle db and make all valid snapshots available to
** sqlite3_snapshot_open(). It is an error if there is already a read
-** transaction open on the database, or if the database is not a wal mode
+** transaction open on the database, or if the database is not a WAL mode
** database.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
/*
+** CAPI3REF: Serialize a database
+**
+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
+** that is a serialization of the S database on [database connection] D.
+** If P is not a NULL pointer, then the size of the database in bytes
+** is written into *P.
+**
+** For an ordinary on-disk database file, the serialization is just a
+** copy of the disk file. For an in-memory database or a "TEMP" database,
+** the serialization is the same sequence of bytes which would be written
+** to disk if that database where backed up to disk.
+**
+** The usual case is that sqlite3_serialize() copies the serialization of
+** the database into memory obtained from [sqlite3_malloc64()] and returns
+** a pointer to that memory. The caller is responsible for freeing the
+** returned value to avoid a memory leak. However, if the F argument
+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
+** are made, and the sqlite3_serialize() function will return a pointer
+** to the contiguous memory representation of the database that SQLite
+** is currently using for that database, or NULL if the no such contiguous
+** memory representation of the database exists. A contiguous memory
+** representation of the database will usually only exist if there has
+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+** values of D and S.
+** The size of the database is written into *P even if the
+** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+** of the database exists.
+**
+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
+** allocation error occurs.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API unsigned char *sqlite3_serialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
+ sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
+ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_serialize
+**
+** Zero or more of the following constants can be OR-ed together for
+** the F argument to [sqlite3_serialize(D,S,P,F)].
+**
+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
+** a pointer to contiguous in-memory database that it is currently using,
+** without making a copy of the database. If SQLite is not currently using
+** a contiguous in-memory database, then this option causes
+** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be
+** using a contiguous in-memory database if it has been initialized by a
+** prior call to [sqlite3_deserialize()].
+*/
+#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
+
+/*
+** CAPI3REF: Deserialize a database
+**
+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
+** [database connection] D to disconnect from database S and then
+** reopen S as an in-memory database based on the serialization contained
+** in P. The serialized database P is N bytes in size. M is the size of
+** the buffer P, which might be larger than N. If M is larger than N, and
+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
+** permitted to add content to the in-memory database as long as the total
+** size does not exceed M bytes.
+**
+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
+** invoke sqlite3_free() on the serialization buffer when the database
+** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
+** SQLite will try to increase the buffer size using sqlite3_realloc64()
+** if writes on the database cause it to grow larger than M bytes.
+**
+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
+** database is currently in a read transaction or is involved in a backup
+** operation.
+**
+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
+** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
+** [sqlite3_free()] is invoked on argument P prior to returning.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API int sqlite3_deserialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to reopen with the deserialization */
+ unsigned char *pData, /* The serialized database content */
+ sqlite3_int64 szDb, /* Number bytes in the deserialization */
+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */
+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_deserialize()
+**
+** The following are allowed values for 6th argument (the F argument) to
+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
+**
+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
+** in the P argument is held in memory obtained from [sqlite3_malloc64()]
+** and that SQLite should take ownership of this memory and automatically
+** free it when it has finished using it. Without this flag, the caller
+** is responsible for freeing any dynamically allocated memory.
+**
+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
+** grow the size of the database using calls to [sqlite3_realloc64()]. This
+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
+** Without this flag, the deserialized database cannot increase in size beyond
+** the number of bytes specified by the M parameter.
+**
+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
+** should be treated as read-only.
+*/
+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
+#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
+#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
+
+/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
@@ -9911,16 +10477,23 @@ extern "C" {
/*
** CAPI3REF: Session Object Handle
+**
+** An instance of this object is a [session] that can be used to
+** record changes to a database.
*/
typedef struct sqlite3_session sqlite3_session;
/*
** CAPI3REF: Changeset Iterator Handle
+**
+** An instance of this object acts as a cursor for iterating
+** over the elements of a [changeset] or [patchset].
*/
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
/*
** CAPI3REF: Create A New Session Object
+** CONSTRUCTOR: sqlite3_session
**
** 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
@@ -9957,6 +10530,7 @@ SQLITE_API int sqlite3session_create(
/*
** CAPI3REF: Delete A Session Object
+** DESTRUCTOR: sqlite3_session
**
** Delete a session object previously allocated using
** [sqlite3session_create()]. Once a session object has been deleted, the
@@ -9972,6 +10546,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
/*
** CAPI3REF: Enable Or Disable A Session Object
+** METHOD: sqlite3_session
**
** Enable or disable the recording of changes by a session object. When
** enabled, a session object records changes made to the database. When
@@ -9991,6 +10566,7 @@ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
+** METHOD: sqlite3_session
**
** Each change recorded by a session object is marked as either direct or
** indirect. A change is marked as indirect if either:
@@ -10020,6 +10596,7 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
/*
** CAPI3REF: Attach A Table To A Session Object
+** METHOD: sqlite3_session
**
** 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
@@ -10045,6 +10622,35 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
**
** 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.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
+** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
+** </pre>
+**
+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
+** The sqlite3changeset_apply() function automatically converts the
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
*/
SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@@ -10053,6 +10659,7 @@ SQLITE_API int sqlite3session_attach(
/*
** CAPI3REF: Set a table filter on a Session Object.
+** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
@@ -10071,6 +10678,7 @@ SQLITE_API void sqlite3session_table_filter(
/*
** CAPI3REF: Generate A Changeset From A Session Object
+** METHOD: sqlite3_session
**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
@@ -10180,7 +10788,8 @@ SQLITE_API int sqlite3session_changeset(
);
/*
-** CAPI3REF: Load The Difference Between Tables Into A Session
+** CAPI3REF: Load The Difference Between Tables Into A Session
+** METHOD: sqlite3_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
@@ -10245,6 +10854,7 @@ SQLITE_API int sqlite3session_diff(
/*
** CAPI3REF: Generate A Patchset From A Session Object
+** METHOD: sqlite3_session
**
** The differences between a patchset and a changeset are that:
**
@@ -10296,6 +10906,7 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
+** CONSTRUCTOR: sqlite3_changeset_iter
**
** 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
@@ -10336,6 +10947,7 @@ SQLITE_API int sqlite3changeset_start(
/*
** CAPI3REF: Advance A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
@@ -10360,6 +10972,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -10394,6 +11007,7 @@ SQLITE_API int sqlite3changeset_op(
/*
** CAPI3REF: Obtain The Primary Key Definition Of A Table
+** METHOD: sqlite3_changeset_iter
**
** For each modified table, a changeset includes the following:
**
@@ -10425,6 +11039,7 @@ SQLITE_API int sqlite3changeset_pk(
/*
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -10455,6 +11070,7 @@ SQLITE_API int sqlite3changeset_old(
/*
** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -10488,6 +11104,7 @@ SQLITE_API int sqlite3changeset_new(
/*
** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function should only be used with iterator objects passed to a
** conflict-handler callback by [sqlite3changeset_apply()] with either
@@ -10515,6 +11132,7 @@ SQLITE_API int sqlite3changeset_conflict(
/*
** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+** METHOD: sqlite3_changeset_iter
**
** This function may only be called with an iterator passed to an
** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
@@ -10531,6 +11149,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
/*
** CAPI3REF: Finalize A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function is used to finalize an iterator allocated with
** [sqlite3changeset_start()].
@@ -10547,6 +11166,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** to that error is returned by this function. Otherwise, SQLITE_OK is
** returned. This is to allow the following pattern (pseudo-code):
**
+** <pre>
** sqlite3changeset_start();
** while( SQLITE_ROW==sqlite3changeset_next() ){
** // Do something with change.
@@ -10555,6 +11175,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** if( rc!=SQLITE_OK ){
** // An error has occurred
** }
+** </pre>
*/
SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
@@ -10602,6 +11223,7 @@ SQLITE_API int sqlite3changeset_invert(
** sqlite3_changegroup object. Calling it produces similar results as the
** following code fragment:
**
+** <pre>
** sqlite3_changegroup *pGrp;
** rc = sqlite3_changegroup_new(&pGrp);
** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
@@ -10612,6 +11234,7 @@ SQLITE_API int sqlite3changeset_invert(
** *ppOut = 0;
** *pnOut = 0;
** }
+** </pre>
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
@@ -10627,11 +11250,15 @@ SQLITE_API int sqlite3changeset_concat(
/*
** CAPI3REF: Changegroup Handle
+**
+** A changegroup is an object used to combine two or more
+** [changesets] or [patchsets]
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
** CAPI3REF: Create A New Changegroup Object
+** CONSTRUCTOR: sqlite3_changegroup
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@@ -10669,6 +11296,7 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
+** METHOD: sqlite3_changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
@@ -10746,6 +11374,7 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pDa
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+** METHOD: sqlite3_changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
@@ -10776,25 +11405,25 @@ SQLITE_API int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
+** DESTRUCTOR: sqlite3_changegroup
*/
SQLITE_API 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.
+** Apply a changeset or patchset to a database. These functions attempt 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
+** The fourth argument (xFilter) passed to these functions 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.
+** passed as the sixth argument 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
+** 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
@@ -10839,7 +11468,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dl>
** <dt>DELETE Changes<dd>
-** For each DELETE change, this function checks if the target database
+** For each DELETE change, the 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
@@ -10884,7 +11513,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** [SQLITE_CHANGESET_REPLACE].
**
** <dt>UPDATE Changes<dd>
-** For each UPDATE change, this function checks if the target database
+** For each UPDATE change, the 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 modified non-primary key columns also match the values
@@ -10915,11 +11544,28 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** This can be used to further customize the applications conflict
** resolution strategy.
**
-** All changes made by this function are enclosed in a savepoint transaction.
+** All changes made by these functions 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.
+**
+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
+** may set (*ppRebase) to point to a "rebase" that may be used with the
+** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
+** is set to the size of the buffer in bytes. It is the responsibility of the
+** caller to eventually free any such buffer using sqlite3_free(). The buffer
+** is only allocated and populated if one or more conflicts were encountered
+** while applying the patchset. See comments surrounding the sqlite3_rebaser
+** APIs for further details.
+**
+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
+**
+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
+** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
@@ -10936,6 +11582,41 @@ SQLITE_API int sqlite3changeset_apply(
),
void *pCtx /* First argument passed to xConflict */
);
+SQLITE_API int sqlite3changeset_apply_v2(
+ 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 */
+ void **ppRebase, int *pnRebase, /* OUT: Rebase data */
+ int flags /* Combination of SESSION_APPLY_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_apply_v2
+**
+** The following flags may passed via the 9th parameter to
+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
+**
+** <dl>
+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
+** Usually, the sessions module encloses all operations performed by
+** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
+** SAVEPOINT is committed if the changeset or patchset is successfully
+** applied, or rolled back if an error occurs. Specifying this flag
+** causes the sessions module to omit this savepoint. In this case, if the
+** caller has an open transaction or savepoint when apply_v2() is called,
+** it may revert the partially applied changeset by rolling it back.
+*/
+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -11033,6 +11714,161 @@ SQLITE_API int sqlite3changeset_apply(
#define SQLITE_CHANGESET_REPLACE 1
#define SQLITE_CHANGESET_ABORT 2
+/*
+** CAPI3REF: Rebasing changesets
+** EXPERIMENTAL
+**
+** Suppose there is a site hosting a database in state S0. And that
+** modifications are made that move that database to state S1 and a
+** changeset recorded (the "local" changeset). Then, a changeset based
+** on S0 is received from another site (the "remote" changeset) and
+** applied to the database. The database is then in state
+** (S1+"remote"), where the exact state depends on any conflict
+** resolution decisions (OMIT or REPLACE) made while applying "remote".
+** Rebasing a changeset is to update it to take those conflict
+** resolution decisions into account, so that the same conflicts
+** do not have to be resolved elsewhere in the network.
+**
+** For example, if both the local and remote changesets contain an
+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
+**
+** local: INSERT INTO t1 VALUES(1, 'v1');
+** remote: INSERT INTO t1 VALUES(1, 'v2');
+**
+** and the conflict resolution is REPLACE, then the INSERT change is
+** removed from the local changeset (it was overridden). Or, if the
+** conflict resolution was "OMIT", then the local changeset is modified
+** to instead contain:
+**
+** UPDATE t1 SET b = 'v2' WHERE a=1;
+**
+** Changes within the local changeset are rebased as follows:
+**
+** <dl>
+** <dt>Local INSERT<dd>
+** This may only conflict with a remote INSERT. If the conflict
+** resolution was OMIT, then add an UPDATE change to the rebased
+** changeset. Or, if the conflict resolution was REPLACE, add
+** nothing to the rebased changeset.
+**
+** <dt>Local DELETE<dd>
+** This may conflict with a remote UPDATE or DELETE. In both cases the
+** only possible resolution is OMIT. If the remote operation was a
+** DELETE, then add no change to the rebased changeset. If the remote
+** operation was an UPDATE, then the old.* fields of change are updated
+** to reflect the new.* values in the UPDATE.
+**
+** <dt>Local UPDATE<dd>
+** This may conflict with a remote UPDATE or DELETE. If it conflicts
+** with a DELETE, and the conflict resolution was OMIT, then the update
+** is changed into an INSERT. Any undefined values in the new.* record
+** from the update change are filled in using the old.* values from
+** the conflicting DELETE. Or, if the conflict resolution was REPLACE,
+** the UPDATE change is simply omitted from the rebased changeset.
+**
+** If conflict is with a remote UPDATE and the resolution is OMIT, then
+** the old.* values are rebased using the new.* values in the remote
+** change. Or, if the resolution is REPLACE, then the change is copied
+** into the rebased changeset with updates to columns also updated by
+** the conflicting remote UPDATE removed. If this means no columns would
+** be updated, the change is omitted.
+** </dl>
+**
+** A local change may be rebased against multiple remote changes
+** simultaneously. If a single key is modified by multiple remote
+** changesets, they are combined as follows before the local changeset
+** is rebased:
+**
+** <ul>
+** <li> If there has been one or more REPLACE resolutions on a
+** key, it is rebased according to a REPLACE.
+**
+** <li> If there have been no REPLACE resolutions on a key, then
+** the local changeset is rebased according to the most recent
+** of the OMIT resolutions.
+** </ul>
+**
+** Note that conflict resolutions from multiple remote changesets are
+** combined on a per-field basis, not per-row. This means that in the
+** case of multiple remote UPDATE operations, some fields of a single
+** local change may be rebased for REPLACE while others are rebased for
+** OMIT.
+**
+** In order to rebase a local changeset, the remote changeset must first
+** be applied to the local database using sqlite3changeset_apply_v2() and
+** the buffer of rebase information captured. Then:
+**
+** <ol>
+** <li> An sqlite3_rebaser object is created by calling
+** sqlite3rebaser_create().
+** <li> The new object is configured with the rebase buffer obtained from
+** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
+** If the local changeset is to be rebased against multiple remote
+** changesets, then sqlite3rebaser_configure() should be called
+** multiple times, in the same order that the multiple
+** sqlite3changeset_apply_v2() calls were made.
+** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
+** <li> The sqlite3_rebaser object is deleted by calling
+** sqlite3rebaser_delete().
+** </ol>
+*/
+typedef struct sqlite3_rebaser sqlite3_rebaser;
+
+/*
+** CAPI3REF: Create a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
+** point to the new object and return SQLITE_OK. Otherwise, if an error
+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew)
+** to NULL.
+*/
+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
+
+/*
+** CAPI3REF: Configure a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Configure the changeset rebaser object to rebase changesets according
+** to the conflict resolutions described by buffer pRebase (size nRebase
+** bytes), which must have been obtained from a previous call to
+** sqlite3changeset_apply_v2().
+*/
+SQLITE_API int sqlite3rebaser_configure(
+ sqlite3_rebaser*,
+ int nRebase, const void *pRebase
+);
+
+/*
+** CAPI3REF: Rebase a changeset
+** EXPERIMENTAL
+**
+** Argument pIn must point to a buffer containing a changeset nIn bytes
+** in size. This function allocates and populates a buffer with a copy
+** of the changeset rebased rebased according to the configuration of the
+** rebaser object passed as the first argument. If successful, (*ppOut)
+** is set to point to the new buffer containing the rebased changset and
+** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
+** responsibility of the caller to eventually free the new buffer using
+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
+** are set to zero and an SQLite error code returned.
+*/
+SQLITE_API int sqlite3rebaser_rebase(
+ sqlite3_rebaser*,
+ int nIn, const void *pIn,
+ int *pnOut, void **ppOut
+);
+
+/*
+** CAPI3REF: Delete a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Delete the changeset rebaser object and all associated resources. There
+** should be one call to this function for each successful invocation
+** of sqlite3rebaser_create().
+*/
+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
+
/*
** CAPI3REF: Streaming Versions of API functions.
**
@@ -11042,6 +11878,7 @@ SQLITE_API int sqlite3changeset_apply(
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
+** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
@@ -11137,6 +11974,23 @@ SQLITE_API int sqlite3changeset_apply_strm(
),
void *pCtx /* First argument passed to xConflict */
);
+SQLITE_API int sqlite3changeset_apply_v2_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 */
+ void **ppRebase, int *pnRebase,
+ int flags
+);
SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
@@ -11174,6 +12028,13 @@ SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
+SQLITE_API int sqlite3rebaser_rebase_strm(
+ sqlite3_rebaser *pRebaser,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
/*
@@ -11632,7 +12493,7 @@ struct Fts5ExtensionApi {
** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do would be
** inefficient), it doesn't matter if the user queries for
-** 'first + place' or '1st + place', as there are entires in the
+** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
** </ol>
**
@@ -11660,7 +12521,7 @@ struct Fts5ExtensionApi {
** extra data to the FTS index or require FTS5 to query for multiple terms,
** so it is efficient in terms of disk space and query speed. However, it
** does not support prefix queries very well. If, as suggested above, the
-** token "first" is subsituted for "1st" by the tokenizer, then the query:
+** token "first" is substituted for "1st" by the tokenizer, then the query:
**
** <codeblock>
** ... MATCH '1s*'</codeblock>
@@ -12516,105 +13377,119 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_ESCAPE 58
#define TK_ID 59
#define TK_COLUMNKW 60
-#define TK_FOR 61
-#define TK_IGNORE 62
-#define TK_INITIALLY 63
-#define TK_INSTEAD 64
-#define TK_NO 65
-#define TK_KEY 66
-#define TK_OF 67
-#define TK_OFFSET 68
-#define TK_PRAGMA 69
-#define TK_RAISE 70
-#define TK_RECURSIVE 71
-#define TK_REPLACE 72
-#define TK_RESTRICT 73
-#define TK_ROW 74
-#define TK_TRIGGER 75
-#define TK_VACUUM 76
-#define TK_VIEW 77
-#define TK_VIRTUAL 78
-#define TK_WITH 79
-#define TK_REINDEX 80
-#define TK_RENAME 81
-#define TK_CTIME_KW 82
-#define TK_ANY 83
-#define TK_BITAND 84
-#define TK_BITOR 85
-#define TK_LSHIFT 86
-#define TK_RSHIFT 87
-#define TK_PLUS 88
-#define TK_MINUS 89
-#define TK_STAR 90
-#define TK_SLASH 91
-#define TK_REM 92
-#define TK_CONCAT 93
-#define TK_COLLATE 94
-#define TK_BITNOT 95
-#define TK_INDEXED 96
-#define TK_STRING 97
-#define TK_JOIN_KW 98
-#define TK_CONSTRAINT 99
-#define TK_DEFAULT 100
-#define TK_NULL 101
-#define TK_PRIMARY 102
-#define TK_UNIQUE 103
-#define TK_CHECK 104
-#define TK_REFERENCES 105
-#define TK_AUTOINCR 106
-#define TK_ON 107
-#define TK_INSERT 108
-#define TK_DELETE 109
-#define TK_UPDATE 110
-#define TK_SET 111
-#define TK_DEFERRABLE 112
-#define TK_FOREIGN 113
-#define TK_DROP 114
-#define TK_UNION 115
-#define TK_ALL 116
-#define TK_EXCEPT 117
-#define TK_INTERSECT 118
-#define TK_SELECT 119
-#define TK_VALUES 120
-#define TK_DISTINCT 121
-#define TK_DOT 122
-#define TK_FROM 123
-#define TK_JOIN 124
-#define TK_USING 125
-#define TK_ORDER 126
-#define TK_GROUP 127
-#define TK_HAVING 128
-#define TK_LIMIT 129
-#define TK_WHERE 130
-#define TK_INTO 131
-#define TK_FLOAT 132
-#define TK_BLOB 133
-#define TK_INTEGER 134
-#define TK_VARIABLE 135
-#define TK_CASE 136
-#define TK_WHEN 137
-#define TK_THEN 138
-#define TK_ELSE 139
-#define TK_INDEX 140
-#define TK_ALTER 141
-#define TK_ADD 142
-#define TK_ISNOT 143
-#define TK_FUNCTION 144
-#define TK_COLUMN 145
-#define TK_AGG_FUNCTION 146
-#define TK_AGG_COLUMN 147
-#define TK_UMINUS 148
-#define TK_UPLUS 149
-#define TK_REGISTER 150
-#define TK_VECTOR 151
-#define TK_SELECT_COLUMN 152
-#define TK_IF_NULL_ROW 153
-#define TK_ASTERISK 154
-#define TK_SPAN 155
-#define TK_END_OF_FILE 156
-#define TK_UNCLOSED_STRING 157
-#define TK_SPACE 158
-#define TK_ILLEGAL 159
+#define TK_DO 61
+#define TK_FOR 62
+#define TK_IGNORE 63
+#define TK_INITIALLY 64
+#define TK_INSTEAD 65
+#define TK_NO 66
+#define TK_KEY 67
+#define TK_OF 68
+#define TK_OFFSET 69
+#define TK_PRAGMA 70
+#define TK_RAISE 71
+#define TK_RECURSIVE 72
+#define TK_REPLACE 73
+#define TK_RESTRICT 74
+#define TK_ROW 75
+#define TK_ROWS 76
+#define TK_TRIGGER 77
+#define TK_VACUUM 78
+#define TK_VIEW 79
+#define TK_VIRTUAL 80
+#define TK_WITH 81
+#define TK_CURRENT 82
+#define TK_FOLLOWING 83
+#define TK_PARTITION 84
+#define TK_PRECEDING 85
+#define TK_RANGE 86
+#define TK_UNBOUNDED 87
+#define TK_REINDEX 88
+#define TK_RENAME 89
+#define TK_CTIME_KW 90
+#define TK_ANY 91
+#define TK_BITAND 92
+#define TK_BITOR 93
+#define TK_LSHIFT 94
+#define TK_RSHIFT 95
+#define TK_PLUS 96
+#define TK_MINUS 97
+#define TK_STAR 98
+#define TK_SLASH 99
+#define TK_REM 100
+#define TK_CONCAT 101
+#define TK_COLLATE 102
+#define TK_BITNOT 103
+#define TK_ON 104
+#define TK_INDEXED 105
+#define TK_STRING 106
+#define TK_JOIN_KW 107
+#define TK_CONSTRAINT 108
+#define TK_DEFAULT 109
+#define TK_NULL 110
+#define TK_PRIMARY 111
+#define TK_UNIQUE 112
+#define TK_CHECK 113
+#define TK_REFERENCES 114
+#define TK_AUTOINCR 115
+#define TK_INSERT 116
+#define TK_DELETE 117
+#define TK_UPDATE 118
+#define TK_SET 119
+#define TK_DEFERRABLE 120
+#define TK_FOREIGN 121
+#define TK_DROP 122
+#define TK_UNION 123
+#define TK_ALL 124
+#define TK_EXCEPT 125
+#define TK_INTERSECT 126
+#define TK_SELECT 127
+#define TK_VALUES 128
+#define TK_DISTINCT 129
+#define TK_DOT 130
+#define TK_FROM 131
+#define TK_JOIN 132
+#define TK_USING 133
+#define TK_ORDER 134
+#define TK_GROUP 135
+#define TK_HAVING 136
+#define TK_LIMIT 137
+#define TK_WHERE 138
+#define TK_INTO 139
+#define TK_NOTHING 140
+#define TK_FLOAT 141
+#define TK_BLOB 142
+#define TK_INTEGER 143
+#define TK_VARIABLE 144
+#define TK_CASE 145
+#define TK_WHEN 146
+#define TK_THEN 147
+#define TK_ELSE 148
+#define TK_INDEX 149
+#define TK_ALTER 150
+#define TK_ADD 151
+#define TK_WINDOW 152
+#define TK_OVER 153
+#define TK_FILTER 154
+#define TK_TRUEFALSE 155
+#define TK_ISNOT 156
+#define TK_FUNCTION 157
+#define TK_COLUMN 158
+#define TK_AGG_FUNCTION 159
+#define TK_AGG_COLUMN 160
+#define TK_UMINUS 161
+#define TK_UPLUS 162
+#define TK_TRUTH 163
+#define TK_REGISTER 164
+#define TK_VECTOR 165
+#define TK_SELECT_COLUMN 166
+#define TK_IF_NULL_ROW 167
+#define TK_ASTERISK 168
+#define TK_SPAN 169
+#define TK_END_OF_FILE 170
+#define TK_UNCLOSED_STRING 171
+#define TK_SPACE 172
+#define TK_ILLEGAL 173
/* The token codes above must all fit in 8 bits */
#define TKFLG_MASK 0xff
@@ -12735,6 +13610,13 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#endif
/*
+** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option.
+*/
+#ifndef SQLITE_DEFAULT_SORTERREF_SIZE
+# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff
+#endif
+
+/*
** The compile-time options SQLITE_MMAP_READWRITE and
** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
** You must choose one or the other (or neither) but not both.
@@ -12881,7 +13763,8 @@ typedef INT16_TYPE LogEst;
# if defined(__SIZEOF_POINTER__)
# define SQLITE_PTRSIZE __SIZEOF_POINTER__
# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(_M_ARM) || defined(__arm__) || defined(__x86)
+ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \
+ (defined(__TOS_AIX__) && !defined(__64BIT__))
# define SQLITE_PTRSIZE 4
# else
# define SQLITE_PTRSIZE 8
@@ -12922,7 +13805,7 @@ typedef INT16_TYPE LogEst;
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__)
+ defined(__arm__) || defined(_M_ARM64)
# define SQLITE_BYTEORDER 1234
# elif defined(sparc) || defined(__ppc__)
# define SQLITE_BYTEORDER 4321
@@ -13059,9 +13942,10 @@ typedef INT16_TYPE LogEst;
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
- int (*xFunc)(void *,int); /* The busy callback */
- void *pArg; /* First arg to busy callback */
- int nBusy; /* Incremented with each busy call */
+ int (*xBusyHandler)(void *,int); /* The busy callback */
+ void *pBusyArg; /* First arg to busy callback */
+ int nBusy; /* Incremented with each busy call */
+ u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
};
/*
@@ -13161,7 +14045,6 @@ typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
-typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
typedef struct FuncDef FuncDef;
@@ -13178,13 +14061,14 @@ typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct PreUpdate PreUpdate;
typedef struct PrintfArguments PrintfArguments;
+typedef struct RenameToken RenameToken;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
-typedef struct StrAccum StrAccum;
+typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
@@ -13193,12 +14077,40 @@ typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
typedef struct TriggerStep TriggerStep;
typedef struct UnpackedRecord UnpackedRecord;
+typedef struct Upsert Upsert;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WhereInfo WhereInfo;
+typedef struct Window Window;
typedef struct With With;
+
+/*
+** The bitmask datatype defined below is used for various optimizations.
+**
+** Changing this from a 64-bit to a 32-bit type limits the number of
+** tables in a join to 32 instead of 64. But it also reduces the size
+** of the library by 738 bytes on ix86.
+*/
+#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".
+*/
+#define BMS ((int)(sizeof(Bitmask)*8))
+
+/*
+** A bit in a Bitmask
+*/
+#define MASKBIT(n) (((Bitmask)1)<<(n))
+#define MASKBIT32(n) (((unsigned int)1)<<(n))
+#define ALLBITS ((Bitmask)-1)
+
/* A VList object records a mapping between parameters/variables/wildcards
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
** variable number associated with that parameter. See the format description
@@ -13294,7 +14206,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*);
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
+SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
@@ -13475,13 +14387,28 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
** entry in either an index or table btree.
**
** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
-** an arbitrary key and no data. These btrees have pKey,nKey set to their
-** key and pData,nData,nZero set to zero.
+** an arbitrary key and no data. These btrees have pKey,nKey set to the
+** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem
+** fields give an array of Mem objects that are a decomposition of the key.
+** The nMem field might be zero, indicating that no decomposition is available.
**
** Table btrees (used for rowid tables) contain an integer rowid used as
** the key and passed in the nKey field. The pKey field is zero.
** pData,nData hold the content of the new entry. nZero extra zero bytes
** are appended to the end of the content when constructing the entry.
+** The aMem,nMem fields are uninitialized for table btrees.
+**
+** Field usage summary:
+**
+** Table BTrees Index Btrees
+**
+** pKey always NULL encoded key
+** nKey the ROWID length of pKey
+** pData data not used
+** aMem not used decomposed key value
+** nMem not used entries in aMem
+** nData length of pData not used
+** nZero extra zeros after pData not used
**
** This object is used to pass information into sqlite3BtreeInsert(). The
** same information used to be passed as five separate parameters. But placing
@@ -13492,7 +14419,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
struct BtreePayload {
const void *pKey; /* Key content for indexes. NULL for tables */
sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
- const void *pData; /* Data for tables. NULL for indexes */
+ const void *pData; /* Data for tables. */
sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */
u16 nMem; /* Number of aMem[] value. Might be zero */
int nData; /* Size of pData. 0 if none. */
@@ -13502,11 +14429,17 @@ struct BtreePayload {
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*);
+#endif
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
+#endif
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
@@ -13666,7 +14599,8 @@ struct VdbeOp {
u64 cycles; /* Total time spent executing this instruction */
#endif
#ifdef SQLITE_VDBE_COVERAGE
- int iSrcLine; /* Source-code line that generated this opcode */
+ u32 iSrcLine; /* Source-code line that generated this opcode
+ ** with flags in the upper 8 bits */
#endif
};
typedef struct VdbeOp VdbeOp;
@@ -13720,6 +14654,7 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
+#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -13766,52 +14701,52 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_AutoCommit 1
#define OP_Transaction 2
#define OP_SorterNext 3 /* jump */
-#define OP_PrevIfOpen 4 /* jump */
-#define OP_NextIfOpen 5 /* jump */
-#define OP_Prev 6 /* jump */
-#define OP_Next 7 /* jump */
-#define OP_Checkpoint 8
-#define OP_JournalMode 9
-#define OP_Vacuum 10
-#define OP_VFilter 11 /* jump, synopsis: iplan=r[P3] zplan='P4' */
-#define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */
-#define OP_Goto 13 /* jump */
-#define OP_Gosub 14 /* jump */
-#define OP_InitCoroutine 15 /* jump */
-#define OP_Yield 16 /* jump */
-#define OP_MustBeInt 17 /* jump */
-#define OP_Jump 18 /* jump */
+#define OP_Prev 4 /* jump */
+#define OP_Next 5 /* jump */
+#define OP_Checkpoint 6
+#define OP_JournalMode 7
+#define OP_Vacuum 8
+#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */
+#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */
+#define OP_Goto 11 /* jump */
+#define OP_Gosub 12 /* jump */
+#define OP_InitCoroutine 13 /* jump */
+#define OP_Yield 14 /* jump */
+#define OP_MustBeInt 15 /* jump */
+#define OP_Jump 16 /* jump */
+#define OP_Once 17 /* jump */
+#define OP_If 18 /* jump */
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
-#define OP_Once 20 /* jump */
-#define OP_If 21 /* jump */
-#define OP_IfNot 22 /* jump */
-#define OP_IfNullRow 23 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
-#define OP_SeekLT 24 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekLE 25 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGE 26 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGT 27 /* jump, synopsis: key=r[P3@P4] */
-#define OP_NoConflict 28 /* jump, synopsis: key=r[P3@P4] */
-#define OP_NotFound 29 /* jump, synopsis: key=r[P3@P4] */
-#define OP_Found 30 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 31 /* jump, synopsis: intkey=r[P3] */
-#define OP_NotExists 32 /* jump, synopsis: intkey=r[P3] */
-#define OP_Last 33 /* jump */
-#define OP_IfSmaller 34 /* jump */
-#define OP_SorterSort 35 /* jump */
-#define OP_Sort 36 /* jump */
-#define OP_Rewind 37 /* jump */
-#define OP_IdxLE 38 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxGT 39 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxLT 40 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxGE 41 /* jump, synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 42 /* jump, synopsis: r[P3]=rowset(P1) */
+#define OP_IfNot 20 /* jump */
+#define OP_IfNullRow 21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
+#define OP_SeekLT 22 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekLE 23 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekGE 24 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekGT 25 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */
+#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */
+#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */
+#define OP_Last 32 /* jump */
+#define OP_IfSmaller 33 /* jump */
+#define OP_SorterSort 34 /* jump */
+#define OP_Sort 35 /* jump */
+#define OP_Rewind 36 /* jump */
+#define OP_IdxLE 37 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGT 38 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxLT 39 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGE 40 /* jump, synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 41 /* jump, synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 46 /* jump */
-#define OP_FkIfZero 47 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_Program 45 /* jump */
+#define OP_FkIfZero 46 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_DecrJumpZero 49 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
@@ -13821,115 +14756,121 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
#define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */
-#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */
-#define OP_IncrVacuum 60 /* jump */
-#define OP_VNext 61 /* jump */
-#define OP_Init 62 /* jump, synopsis: Start at P2 */
-#define OP_Return 63
-#define OP_EndCoroutine 64
-#define OP_HaltIfNull 65 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 66
-#define OP_Integer 67 /* synopsis: r[P2]=P1 */
-#define OP_Int64 68 /* synopsis: r[P2]=P4 */
-#define OP_String 69 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 70 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 71 /* synopsis: r[P1]=NULL */
-#define OP_Blob 72 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 73 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 74 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 75 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 76 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 77 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 78 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 79
-#define OP_AddImm 80 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_RealAffinity 81
-#define OP_Cast 82 /* synopsis: affinity(r[P1]) */
-#define OP_Permutation 83
-#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
-#define OP_ShiftRight 87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
-#define OP_Add 88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_Compare 94 /* synopsis: r[P1@P3] <-> r[P2@P3] */
-#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_Column 96 /* synopsis: r[P3]=PX */
-#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 100 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 101
-#define OP_SetCookie 102
-#define OP_ReopenIdx 103 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 104 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 105 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenDup 106
-#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2 */
-#define OP_SorterOpen 109
-#define OP_SequenceTest 110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_OpenPseudo 111 /* synopsis: P3 columns in r[P2] */
-#define OP_Close 112
-#define OP_ColumnsUsed 113
-#define OP_Sequence 114 /* synopsis: r[P2]=cursor[P1].ctr++ */
-#define OP_NewRowid 115 /* synopsis: r[P2]=rowid */
-#define OP_Insert 116 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_InsertInt 117 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 118
-#define OP_ResetCount 119
-#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 121 /* synopsis: r[P2]=data */
-#define OP_RowData 122 /* synopsis: r[P2]=data */
-#define OP_Rowid 123 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 124
-#define OP_SeekEnd 125
-#define OP_SorterInsert 126 /* synopsis: key=r[P2] */
-#define OP_IdxInsert 127 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 128 /* synopsis: key=r[P2@P3] */
-#define OP_DeferredSeek 129 /* synopsis: Move P3 to P1.rowid if needed */
-#define OP_IdxRowid 130 /* synopsis: r[P2]=rowid */
-#define OP_Destroy 131
-#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_Clear 133
-#define OP_ResetSorter 134
-#define OP_CreateBtree 135 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
-#define OP_SqlExec 136
-#define OP_ParseSchema 137
-#define OP_LoadAnalysis 138
-#define OP_DropTable 139
-#define OP_DropIndex 140
-#define OP_DropTrigger 141
-#define OP_IntegrityCk 142
-#define OP_RowSetAdd 143 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Param 144
-#define OP_FkCounter 145 /* synopsis: fkctr[P1]+=P2 */
-#define OP_MemMax 146 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_OffsetLimit 147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggStep0 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggStep 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggFinal 150 /* synopsis: accum=r[P1] N=P2 */
-#define OP_Expire 151
-#define OP_TableLock 152 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 153
-#define OP_VCreate 154
-#define OP_VDestroy 155
-#define OP_VOpen 156
-#define OP_VColumn 157 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 158
-#define OP_Pagecount 159
-#define OP_MaxPgcnt 160
-#define OP_PureFunc0 161
-#define OP_Function0 162 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_PureFunc 163
-#define OP_Function 164 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_CursorHint 165
-#define OP_Noop 166
-#define OP_Explain 167
+#define OP_IncrVacuum 59 /* jump */
+#define OP_VNext 60 /* jump */
+#define OP_Init 61 /* jump, synopsis: Start at P2 */
+#define OP_PureFunc0 62
+#define OP_Function0 63 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_PureFunc 64
+#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Return 66
+#define OP_EndCoroutine 67
+#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 69
+#define OP_Integer 70 /* synopsis: r[P2]=P1 */
+#define OP_Int64 71 /* synopsis: r[P2]=P4 */
+#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */
+#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 82
+#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 84
+#define OP_Cast 85 /* synopsis: affinity(r[P1]) */
+#define OP_Permutation 86
+#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */
+#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
+#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */
+#define OP_Column 90 /* synopsis: r[P3]=PX */
+#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */
+#define OP_BitAnd 92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 95 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_MakeRecord 102 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_BitNot 103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
+#define OP_Count 104 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 105
+#define OP_String8 106 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_SetCookie 107
+#define OP_ReopenIdx 108 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 109 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 110 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenDup 111
+#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 114
+#define OP_SequenceTest 115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 116 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 117
+#define OP_ColumnsUsed 118
+#define OP_SeekHit 119 /* synopsis: seekHit=P2 */
+#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */
+#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 123 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 124
+#define OP_ResetCount 125
+#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 127 /* synopsis: r[P2]=data */
+#define OP_RowData 128 /* synopsis: r[P2]=data */
+#define OP_Rowid 129 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 130
+#define OP_SeekEnd 131
+#define OP_SorterInsert 132 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 133 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 134 /* synopsis: key=r[P2@P3] */
+#define OP_DeferredSeek 135 /* synopsis: Move P3 to P1.rowid if needed */
+#define OP_IdxRowid 136 /* synopsis: r[P2]=rowid */
+#define OP_Destroy 137
+#define OP_Clear 138
+#define OP_ResetSorter 139
+#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
+#define OP_Real 141 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_SqlExec 142
+#define OP_ParseSchema 143
+#define OP_LoadAnalysis 144
+#define OP_DropTable 145
+#define OP_DropIndex 146
+#define OP_DropTrigger 147
+#define OP_IntegrityCk 148
+#define OP_RowSetAdd 149 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 150
+#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
+#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */
+#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 159
+#define OP_TableLock 160 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 161
+#define OP_VCreate 162
+#define OP_VDestroy 163
+#define OP_VOpen 164
+#define OP_VColumn 165 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 166
+#define OP_Pagecount 167
+#define OP_MaxPgcnt 168
+#define OP_Trace 169
+#define OP_CursorHint 170
+#define OP_Noop 171
+#define OP_Explain 172
+#define OP_Abortable 173
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -13942,28 +14883,28 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
#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, 0x01,\
-/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
+/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
+/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
+/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\
/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
-/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
-/* 40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\
+/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+/* 40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\
/* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
-/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x02,\
-/* 64 */ 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00,\
-/* 72 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
-/* 80 */ 0x02, 0x02, 0x02, 0x00, 0x26, 0x26, 0x26, 0x26,\
-/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
-/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
-/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x04,\
-/* 128 */ 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\
-/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
-/* 160 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-}
+/* 56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\
+/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
+/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
+/* 80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
+/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\
+/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
+/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\
+/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
+/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
@@ -13971,7 +14912,7 @@ typedef struct VdbeOpList VdbeOpList;
** generated this include file strives to group all JUMP opcodes
** together near the beginning of the list.
*/
-#define SQLITE_MX_JUMP_OPCODE 62 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 61 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -14005,7 +14946,24 @@ SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
# define sqlite3VdbeVerifyNoMallocRequired(A,B)
# define sqlite3VdbeVerifyNoResultRow(A)
#endif
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int);
+#else
+# define sqlite3VdbeVerifyAbortable(A,B)
+#endif
+SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
+#ifndef SQLITE_OMIT_EXPLAIN
+SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...);
+SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*);
+SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*);
+# define ExplainQueryPlan(P) sqlite3VdbeExplain P
+# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P)
+# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P)
+#else
+# define ExplainQueryPlan(P)
+# define ExplainQueryPlanPop(P)
+# define ExplainQueryPlanParent(P) 0
+#endif
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
@@ -14049,6 +15007,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
+SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*);
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
@@ -14104,23 +15063,52 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
**
** VdbeCoverageNeverTaken(v) // Previous branch is never taken
**
+** VdbeCoverageNeverNull(v) // Previous three-way branch is only
+** // taken on the first two ways. The
+** // NULL option is not possible
+**
+** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested
+** // in distingishing equal and not-equal.
+**
** Every VDBE branch operation must be tagged with one of the macros above.
** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
** routine in vdbe.c, alerting the developer to the missed tag.
+**
+** During testing, the test application will invoke
+** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback
+** routine that is invoked as each bytecode branch is taken. The callback
+** contains the sqlite3.c source line number ov the VdbeCoverage macro and
+** flags to indicate whether or not the branch was taken. The test application
+** is responsible for keeping track of this and reporting byte-code branches
+** that are never taken.
+**
+** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the
+** vdbe.c source file for additional information.
*/
#ifdef SQLITE_VDBE_COVERAGE
SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int);
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
-# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
-# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
+# define VdbeCoverageAlwaysTaken(v) \
+ sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000);
+# define VdbeCoverageNeverTaken(v) \
+ sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000);
+# define VdbeCoverageNeverNull(v) \
+ sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
+# define VdbeCoverageNeverNullIf(v,x) \
+ if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
+# define VdbeCoverageEqNe(v) \
+ sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000);
# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
#else
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
+# define VdbeCoverageNeverNull(v)
+# define VdbeCoverageNeverNullIf(v,x)
+# define VdbeCoverageEqNe(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif
@@ -14130,6 +15118,10 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const ch
# define sqlite3VdbeScanStatus(a,b,c,d,e)
#endif
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*);
+#endif
+
#endif /* SQLITE_VDBE_H */
/************** End of vdbe.h ************************************************/
@@ -14264,7 +15256,7 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
/* Functions used to configure a Pager object. */
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
+SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
#ifdef SQLITE_HAS_CODEC
SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
@@ -14324,6 +15316,8 @@ SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
+SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#else
# define sqlite3PagerUseWal(x,y) 0
@@ -14350,6 +15344,11 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
+#else
+# define sqlite3PagerResetLockTimeout(X)
+#endif
/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
@@ -15157,7 +16156,7 @@ struct sqlite3 {
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
u8 mTrace; /* zero or more SQLITE_TRACE flags */
- u8 skipBtreeMutex; /* True if no shared-cache backends */
+ u8 noSharedCache; /* True if no shared-cache backends */
u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
@@ -15169,8 +16168,9 @@ struct sqlite3 {
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
- u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
- u8 imposterTable; /* Building an imposter table */
+ unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
+ unsigned imposterTable : 1; /* Building an imposter table */
+ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
int nVdbeRead; /* Number of active VDBEs that read or write */
@@ -15223,7 +16223,7 @@ struct sqlite3 {
Hash aModule; /* populated by sqlite3_create_module() */
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
VTable **aVTrans; /* Virtual tables with open transactions */
- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
+ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
#endif
Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
@@ -15298,7 +16298,11 @@ struct sqlite3 {
#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */
#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
-#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee */
+#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
+#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
+#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
+#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
+
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
@@ -15314,6 +16318,7 @@ struct sqlite3 {
#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
+#define DBFLAG_SchemaKnownOk 0x0008 /* Schema is known to be valid */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -15321,7 +16326,7 @@ struct sqlite3 {
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
-#define SQLITE_ColumnCache 0x0002 /* Column cache */
+ /* 0x0002 available for reuse */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */
@@ -15333,6 +16338,10 @@ struct sqlite3 {
#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
/* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */
+#define SQLITE_PushDown 0x1000 /* The push-down optimization */
+#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */
+#define SQLITE_SkipScan 0x4000 /* Skip-scans */
+#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -15371,11 +16380,13 @@ struct sqlite3 {
*/
struct FuncDef {
i8 nArg; /* Number of arguments. -1 means unlimited */
- u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
+ u32 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 */
+ void (*xValue)(sqlite3_context*); /* Current agg value */
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
const char *zName; /* SQL name of the function. */
union {
FuncDef *pHash; /* Next with a different name but the same hash */
@@ -15431,6 +16442,9 @@ struct FuncDestructor {
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
+#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
+#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
+#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -15465,6 +16479,12 @@ struct FuncDestructor {
** are interpreted in the same way as the first 4 parameters to
** FUNCTION().
**
+** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse)
+** Used to create an aggregate function definition implemented by
+** the C functions xStep and xFinal. The first four parameters
+** are interpreted in the same way as the first 4 parameters to
+** 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
@@ -15475,31 +16495,35 @@ 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} }
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 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} }
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
- 0, 0, xFunc, 0, #zName, {0} }
+ 0, 0, xFunc, 0, 0, 0, #zName, {0} }
#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
- (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} }
+ (void*)&sqlite3Config, 0, xFunc, 0, 0, 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} }
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 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, }
+ pArg, 0, xFunc, 0, 0, 0, #zName, }
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
- (void *)arg, 0, likeFunc, 0, #zName, {0} }
-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
+ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
+#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#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}}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
+
+#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
+ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
/*
** All current savepoints are stored in a linked list starting at
@@ -15555,6 +16579,8 @@ 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 */
+#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */
+#define COLFLAG_SORTERREF 0x0010 /* Use sorter-refs with this column */
/*
** A "Collating Sequence" is defined by an instance of the following
@@ -15842,13 +16868,12 @@ struct FKey {
#define OE_Fail 3 /* Stop the operation but leave all prior changes */
#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
-
-#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
-#define OE_SetNull 7 /* Set the foreign key value to NULL */
-#define OE_SetDflt 8 /* Set the foreign key value to its default */
-#define OE_Cascade 9 /* Cascade the changes */
-
-#define OE_Default 10 /* Do whatever the default action is */
+#define OE_Update 6 /* Process as a DO UPDATE in an upsert */
+#define OE_Restrict 7 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+#define OE_SetNull 8 /* Set the foreign key value to NULL */
+#define OE_SetDflt 9 /* Set the foreign key value to its default */
+#define OE_Cascade 10 /* Cascade the changes */
+#define OE_Default 11 /* Do whatever the default action is */
/*
@@ -15975,6 +17000,7 @@ struct Index {
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
+ unsigned bNoQuery:1; /* Do not use this index to optimize queries */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -15983,6 +17009,7 @@ struct Index {
tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */
tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */
#endif
+ Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */
};
/*
@@ -16021,9 +17048,11 @@ struct IndexSample {
** Each token coming out of the lexer is an instance of
** this structure. Tokens are also used as part of an expression.
**
-** Note if Token.z==0 then Token.dyn and Token.n are undefined and
-** may contain random values. Do not make any assumptions about Token.dyn
-** and Token.n when Token.z==0.
+** The memory that "z" points to is owned by other objects. Take care
+** that the owner of the "z" string does not deallocate the string before
+** the Token goes out of scope! Very often, the "z" points to some place
+** in the middle of the Parse.zSql text. But it might also point to a
+** static string.
*/
struct Token {
const char *z; /* Text of the token. Not NULL-terminated! */
@@ -16198,6 +17227,9 @@ struct Expr {
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
** for a column of an index on an expression */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ Window *pWin; /* Window definition for window functions */
+#endif
};
/*
@@ -16205,8 +17237,8 @@ struct Expr {
*/
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
- /* 0x000004 // available for use */
- /* 0x000008 // available for use */
+#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
+#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
@@ -16229,9 +17261,10 @@ struct Expr {
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
/*
-** Combinations of two or more EP_* flags
+** The EP_Propagate mask is a set of properties that automatically propagate
+** upwards into parent nodes.
*/
-#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
+#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
/*
** These macros can be used to test, set, or clear bits in the
@@ -16293,6 +17326,7 @@ struct ExprList {
unsigned done :1; /* A flag to indicate when processing is finished */
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
unsigned reusable :1; /* Constant expression is reusable */
+ unsigned bSorterRef :1; /* Defer evaluation until after sorting */
union {
struct {
u16 iOrderByCol; /* For ORDER BY, column number in result set */
@@ -16304,17 +17338,6 @@ struct ExprList {
};
/*
-** An instance of this structure is used by the parser to record both
-** the parse tree for an expression and the span of input text for an
-** expression.
-*/
-struct ExprSpan {
- Expr *pExpr; /* The expression parse tree */
- const char *zStart; /* First character of input text */
- const char *zEnd; /* One character past the end of input text */
-};
-
-/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
@@ -16338,31 +17361,6 @@ struct IdList {
};
/*
-** The bitmask datatype defined below is used for various optimizations.
-**
-** Changing this from a 64-bit to a 32-bit type limits the number of
-** tables in a join to 32 instead of 64. But it also reduces the size
-** of the library by 738 bytes on ix86.
-*/
-#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".
-*/
-#define BMS ((int)(sizeof(Bitmask)*8))
-
-/*
-** A bit in a 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.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
@@ -16403,9 +17401,6 @@ struct SrcList {
unsigned viaCoroutine :1; /* Implemented as a co-routine */
unsigned isRecursive :1; /* True for recursive reference in WITH */
} fg;
-#ifndef SQLITE_OMIT_EXPLAIN
- u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
-#endif
int iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
IdList *pUsing; /* The USING clause of a join */
@@ -16487,12 +17482,16 @@ struct SrcList {
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
- ExprList *pEList; /* Optional list of result-set columns */
- AggInfo *pAggInfo; /* Information about aggregates at this level */
+ union {
+ ExprList *pEList; /* Optional list of result-set columns */
+ AggInfo *pAggInfo; /* Information about aggregates at this level */
+ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */
+ } uNC;
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u16 ncFlags; /* Zero or more NC_* flags defined below */
+ Select *pWinSelect; /* SELECT statement for any window functions */
};
/*
@@ -16510,17 +17509,49 @@ struct NameContext {
#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_UEList 0x0080 /* True if uNC.pEList is used */
+#define NC_UAggInfo 0x0100 /* True if uNC.pAggInfo is used */
+#define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
+#define NC_Complex 0x2000 /* True if a function or subquery seen */
+#define NC_AllowWin 0x4000 /* Window functions are allowed here */
+
+/*
+** An instance of the following object describes a single ON CONFLICT
+** clause in an upsert.
+**
+** The pUpsertTarget field is only set if the ON CONFLICT clause includes
+** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the
+** conflict-target clause.) The pUpsertTargetWhere is the optional
+** WHERE clause used to identify partial unique indexes.
+**
+** pUpsertSet is the list of column=expr terms of the UPDATE statement.
+** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The
+** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
+** WHERE clause is omitted.
+*/
+struct Upsert {
+ ExprList *pUpsertTarget; /* Optional description of conflicting index */
+ Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */
+ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */
+ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
+ /* The fields above comprise the parse tree for the upsert clause.
+ ** The fields below are used to transfer information from the INSERT
+ ** processing down into the UPDATE processing while generating code.
+ ** Upsert owns the memory allocated above, but not the memory below. */
+ Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */
+ SrcList *pUpsertSrc; /* Table to be updated */
+ int regData; /* First register holding array of VALUES */
+ int iDataCur; /* Index of the data cursor */
+ int iIdxCur; /* Index of the first index cursor */
+};
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
-** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
-** If there is a LIMIT clause, the parser sets nLimit to the value of the
-** limit and nOffset to the value of the offset (or 0 if there is not
-** offset). But later on, nLimit and nOffset become the memory locations
-** in the VDBE that record the limit and offset counters.
+** See the header comment on the computeLimitRegisters() routine for a
+** detailed description of the meaning of the iLimit and iOffset fields.
**
** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
** These addresses must be stored so that we can go back and fill in
@@ -16538,9 +17569,7 @@ struct Select {
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
+ u32 selId; /* Unique identifier number for this SELECT */
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
@@ -16550,8 +17579,11 @@ struct Select {
Select *pPrior; /* Prior select in a compound select statement */
Select *pNext; /* Next select to the left in a compound */
Expr *pLimit; /* LIMIT expression. NULL means not used. */
- Expr *pOffset; /* OFFSET expression. NULL means not used. */
With *pWith; /* WITH clause attached to this select. Or NULL. */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ Window *pWin; /* List of window functions */
+ Window *pWinDefn; /* List of named window definitions */
+#endif
};
/*
@@ -16581,7 +17613,7 @@ struct Select {
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
-
+#define SF_ComplexResult 0x40000 /* Result contains subquery or function */
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -16696,13 +17728,6 @@ struct AutoincInfo {
};
/*
-** Size of the column cache
-*/
-#ifndef SQLITE_N_COLCACHE
-# define SQLITE_N_COLCACHE 10
-#endif
-
-/*
** 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
@@ -16781,7 +17806,6 @@ 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 nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
@@ -16789,10 +17813,8 @@ struct Parse {
int nMem; /* Number of memory cells used so far */
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
- int iSelfTab; /* Table for associated with an index on expr, or negative
+ int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
- int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
- int iCacheCnt; /* Counter used to generate aColCache[].lru values */
int nLabel; /* Number of labels used */
int *aLabel; /* Space to hold the labels */
ExprList *pConstExpr;/* Constant expressions */
@@ -16802,10 +17824,7 @@ struct Parse {
int regRowid; /* Register holding rowid of CREATE TABLE entry */
int regRoot; /* Register holding root page number for new objects */
int nMaxArg; /* Max args passed to user function by sub-program */
-#if SELECTTRACE_ENABLED
- int nSelect; /* Number of SELECT statements seen */
- int nSelectIndent; /* How far to indent SELECTTRACE() output */
-#endif
+ int nSelect; /* Number of SELECT stmts. Counter for Select.selId */
#ifndef SQLITE_OMIT_SHARED_CACHE
int nTableLock; /* Number of locks in aTableLock */
TableLock *aTableLock; /* Required table locks for shared-cache mode */
@@ -16825,17 +17844,9 @@ struct Parse {
** Fields above must be initialized to zero. The fields that follow,
** down to the beginning of the recursive section, do not need to be
** initialized as they will be set before being used. The boundary is
- ** determined by offsetof(Parse,aColCache).
+ ** determined by offsetof(Parse,aTempReg).
**************************************************************************/
- struct yColCache {
- int iTable; /* Table cursor number */
- i16 iColumn; /* Table column number */
- u8 tempReg; /* iReg is a temp register that needs to be freed */
- int iLevel; /* Nesting level */
- int iReg; /* Reg with value of this column. 0 means none. */
- int lru; /* Least recently used entry has the smallest value */
- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
int aTempReg[8]; /* Holding area for temporary registers */
Token sNameToken; /* Token with unqualified schema object name */
@@ -16850,19 +17861,21 @@ struct Parse {
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
+#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE))
+ u8 eParseMode; /* PARSE_MODE_XXX constant */
+#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
- u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
int nVtabLock; /* Number of virtual tables to lock */
#endif
int nHeight; /* Expression tree height of current sub-select */
#ifndef SQLITE_OMIT_EXPLAIN
- int iSelectId; /* ID of current select for EXPLAIN output */
- int iNextSelectId; /* Next available select ID for EXPLAIN output */
+ int addrExplain; /* Address of current OP_Explain opcode */
#endif
VList *pVList; /* Mapping between variable names and numbers */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
+ Index *pNewIndex; /* An index being constructed by CREATE INDEX */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -16873,12 +17886,20 @@ struct Parse {
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
With *pWith; /* Current WITH clause, or NULL */
With *pWithToFree; /* Free this WITH object at the end of the parse */
+#ifndef SQLITE_OMIT_ALTERTABLE
+ RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */
+#endif
};
+#define PARSE_MODE_NORMAL 0
+#define PARSE_MODE_DECLARE_VTAB 1
+#define PARSE_MODE_RENAME_COLUMN 2
+#define PARSE_MODE_RENAME_TABLE 3
+
/*
** Sizes and pointers of various parts of the Parse object.
*/
-#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
+#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
@@ -16889,7 +17910,19 @@ struct Parse {
#ifdef SQLITE_OMIT_VIRTUALTABLE
#define IN_DECLARE_VTAB 0
#else
- #define IN_DECLARE_VTAB (pParse->declareVtab)
+ #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB)
+#endif
+
+#if defined(SQLITE_OMIT_ALTERTABLE)
+ #define IN_RENAME_OBJECT 0
+#else
+ #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN)
+#endif
+
+#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)
+ #define IN_SPECIAL_PARSE 0
+#else
+ #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL)
#endif
/*
@@ -16915,6 +17948,7 @@ struct AuthContext {
*/
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
/* Also used in P2 (not P5) of OP_Delete */
+#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
@@ -16930,6 +17964,7 @@ struct AuthContext {
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
+#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
/*
* Each trigger present in the database schema is stored as an instance of
@@ -17015,8 +18050,10 @@ struct TriggerStep {
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
- ExprList *pExprList; /* SET clause for UPDATE. */
+ ExprList *pExprList; /* SET clause for UPDATE */
IdList *pIdList; /* Column names for INSERT */
+ Upsert *pUpsert; /* Upsert clauses on an INSERT */
+ char *zSpan; /* Original SQL text of this command */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
@@ -17040,17 +18077,15 @@ struct DbFixer {
** An objected used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
-struct StrAccum {
+struct sqlite3_str {
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
char *zText; /* The string collected so far */
u32 nAlloc; /* Amount of space allocated in zText */
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
u32 nChar; /* Length of the string so far */
- u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
+ u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */
u8 printfFlags; /* SQLITE_PRINTF flags below */
};
-#define STRACCUM_NOMEM 1
-#define STRACCUM_TOOBIG 2
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
@@ -17067,6 +18102,7 @@ typedef struct {
char **pzErrMsg; /* Error message stored here */
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
int rc; /* Result code stored here */
+ u32 mInitFlags; /* Flags controlling error messages */
} InitData;
/*
@@ -17086,6 +18122,11 @@ struct sqlite3_mem_methods {
};
/*
+** Allowed values for mInitFlags
+*/
+#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */
+
+/*
** Structure containing global configuration data for the SQLite library.
**
** This structure also contains some state information.
@@ -17135,7 +18176,7 @@ struct Sqlite3Config {
/* The following callback (if not NULL) is invoked on every VDBE branch
** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
*/
- void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
+ void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
#ifndef SQLITE_UNTESTABLE
@@ -17143,6 +18184,7 @@ struct Sqlite3Config {
int bLocaltimeFault; /* True to fail localtime() calls */
#endif
int iOnceResetThreshold; /* When to reset OP_Once counters */
+ u32 szSorterRef; /* Min size in bytes to use sorter-refs */
};
/*
@@ -17182,9 +18224,12 @@ struct Walker {
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
int *aiCol; /* array of column indexes */
struct IdxCover *pIdxCover; /* Check for index coverage */
- struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */
+ struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
ExprList *pGroupBy; /* GROUP BY clause */
- struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */
+ Select *pSelect; /* HAVING to WHERE clause ctx */
+ struct WindowRewrite *pRewrite; /* Window rewrite context */
+ struct WhereConst *pConst; /* WHERE clause constants */
+ struct RenameCtx *pRename; /* RENAME COLUMN context */
} u;
};
@@ -17236,6 +18281,68 @@ struct TreeView {
#endif /* SQLITE_DEBUG */
/*
+** This object is used in varioius ways, all related to window functions
+**
+** (1) A single instance of this structure is attached to the
+** the Expr.pWin field for each window function in an expression tree.
+** This object holds the information contained in the OVER clause,
+** plus additional fields used during code generation.
+**
+** (2) All window functions in a single SELECT form a linked-list
+** attached to Select.pWin. The Window.pFunc and Window.pExpr
+** fields point back to the expression that is the window function.
+**
+** (3) The terms of the WINDOW clause of a SELECT are instances of this
+** object on a linked list attached to Select.pWinDefn.
+**
+** The uses (1) and (2) are really the same Window object that just happens
+** to be accessible in two different ways. Use (3) is are separate objects.
+*/
+struct Window {
+ char *zName; /* Name of window (may be NULL) */
+ ExprList *pPartition; /* PARTITION BY clause */
+ ExprList *pOrderBy; /* ORDER BY clause */
+ u8 eType; /* TK_RANGE or TK_ROWS */
+ u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
+ u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
+ Expr *pStart; /* Expression for "<expr> PRECEDING" */
+ Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
+ Window *pNextWin; /* Next window function belonging to this SELECT */
+ Expr *pFilter; /* The FILTER expression */
+ FuncDef *pFunc; /* The function */
+ int iEphCsr; /* Partition buffer or Peer buffer */
+ int regAccum;
+ int regResult;
+ int csrApp; /* Function cursor (used by min/max) */
+ int regApp; /* Function register (also used by min/max) */
+ int regPart; /* First in a set of registers holding PARTITION BY
+ ** and ORDER BY values for the window */
+ Expr *pOwner; /* Expression object this window is attached to */
+ int nBufferCol; /* Number of columns in buffer table */
+ int iArgCol; /* Offset of first argument for this function */
+};
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
+SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p);
+SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
+SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
+SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*);
+SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
+SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
+SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*);
+SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
+SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
+SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
+SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
+SQLITE_PRIVATE void sqlite3WindowFunctions(void);
+#else
+# define sqlite3WindowDelete(a,b)
+# define sqlite3WindowFunctions()
+# define sqlite3WindowAttach(a,b,c)
+#endif
+
+/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
@@ -17252,6 +18359,7 @@ struct TreeView {
** using sqlite3_log(). The routines also provide a convenient place
** to set a debugger breakpoint.
*/
+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType);
SQLITE_PRIVATE int sqlite3CorruptError(int);
SQLITE_PRIVATE int sqlite3MisuseError(int);
SQLITE_PRIVATE int sqlite3CantopenError(int);
@@ -17321,9 +18429,7 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# 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);
-#endif
/*
** Internal function prototypes
@@ -17342,6 +18448,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, size_t);
SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, size_t);
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
SQLITE_PRIVATE void *sqlite3Realloc(void*, size_t);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, size_t);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, size_t);
@@ -17413,6 +18520,12 @@ SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*);
SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
+#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
+#else
+# define sqlite3MutexWarnOnContention(x)
+#endif
+
#ifndef SQLITE_OMIT_FLOATING_POINT
SQLITE_PRIVATE int sqlite3IsNaN(double);
#else
@@ -17429,8 +18542,6 @@ struct PrintfArguments {
sqlite3_value **apArg; /* The argument values */
};
-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list);
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
@@ -17446,6 +18557,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, co
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
+SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
+#endif
#endif
@@ -17470,18 +18585,19 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
+SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
#ifndef SQLITE_OMIT_VIRTUALTABLE
SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
@@ -17507,7 +18623,7 @@ 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 sqlite3AddDefaultValue(Parse*,ExprSpan*);
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
@@ -17531,8 +18647,9 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
#endif
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*);
+SQLITE_PRIVATE void sqlite3RowSetDelete(void*);
+SQLITE_PRIVATE void sqlite3RowSetClear(void*);
SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
@@ -17551,6 +18668,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask);
SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
+SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
#ifndef SQLITE_OMIT_AUTOINCREMENT
SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
@@ -17558,9 +18676,9 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
+SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
+SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
@@ -17579,22 +18697,23 @@ SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,i
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*,u32,Expr*,Expr*);
+ Expr*,ExprList*,u32,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*,const char*);
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,const char*);
#endif
-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
+SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
+SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
+ Upsert*);
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
@@ -17604,15 +18723,8 @@ SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
@@ -17643,6 +18755,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
@@ -17660,6 +18773,8 @@ SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
+SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
+SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
@@ -17677,8 +18792,9 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
- u8,u8,int,int*,int*);
+ u8,u8,int,int*,int*,Upsert*);
#ifdef SQLITE_ENABLE_NULL_TRIM
SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
#else
@@ -17697,11 +18813,6 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
-#if SELECTTRACE_ENABLED
-SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
-#else
-# define sqlite3SelectSetName(A,B)
-#endif
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
@@ -17712,7 +18823,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
+SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
#endif
#ifndef SQLITE_OMIT_TRIGGER
@@ -17728,11 +18839,15 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, i
SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- Select*,u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
+ const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
+ Select*,u8,Upsert*,
+ const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8,
+ const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
+ const char*,const char*);
SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
@@ -17839,9 +18954,14 @@ SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
SQLITE_PRIVATE const char *sqlite3ErrName(int);
#endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+SQLITE_PRIVATE int sqlite3MemdbInit(void);
+#endif
+
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
+SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
@@ -17887,13 +19007,17 @@ SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
SQLITE_PRIVATE int sqlite3PendingByte;
#endif
#endif
+#ifdef VDBE_PROFILE
+SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt;
+#endif
SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int);
SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
SQLITE_PRIVATE void sqlite3AlterFunctions(void);
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
+SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
+SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
@@ -17906,10 +19030,14 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
+SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*);
+SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
+SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
+SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
-SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*);
+SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
@@ -17924,25 +19052,27 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
+
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
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*),
+ void (*)(sqlite3_context*,int,sqlite3_value **),
+ void (*)(sqlite3_context*),
+ void (*)(sqlite3_context*),
+ void (*)(sqlite3_context*,int,sqlite3_value **),
FuncDestructor *pDestructor
);
+SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
@@ -17969,10 +19099,11 @@ SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
** The interface to the LEMON-generated parser
*/
#ifndef SQLITE_AMALGAMATION
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t), Parse*);
SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
#endif
-SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
+SQLITE_PRIVATE void sqlite3Parser(void*, int, Token);
+SQLITE_PRIVATE int sqlite3ParserFallback(int);
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
#endif
@@ -18038,7 +19169,6 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
-SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
@@ -18060,6 +19190,18 @@ SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8);
#define sqlite3WithPush(x,y,z)
#define sqlite3WithDelete(x,y)
#endif
+#ifndef SQLITE_OMIT_UPSERT
+SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*);
+SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
+SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
+SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
+#else
+#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0)
+#define sqlite3UpsertDelete(x,y)
+#define sqlite3UpsertDup(x,y) ((Upsert*)0)
+#endif
+
/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
@@ -18162,6 +19304,9 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
#endif
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*);
+#endif
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
@@ -18489,7 +19634,8 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xTestCallback */
0, /* bLocaltimeFault */
#endif
- 0x7ffffffe /* iOnceResetThreshold */
+ 0x7ffffffe, /* iOnceResetThreshold */
+ SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
};
/*
@@ -18507,6 +19653,13 @@ SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
{ "1", 1 }
};
+#ifdef VDBE_PROFILE
+/*
+** The following performance counter can be used in place of
+** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
+*/
+SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0;
+#endif
/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
@@ -18651,6 +19804,7 @@ struct VdbeCursor {
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
+ Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */
Btree *pBtx; /* Separate file holding temporary table */
i64 seqCount; /* Sequence counter */
int *aAltMap; /* Mapping from table to index column numbers */
@@ -18734,6 +19888,9 @@ struct VdbeFrame {
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
AuxData *pAuxData; /* Linked list of auxdata allocations */
+#if SQLITE_DEBUG
+ u32 iFrameMagic; /* magic number for sanity checking */
+#endif
int nCursor; /* Number of entries in apCsr */
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
@@ -18744,6 +19901,13 @@ struct VdbeFrame {
u64 nDbChange; /* Value of db->nChange */
};
+/* Magic number for sanity checking on VdbeFrame objects */
+#define SQLITE_FRAME_MAGIC 0x879fb71e
+
+/*
+** Return a pointer to the array of registers allocated for use
+** by a VdbeFrame.
+*/
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
/*
@@ -18758,8 +19922,6 @@ struct sqlite3_value {
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
FuncDef *pDef; /* Used only when flags==MEM_Agg */
- RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
- VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
} u;
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
@@ -18774,7 +19936,7 @@ struct sqlite3_value {
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
- void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
+ u16 mScopyFlags; /* flags value immediately after the shallow copy */
#endif
};
@@ -18803,8 +19965,8 @@ struct sqlite3_value {
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
-#define MEM_RowSet 0x0020 /* Value is a RowSet object */
-#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
+/* Available 0x0020 */
+/* Available 0x0040 */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0xc1ff /* Mask of type bits */
@@ -18831,7 +19993,7 @@ struct sqlite3_value {
** that needs to be deallocated to avoid a leak.
*/
#define VdbeMemDynamic(X) \
- (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
+ (((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
/*
** Clear any existing type flags from a Mem and replace them with f
@@ -18883,7 +20045,6 @@ struct sqlite3_context {
int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
u8 skipFlag; /* Skip accumulator loading if true */
- u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
u8 argc; /* Number of arguments */
sqlite3_value *argv[1]; /* Argument set */
};
@@ -18946,14 +20107,15 @@ struct Vdbe {
int nOp; /* Number of instructions in the program */
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
+ u32 nWrite; /* Number of write operations that have occurred */
#endif
u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
- bft expired:1; /* True if the VM needs to be recompiled */
- bft doingRerun:1; /* True if rerunning after an auto-reprepare */
+ bft expired:2; /* 1: recompile VM immediately 2: when convenient */
bft explain:2; /* True if EXPLAIN present on SQL command */
+ bft doingRerun:1; /* True if rerunning after an auto-reprepare */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -19014,9 +20176,6 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
-#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
@@ -19047,12 +20206,16 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(v
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
+#endif
+SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
@@ -19060,11 +20223,18 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
+#endif
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
+#endif
+SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */
+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
@@ -19080,6 +20250,14 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*);
+SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*);
+#else
+# define sqlite3VdbeIncrWriteCounter(V,C)
+# define sqlite3VdbeAssertAbortable(V)
+#endif
+
#if !defined(SQLITE_OMIT_SHARED_CACHE)
SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
#else
@@ -19437,6 +20615,9 @@ SQLITE_API int sqlite3_db_status(
** pagers the database handle is connected to. *pHighwater is always set
** to zero.
*/
+ case SQLITE_DBSTATUS_CACHE_SPILL:
+ op = SQLITE_DBSTATUS_CACHE_WRITE+1;
+ /* Fall through into the next case */
case SQLITE_DBSTATUS_CACHE_HIT:
case SQLITE_DBSTATUS_CACHE_MISS:
case SQLITE_DBSTATUS_CACHE_WRITE:{
@@ -19519,7 +20700,7 @@ SQLITE_API int sqlite3_db_status(
**
** Jean Meeus
** Astronomical Algorithms, 2nd Edition, 1998
-** ISBM 0-943396-61-1
+** ISBN 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
@@ -20868,8 +22049,11 @@ SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
** routine has no return value since the return value would be meaningless.
*/
SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
+ if( id->pMethods==0 ) return SQLITE_NOTFOUND;
#ifdef SQLITE_TEST
- if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+ if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
+ && op!=SQLITE_FCNTL_LOCK_TIMEOUT
+ ){
/* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
** is using a regular VFS, it is called after the corresponding
** transaction has been committed. Injecting a fault at this point
@@ -20886,7 +22070,7 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
return id->pMethods->xFileControl(id, op, pArg);
}
SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
- (void)id->pMethods->xFileControl(id, op, pArg);
+ if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg);
}
SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
@@ -21150,9 +22334,12 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
** Unregister a VFS so that it is no longer accessible.
*/
SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ MUTEX_LOGIC(sqlite3_mutex *mutex;)
+#ifndef SQLITE_OMIT_AUTOINIT
+ int rc = sqlite3_initialize();
+ if( rc ) return rc;
#endif
+ MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
sqlite3_mutex_leave(mutex);
@@ -23444,6 +24631,193 @@ static SQLITE_WSD int mutexIsInit = 0;
#ifndef SQLITE_MUTEX_OMIT
+
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+/*
+** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
+** the implementation of a wrapper around the system default mutex
+** implementation (sqlite3DefaultMutex()).
+**
+** Most calls are passed directly through to the underlying default
+** mutex implementation. Except, if a mutex is configured by calling
+** sqlite3MutexWarnOnContention() on it, then if contention is ever
+** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
+**
+** This type of mutex is used as the database handle mutex when testing
+** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
+*/
+
+/*
+** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
+** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
+** allocated by the system mutex implementation. Variable iType is usually set
+** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
+** or one of the static mutex identifiers. Or, if this is a recursive mutex
+** that has been configured using sqlite3MutexWarnOnContention(), it is
+** set to SQLITE_MUTEX_WARNONCONTENTION.
+*/
+typedef struct CheckMutex CheckMutex;
+struct CheckMutex {
+ int iType;
+ sqlite3_mutex *mutex;
+};
+
+#define SQLITE_MUTEX_WARNONCONTENTION (-1)
+
+/*
+** Pointer to real mutex methods object used by the CheckMutex
+** implementation. Set by checkMutexInit().
+*/
+static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
+
+#ifdef SQLITE_DEBUG
+static int checkMutexHeld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
+}
+static int checkMutexNotheld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
+}
+#endif
+
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int checkMutexInit(void){
+ pGlobalMutexMethods = sqlite3DefaultMutex();
+ return SQLITE_OK;
+}
+static int checkMutexEnd(void){
+ pGlobalMutexMethods = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Allocate a mutex.
+*/
+static sqlite3_mutex *checkMutexAlloc(int iType){
+ static CheckMutex staticMutexes[] = {
+ {2, 0}, {3, 0}, {4, 0}, {5, 0},
+ {6, 0}, {7, 0}, {8, 0}, {9, 0},
+ {10, 0}, {11, 0}, {12, 0}, {13, 0}
+ };
+ CheckMutex *p = 0;
+
+ assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
+ if( iType<2 ){
+ p = sqlite3MallocZero(sizeof(CheckMutex));
+ if( p==0 ) return 0;
+ p->iType = iType;
+ }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( iType-2>=ArraySize(staticMutexes) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ p = &staticMutexes[iType-2];
+ }
+
+ if( p->mutex==0 ){
+ p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
+ if( p->mutex==0 ){
+ if( iType<2 ){
+ sqlite3_free(p);
+ }
+ p = 0;
+ }
+ }
+
+ return (sqlite3_mutex*)p;
+}
+
+/*
+** Free a mutex.
+*/
+static void checkMutexFree(sqlite3_mutex *p){
+ assert( SQLITE_MUTEX_RECURSIVE<2 );
+ assert( SQLITE_MUTEX_FAST<2 );
+ assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
+
+#if SQLITE_ENABLE_API_ARMOR
+ if( ((CheckMutex*)p)->iType<2 )
+#endif
+ {
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexFree(pCheck->mutex);
+ sqlite3_free(pCheck);
+ }
+#ifdef SQLITE_ENABLE_API_ARMOR
+ else{
+ (void)SQLITE_MISUSE_BKPT;
+ }
+#endif
+}
+
+/*
+** Enter the mutex.
+*/
+static void checkMutexEnter(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
+ if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
+ return;
+ }
+ sqlite3_log(SQLITE_MISUSE,
+ "illegal multi-threaded access to database connection"
+ );
+ }
+ pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
+}
+
+/*
+** Enter the mutex (do not block).
+*/
+static int checkMutexTry(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
+}
+
+/*
+** Leave the mutex.
+*/
+static void checkMutexLeave(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
+}
+
+sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
+ static const sqlite3_mutex_methods sMutex = {
+ checkMutexInit,
+ checkMutexEnd,
+ checkMutexAlloc,
+ checkMutexFree,
+ checkMutexEnter,
+ checkMutexTry,
+ checkMutexLeave,
+#ifdef SQLITE_DEBUG
+ checkMutexHeld,
+ checkMutexNotheld
+#else
+ 0,
+ 0
+#endif
+ };
+ return &sMutex;
+}
+
+/*
+** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
+** one on which there should be no contention.
+*/
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
+ if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
+ pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
+ }
+}
+#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
+
/*
** Initialize the mutex system.
*/
@@ -23459,7 +24833,11 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
if( sqlite3GlobalConfig.bCoreMutex ){
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ pFrom = multiThreadedCheckMutex();
+#else
pFrom = sqlite3DefaultMutex();
+#endif
}else{
pFrom = sqlite3NoopMutex();
}
@@ -23858,11 +25236,12 @@ struct sqlite3_mutex {
#endif
};
#if SQLITE_MUTEX_NREF
-#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
+# define SQLITE3_MUTEX_INITIALIZER(id) \
+ {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
#elif defined(SQLITE_ENABLE_API_ARMOR)
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
+# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
#else
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
#endif
/*
@@ -23959,18 +25338,18 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
*/
static sqlite3_mutex *pthreadMutexAlloc(int iType){
static sqlite3_mutex staticMutexes[] = {
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER
+ SQLITE3_MUTEX_INITIALIZER(2),
+ SQLITE3_MUTEX_INITIALIZER(3),
+ SQLITE3_MUTEX_INITIALIZER(4),
+ SQLITE3_MUTEX_INITIALIZER(5),
+ SQLITE3_MUTEX_INITIALIZER(6),
+ SQLITE3_MUTEX_INITIALIZER(7),
+ SQLITE3_MUTEX_INITIALIZER(8),
+ SQLITE3_MUTEX_INITIALIZER(9),
+ SQLITE3_MUTEX_INITIALIZER(10),
+ SQLITE3_MUTEX_INITIALIZER(11),
+ SQLITE3_MUTEX_INITIALIZER(12),
+ SQLITE3_MUTEX_INITIALIZER(13)
};
sqlite3_mutex *p;
switch( iType ){
@@ -23989,6 +25368,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
pthread_mutex_init(&p->mutex, &recursiveAttr);
pthread_mutexattr_destroy(&recursiveAttr);
#endif
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
+ p->id = SQLITE_MUTEX_RECURSIVE;
+#endif
}
break;
}
@@ -23996,6 +25378,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
pthread_mutex_init(&p->mutex, 0);
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
+ p->id = SQLITE_MUTEX_FAST;
+#endif
}
break;
}
@@ -24011,7 +25396,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
}
}
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
- if( p ) p->id = iType;
+ assert( p==0 || p->id==iType );
#endif
return p;
}
@@ -24528,7 +25913,7 @@ struct sqlite3_mutex {
#ifdef SQLITE_DEBUG
volatile int nRef; /* Number of enterances */
volatile DWORD owner; /* Thread holding this mutex */
- volatile int trace; /* True to trace changes */
+ volatile LONG trace; /* True to trace changes */
#endif
};
@@ -24540,10 +25925,10 @@ struct sqlite3_mutex {
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
#ifdef SQLITE_DEBUG
-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
+#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
0L, (DWORD)0, 0 }
#else
-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
+#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
#endif
#ifdef SQLITE_DEBUG
@@ -24586,18 +25971,18 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER
+ SQLITE3_MUTEX_INITIALIZER(2),
+ SQLITE3_MUTEX_INITIALIZER(3),
+ SQLITE3_MUTEX_INITIALIZER(4),
+ SQLITE3_MUTEX_INITIALIZER(5),
+ SQLITE3_MUTEX_INITIALIZER(6),
+ SQLITE3_MUTEX_INITIALIZER(7),
+ SQLITE3_MUTEX_INITIALIZER(8),
+ SQLITE3_MUTEX_INITIALIZER(9),
+ SQLITE3_MUTEX_INITIALIZER(10),
+ SQLITE3_MUTEX_INITIALIZER(11),
+ SQLITE3_MUTEX_INITIALIZER(12),
+ SQLITE3_MUTEX_INITIALIZER(13)
};
static int winMutex_isInit = 0;
@@ -24727,15 +26112,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
}
#endif
p = &winMutex_staticMutexes[iType-2];
- p->id = iType;
#ifdef SQLITE_DEBUG
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
- p->trace = 1;
+ InterlockedCompareExchange(&p->trace, 1, 0);
#endif
#endif
break;
}
}
+ assert( p==0 || p->id==iType );
return p;
}
@@ -25534,6 +26919,19 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, size_t n){
}
/*
+** The text between zStart and zEnd represents a phrase within a larger
+** SQL statement. Make a copy of this phrase in space obtained form
+** sqlite3DbMalloc(). Omit leading and trailing whitespace.
+*/
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ int n;
+ while( sqlite3Isspace(zStart[0]) ) zStart++;
+ n = (int)(zEnd - zStart);
+ while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
+ return sqlite3DbStrNDup(db, zStart, n);
+}
+
+/*
** Free any prior content in *pz and replace it with a copy of zNew.
*/
SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
@@ -25745,7 +27143,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
** Set the StrAccum object to an error mode.
*/
static void setStrAccumError(StrAccum *p, u8 eError){
- assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
+ assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
p->accError = eError;
p->nAlloc = 0;
}
@@ -25779,8 +27177,8 @@ static char *getTextArg(PrintfArguments *p){
/*
** Render a string given by "fmt" into the StrAccum object.
*/
-SQLITE_PRIVATE void sqlite3VXPrintf(
- StrAccum *pAccum, /* Accumulate results here */
+SQLITE_API void sqlite3_str_vappendf(
+ sqlite3_str *pAccum, /* Accumulate results here */
const char *fmt, /* Format string */
va_list ap /* arguments */
){
@@ -25817,6 +27215,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
+ /* pAccum never starts out with an empty buffer that was obtained from
+ ** malloc(). This precondition is required by the mprintf("%z...")
+ ** optimization. */
+ assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
+
bufpt = 0;
if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
pArgList = va_arg(ap, PrintfArguments*);
@@ -25832,11 +27235,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
#else
do{ fmt++; }while( *fmt && *fmt != '%' );
#endif
- sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
+ sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
if( *fmt==0 ) break;
}
if( (c=(*++fmt))==0 ){
- sqlite3StrAccumAppend(pAccum, "%", 1);
+ sqlite3_str_append(pAccum, "%", 1);
break;
}
/* Find out what flags are present */
@@ -26024,7 +27427,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
u64 n = (u64)precision + 10 + precision/3;
zOut = zExtra = sqlite3Malloc( n );
if( zOut==0 ){
- setStrAccumError(pAccum, STRACCUM_NOMEM);
+ setStrAccumError(pAccum, SQLITE_NOMEM);
return;
}
nOut = (int)n;
@@ -26151,7 +27554,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
bufpt = zExtra
= sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
if( bufpt==0 ){
- setStrAccumError(pAccum, STRACCUM_NOMEM);
+ setStrAccumError(pAccum, SQLITE_NOMEM);
return;
}
}
@@ -26247,22 +27650,52 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
case etCHARX:
if( bArgList ){
bufpt = getTextArg(pArgList);
- c = bufpt ? bufpt[0] : 0;
+ length = 1;
+ if( bufpt ){
+ buf[0] = c = *(bufpt++);
+ if( (c&0xc0)==0xc0 ){
+ while( length<4 && (bufpt[0]&0xc0)==0x80 ){
+ buf[length++] = *(bufpt++);
+ }
+ }
+ }else{
+ buf[0] = 0;
+ }
}else{
- c = va_arg(ap,int);
+ unsigned int ch = va_arg(ap,unsigned int);
+ if( ch<0x00080 ){
+ buf[0] = ch & 0xff;
+ length = 1;
+ }else if( ch<0x00800 ){
+ buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
+ buf[1] = 0x80 + (u8)(ch & 0x3f);
+ length = 2;
+ }else if( ch<0x10000 ){
+ buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
+ buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
+ buf[2] = 0x80 + (u8)(ch & 0x3f);
+ length = 3;
+ }else{
+ buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
+ buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
+ buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
+ buf[3] = 0x80 + (u8)(ch & 0x3f);
+ length = 4;
+ }
}
if( precision>1 ){
width -= precision-1;
if( width>1 && !flag_leftjustify ){
- sqlite3AppendChar(pAccum, width-1, ' ');
+ sqlite3_str_appendchar(pAccum, width-1, ' ');
width = 0;
}
- sqlite3AppendChar(pAccum, precision-1, c);
+ while( precision-- > 1 ){
+ sqlite3_str_append(pAccum, buf, length);
+ }
}
- length = 1;
- buf[0] = c;
bufpt = buf;
- break;
+ flag_altform2 = 1;
+ goto adjust_width_for_utf8;
case etSTRING:
case etDYNSTRING:
if( bArgList ){
@@ -26274,17 +27707,50 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( bufpt==0 ){
bufpt = (char *)"";
}else if( xtype==etDYNSTRING ){
+ if( pAccum->nChar==0
+ && pAccum->mxAlloc
+ && width==0
+ && precision<0
+ && pAccum->accError==0
+ ){
+ /* Special optimization for sqlite3_mprintf("%z..."):
+ ** Extend an existing memory allocation rather than creating
+ ** a new one. */
+ assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
+ pAccum->zText = bufpt;
+ pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
+ pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
+ pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
+ length = 0;
+ break;
+ }
zExtra = bufpt;
}
if( precision>=0 ){
- for(length=0; length<precision && bufpt[length]; length++){}
+ if( flag_altform2 ){
+ /* Set length to the number of bytes needed in order to display
+ ** precision characters */
+ unsigned char *z = (unsigned char*)bufpt;
+ while( precision-- > 0 && z[0] ){
+ SQLITE_SKIP_UTF8(z);
+ }
+ length = (int)(z - (unsigned char*)bufpt);
+ }else{
+ for(length=0; length<precision && bufpt[length]; length++){}
+ }
}else{
length = 0x7fffffff & (int)strlen(bufpt);
}
+ adjust_width_for_utf8:
+ if( flag_altform2 && width>0 ){
+ /* Adjust width to account for extra bytes in UTF-8 characters */
+ int ii = length - 1;
+ while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
+ }
break;
- case etSQLESCAPE: /* Escape ' characters */
- case etSQLESCAPE2: /* Escape ' and enclose in '...' */
- case etSQLESCAPE3: { /* Escape " characters */
+ case etSQLESCAPE: /* %q: Escape ' characters */
+ case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */
+ case etSQLESCAPE3: { /* %w: Escape " characters */
int i, j, k, n, isnull;
int needQuote;
char ch;
@@ -26298,16 +27764,24 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
+ /* For %q, %Q, and %w, the precision is the number of byte (or
+ ** characters if the ! flags is present) to use from the input.
+ ** Because of the extra quoting characters inserted, the number
+ ** of output characters may be larger than the precision.
+ */
k = precision;
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
if( ch==q ) n++;
+ if( flag_altform2 && (ch&0xc0)==0xc0 ){
+ while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
+ }
}
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 3;
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
- setStrAccumError(pAccum, STRACCUM_NOMEM);
+ setStrAccumError(pAccum, SQLITE_NOMEM);
return;
}
}else{
@@ -26323,10 +27797,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0;
length = j;
- /* The precision in %q and %Q means how many input characters to
- ** consume, not the length of the output...
- ** if( precision>=0 && precision<length ) length = precision; */
- break;
+ goto adjust_width_for_utf8;
}
case etTOKEN: {
Token *pToken;
@@ -26334,7 +27805,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
pToken = va_arg(ap, Token*);
assert( bArgList==0 );
if( pToken && pToken->n ){
- sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
+ sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
}
length = width = 0;
break;
@@ -26350,10 +27821,10 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
- sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
- sqlite3StrAccumAppend(pAccum, ".", 1);
+ sqlite3_str_appendall(pAccum, pItem->zDatabase);
+ sqlite3_str_append(pAccum, ".", 1);
}
- sqlite3StrAccumAppendAll(pAccum, pItem->zName);
+ sqlite3_str_appendall(pAccum, pItem->zName);
length = width = 0;
break;
}
@@ -26365,15 +27836,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
/*
** The text of the conversion is pointed to by "bufpt" and is
** "length" characters long. The field width is "width". Do
- ** the output.
+ ** the output. Both length and width are in bytes, not characters,
+ ** at this point. If the "!" flag was present on string conversions
+ ** indicating that width and precision should be expressed in characters,
+ ** then the values have been translated prior to reaching this point.
*/
width -= length;
if( width>0 ){
- if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
- sqlite3StrAccumAppend(pAccum, bufpt, length);
- if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+ if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
+ sqlite3_str_append(pAccum, bufpt, length);
+ if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
}else{
- sqlite3StrAccumAppend(pAccum, bufpt, length);
+ sqlite3_str_append(pAccum, bufpt, length);
}
if( zExtra ){
@@ -26394,13 +27868,13 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
- testcase(p->accError==STRACCUM_TOOBIG);
- testcase(p->accError==STRACCUM_NOMEM);
+ testcase(p->accError==SQLITE_TOOBIG);
+ testcase(p->accError==SQLITE_NOMEM);
return 0;
}
if( p->mxAlloc==0 ){
N = p->nAlloc - p->nChar - 1;
- setStrAccumError(p, STRACCUM_TOOBIG);
+ setStrAccumError(p, SQLITE_TOOBIG);
return N;
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
@@ -26412,8 +27886,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
szNew += p->nChar;
}
if( szNew > p->mxAlloc ){
- sqlite3StrAccumReset(p);
- setStrAccumError(p, STRACCUM_TOOBIG);
+ sqlite3_str_reset(p);
+ setStrAccumError(p, SQLITE_TOOBIG);
return 0;
}else{
p->nAlloc = (int)szNew;
@@ -26430,8 +27904,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
- sqlite3StrAccumReset(p);
- setStrAccumError(p, STRACCUM_NOMEM);
+ sqlite3_str_reset(p);
+ setStrAccumError(p, SQLITE_NOMEM);
return 0;
}
}
@@ -26441,7 +27915,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
/*
** Append N copies of character c to the given string buffer.
*/
-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
+SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
testcase( p->nChar + (i64)N > 0x7fffffff );
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
@@ -26453,9 +27927,9 @@ SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
-** This is a helper routine to sqlite3StrAccumAppend() that does special-case
+** This is a helper routine to sqlite3_str_append() that does special-case
** work (enlarging the buffer) using tail recursion, so that the
-** sqlite3StrAccumAppend() routine can use fast calling semantics.
+** sqlite3_str_append() routine can use fast calling semantics.
*/
static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
N = sqlite3StrAccumEnlarge(p, N);
@@ -26469,7 +27943,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
+SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
assert( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
@@ -26486,8 +27960,8 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
/*
** Append the complete text of zero-terminated string z[] to the p string.
*/
-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
- sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
+SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){
+ sqlite3_str_append(p, z, sqlite3Strlen30(z));
}
@@ -26504,7 +27978,7 @@ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
memcpy(zText, p->zText, p->nChar+1);
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
- setStrAccumError(p, STRACCUM_NOMEM);
+ setStrAccumError(p, SQLITE_NOMEM);
}
p->zText = zText;
return zText;
@@ -26520,13 +27994,55 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
}
/*
+** This singleton is an sqlite3_str object that is returned if
+** sqlite3_malloc() fails to provide space for a real one. This
+** sqlite3_str object accepts no new text and always returns
+** an SQLITE_NOMEM error.
+*/
+static sqlite3_str sqlite3OomStr = {
+ 0, 0, 0, 0, 0, SQLITE_NOMEM, 0
+};
+
+/* Finalize a string created using sqlite3_str_new().
+*/
+SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){
+ char *z;
+ if( p!=0 && p!=&sqlite3OomStr ){
+ z = sqlite3StrAccumFinish(p);
+ sqlite3_free(p);
+ }else{
+ z = 0;
+ }
+ return z;
+}
+
+/* Return any error code associated with p */
+SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){
+ return p ? p->accError : SQLITE_NOMEM;
+}
+
+/* Return the current length of p in bytes */
+SQLITE_API int sqlite3_str_length(sqlite3_str *p){
+ return p ? p->nChar : 0;
+}
+
+/* Return the current value for p */
+SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
+ if( p==0 || p->nChar==0 ) return 0;
+ p->zText[p->nChar] = 0;
+ return p->zText;
+}
+
+/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
+SQLITE_API void sqlite3_str_reset(StrAccum *p){
if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
}
+ p->nAlloc = 0;
+ p->nChar = 0;
p->zText = 0;
}
@@ -26554,6 +28070,18 @@ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, i
p->printfFlags = 0;
}
+/* Allocate and initialize a new dynamic string object */
+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){
+ sqlite3_str *p = sqlite3_malloc64(sizeof(*p));
+ if( p ){
+ sqlite3StrAccumInit(p, 0, 0, 0,
+ db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
+ }else{
+ p = &sqlite3OomStr;
+ }
+ return p;
+}
+
/*
** Print into memory obtained from sqliteMalloc(). Use the internal
** %-conversion extensions.
@@ -26566,9 +28094,9 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
acc.printfFlags = SQLITE_PRINTF_INTERNAL;
- sqlite3VXPrintf(&acc, zFormat, ap);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
- if( acc.accError==STRACCUM_NOMEM ){
+ if( acc.accError==SQLITE_NOMEM ){
sqlite3OomFault(db);
}
return z;
@@ -26606,7 +28134,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
if( sqlite3_initialize() ) return 0;
#endif
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
- sqlite3VXPrintf(&acc, zFormat, ap);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
return z;
}
@@ -26651,7 +28179,7 @@ SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_li
}
#endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
- sqlite3VXPrintf(&acc, zFormat, ap);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
zBuf[acc.nChar] = 0;
return zBuf;
}
@@ -26673,7 +28201,7 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
** allocate memory because it might be called while the memory allocator
** mutex is held.
**
-** sqlite3VXPrintf() might ask for *temporary* memory allocations for
+** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
** certain format characters (%q) or for very large precisions or widths.
** Care must be taken that any sqlite3_log() calls that occur while the
** memory mutex is held do not use these mechanisms.
@@ -26683,7 +28211,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
- sqlite3VXPrintf(&acc, zFormat, ap);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
}
@@ -26712,23 +28240,30 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
char zBuf[500];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
- sqlite3VXPrintf(&acc, zFormat, ap);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
+#ifdef SQLITE_OS_TRACE_PROC
+ {
+ extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
+ SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
+ }
+#else
fprintf(stdout,"%s", zBuf);
fflush(stdout);
+#endif
}
#endif
/*
-** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument
+** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
*/
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
+SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
- sqlite3VXPrintf(p, zFormat, ap);
+ sqlite3_str_vappendf(p, zFormat, ap);
va_end(ap);
}
@@ -26794,15 +28329,17 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
if( p ){
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
- sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
+ sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
}
- sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+ sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+ }
+ if( zFormat!=0 ){
+ va_start(ap, zFormat);
+ sqlite3_str_vappendf(&acc, zFormat, ap);
+ va_end(ap);
+ assert( acc.nChar>0 );
+ sqlite3_str_append(&acc, "\n", 1);
}
- va_start(ap, zFormat);
- sqlite3VXPrintf(&acc, zFormat, ap);
- va_end(ap);
- assert( acc.nChar>0 );
- if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
fflush(stdout);
@@ -26835,17 +28372,17 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
char zLine[1000];
const struct Cte *pCte = &pWith->a[i];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3XPrintf(&x, "%s", pCte->zName);
+ sqlite3_str_appendf(&x, "%s", pCte->zName);
if( pCte->pCols && pCte->pCols->nExpr>0 ){
char cSep = '(';
int j;
for(j=0; j<pCte->pCols->nExpr; j++){
- sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
+ sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
cSep = ',';
}
- sqlite3XPrintf(&x, ")");
+ sqlite3_str_appendf(&x, ")");
}
- sqlite3XPrintf(&x, " AS");
+ sqlite3_str_appendf(&x, " AS");
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
@@ -26873,9 +28410,11 @@ 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 nSelectRow=%d",
+ sqlite3TreeViewLine(pView,
+ "SELECT%s%s (%u/%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->selId, p, p->selFlags,
(int)p->nSelectRow
);
if( cnt++ ) sqlite3TreeViewPop(pView);
@@ -26889,9 +28428,23 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
if( p->pHaving ) n++;
if( p->pOrderBy ) n++;
if( p->pLimit ) n++;
- if( p->pOffset ) n++;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWin ) n++;
+ if( p->pWinDefn ) n++;
+#endif
}
sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWin ){
+ Window *pX;
+ pView = sqlite3TreeViewPush(pView, (n--)>0);
+ sqlite3TreeViewLine(pView, "window-functions");
+ for(pX=p->pWin; pX; pX=pX->pNextWin){
+ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+#endif
if( p->pSrc && p->pSrc->nSrc ){
int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
@@ -26901,20 +28454,20 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
+ sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
- sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
+ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
- sqlite3XPrintf(&x, " %s", pItem->zName);
+ sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
- sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
+ sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
}
if( pItem->zAlias ){
- sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
+ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
}
if( pItem->fg.jointype & JT_LEFT ){
- sqlite3XPrintf(&x, " LEFT-JOIN");
+ sqlite3_str_appendf(&x, " LEFT-JOIN");
}
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1);
@@ -26941,17 +28494,27 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewExpr(pView, p->pHaving, 0);
sqlite3TreeViewPop(pView);
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWinDefn ){
+ Window *pX;
+ sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
+ for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
+ sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
+ }
+ sqlite3TreeViewPop(pView);
+ }
+#endif
if( p->pOrderBy ){
sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
}
if( p->pLimit ){
sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pLimit, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pOffset ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pOffset, 0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
+ if( p->pLimit->pRight ){
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
+ sqlite3TreeViewPop(pView);
+ }
sqlite3TreeViewPop(pView);
}
if( p->pPrior ){
@@ -26968,6 +28531,83 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewPop(pView);
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a description of starting or stopping bounds
+*/
+SQLITE_PRIVATE void sqlite3TreeViewBound(
+ TreeView *pView, /* View context */
+ u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
+ Expr *pExpr, /* Value for PRECEDING or FOLLOWING */
+ u8 moreToFollow /* True if more to follow */
+){
+ switch( eBound ){
+ case TK_UNBOUNDED: {
+ sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
+ sqlite3TreeViewPop(pView);
+ break;
+ }
+ case TK_CURRENT: {
+ sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
+ sqlite3TreeViewPop(pView);
+ break;
+ }
+ case TK_PRECEDING: {
+ sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
+ sqlite3TreeViewExpr(pView, pExpr, 0);
+ sqlite3TreeViewPop(pView);
+ break;
+ }
+ case TK_FOLLOWING: {
+ sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
+ sqlite3TreeViewExpr(pView, pExpr, 0);
+ sqlite3TreeViewPop(pView);
+ break;
+ }
+ }
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a human-readable explanation for a Window object
+*/
+SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+ pView = sqlite3TreeViewPush(pView, more);
+ if( pWin->zName ){
+ sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
+ }else{
+ sqlite3TreeViewLine(pView, "OVER");
+ }
+ if( pWin->pPartition ){
+ sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
+ }
+ if( pWin->pOrderBy ){
+ sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
+ }
+ if( pWin->eType ){
+ sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
+ sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
+ sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
+ sqlite3TreeViewPop(pView);
+ }
+ sqlite3TreeViewPop(pView);
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a human-readable explanation for a Window Function object
+*/
+SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
+ pView = sqlite3TreeViewPush(pView, more);
+ sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
+ pWin->pFunc->zName, pWin->pFunc->nArg);
+ sqlite3TreeViewWindow(pView, pWin, 0);
+ sqlite3TreeViewPop(pView);
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
/*
** Generate a human-readable explanation of an expression tree.
*/
@@ -27005,6 +28645,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewLine(pView, "{%d:%d}%s",
pExpr->iTable, pExpr->iColumn, zFlgs);
}
+ if( ExprHasProperty(pExpr, EP_FixedCol) ){
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+ }
break;
}
case TK_INTEGER: {
@@ -27029,6 +28672,11 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewLine(pView,"NULL");
break;
}
+ case TK_TRUEFALSE: {
+ sqlite3TreeViewLine(pView,
+ sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE");
+ break;
+ }
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
@@ -27085,6 +28733,19 @@ 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_TRUTH: {
+ int x;
+ const char *azOp[] = {
+ "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
+ };
+ assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
+ assert( pExpr->pRight );
+ assert( pExpr->pRight->op==TK_TRUEFALSE );
+ x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
+ zUniOp = azOp[x];
+ break;
+ }
+
case TK_SPAN: {
sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
@@ -27100,10 +28761,17 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
case TK_AGG_FUNCTION:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
+ Window *pWin;
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
+ pWin = 0;
}else{
pFarg = pExpr->x.pList;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ pWin = pExpr->pWin;
+#else
+ pWin = 0;
+#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
@@ -27112,8 +28780,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
}
if( pFarg ){
- sqlite3TreeViewExprList(pView, pFarg, 0, 0);
+ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
+ }
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pWin ){
+ sqlite3TreeViewWindow(pView, pWin, 0);
}
+#endif
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -27244,12 +28917,25 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
- if( j ){
- sqlite3TreeViewPush(pView, 0);
- sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
+ char *zName = pList->a[i].zName;
+ int moreToFollow = i<pList->nExpr - 1;
+ if( j || zName ){
+ sqlite3TreeViewPush(pView, moreToFollow);
+ moreToFollow = 0;
+ sqlite3TreeViewLine(pView, 0);
+ if( zName ){
+ fprintf(stdout, "AS %s ", zName);
+ }
+ if( j ){
+ fprintf(stdout, "iOrderByCol=%d", j);
+ }
+ fprintf(stdout, "\n");
+ fflush(stdout);
+ }
+ sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
+ if( j || zName ){
+ sqlite3TreeViewPop(pView);
}
- sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
- if( j ) sqlite3TreeViewPop(pView);
}
}
}
@@ -28538,6 +30224,45 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
}
/*
+** Compute 10 to the E-th power. Examples: E==1 results in 10.
+** E==2 results in 100. E==50 results in 1.0e50.
+**
+** This routine only works for values of E between 1 and 341.
+*/
+static LONGDOUBLE_TYPE sqlite3Pow10(int E){
+#if defined(_MSC_VER)
+ static const LONGDOUBLE_TYPE x[] = {
+ 1.0e+001,
+ 1.0e+002,
+ 1.0e+004,
+ 1.0e+008,
+ 1.0e+016,
+ 1.0e+032,
+ 1.0e+064,
+ 1.0e+128,
+ 1.0e+256
+ };
+ LONGDOUBLE_TYPE r = 1.0;
+ int i;
+ assert( E>=0 && E<=307 );
+ for(i=0; E!=0; i++, E >>=1){
+ if( E & 1 ) r *= x[i];
+ }
+ return r;
+#else
+ LONGDOUBLE_TYPE x = 10.0;
+ LONGDOUBLE_TYPE r = 1.0;
+ while(1){
+ if( E & 1 ) r *= x;
+ E >>= 1;
+ if( E==0 ) break;
+ x *= x;
+ }
+ return r;
+#endif
+}
+
+/*
** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
@@ -28604,12 +30329,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
/* copy max significant digits to significand */
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
- z+=incr, nDigits++;
+ z+=incr; nDigits++;
}
/* skip non-significant significand digits
** (increase exponent by d to shift decimal left) */
- while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
+ while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
if( z>=zEnd ) goto do_atof_calc;
/* if decimal point is present */
@@ -28622,7 +30347,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
s = s*10 + (*z - '0');
d--;
}
- z+=incr, nDigits++;
+ z+=incr; nDigits++;
}
}
if( z>=zEnd ) goto do_atof_calc;
@@ -28692,11 +30417,10 @@ do_atof_calc:
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 ){ /*OPTIMIZATION-IF-TRUE*/
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
- while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
@@ -28716,10 +30440,7 @@ do_atof_calc:
}
}
}else{
- /* 1.0e+22 is the largest power of 10 than can be
- ** represented exactly. */
- while( e%22 ) { scale *= 1.0e+1; e -= 1; }
- while( e>0 ) { scale *= 1.0e+22; e -= 22; }
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
if( esign<0 ){
result = s / scale;
}else{
@@ -28777,7 +30498,7 @@ static int compare2pow63(const char *zNum, int incr){
** Returns:
**
** 0 Successful transformation. Fits in a 64-bit signed integer.
-** 1 Excess text after the integer value
+** 1 Excess non-space text after the integer value
** 2 Integer too large for a 64-bit signed integer or is malformed
** 3 Special case of 9223372036854775808
**
@@ -28820,47 +30541,57 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
u = u*10 + c - '0';
}
+ testcase( i==18*incr );
+ testcase( i==19*incr );
+ testcase( i==20*incr );
if( u>LARGEST_INT64 ){
+ /* This test and assignment is needed only to suppress UB warnings
+ ** from clang and -fsanitize=undefined. This test and assignment make
+ ** the code a little larger and slower, and no harm comes from omitting
+ ** them, but we must appaise the undefined-behavior pharisees. */
*pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
*pNum = (i64)u;
}
- testcase( i==18 );
- testcase( i==19 );
- testcase( i==20 );
- if( &zNum[i]<zEnd /* Extra bytes at the end */
- || (i==0 && zStart==zNum) /* No digits */
+ rc = 0;
+ if( (i==0 && zStart==zNum) /* No digits */
|| nonNum /* UTF16 with high-order bytes non-zero */
){
rc = 1;
- }else{
- rc = 0;
+ }else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */
+ int jj = i;
+ do{
+ if( !sqlite3Isspace(zNum[jj]) ){
+ rc = 1; /* Extra non-space text after the integer */
+ break;
+ }
+ jj += incr;
+ }while( &zNum[jj]<zEnd );
}
- if( i>19*incr ){ /* Too many digits */
- /* zNum is empty or contains non-numeric text or is longer
- ** than 19 digits (thus guaranteeing that it is too large) */
- return 2;
- }else if( i<19*incr ){
+ if( i<19*incr ){
/* Less than 19 digits, so we know that it fits in 64 bits */
assert( u<=LARGEST_INT64 );
return rc;
}else{
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
- c = compare2pow63(zNum, incr);
+ c = i>19*incr ? 1 : compare2pow63(zNum, incr);
if( c<0 ){
/* zNum is less than 9223372036854775808 so it fits */
assert( u<=LARGEST_INT64 );
return rc;
- }else if( c>0 ){
- /* zNum is greater than 9223372036854775808 so it overflows */
- return 2;
}else{
- /* zNum is exactly 9223372036854775808. Fits if negative. The
- ** special case 2 overflow if positive */
- assert( u-1==LARGEST_INT64 );
- return neg ? rc : 3;
+ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
+ if( c>0 ){
+ /* zNum is greater than 9223372036854775808 so it overflows */
+ return 2;
+ }else{
+ /* zNum is exactly 9223372036854775808. Fits if negative. The
+ ** special case 2 overflow if positive */
+ assert( u-1==LARGEST_INT64 );
+ return neg ? rc : 3;
+ }
}
}
}
@@ -30085,52 +31816,52 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 1 */ "AutoCommit" OpHelp(""),
/* 2 */ "Transaction" OpHelp(""),
/* 3 */ "SorterNext" OpHelp(""),
- /* 4 */ "PrevIfOpen" OpHelp(""),
- /* 5 */ "NextIfOpen" OpHelp(""),
- /* 6 */ "Prev" OpHelp(""),
- /* 7 */ "Next" OpHelp(""),
- /* 8 */ "Checkpoint" OpHelp(""),
- /* 9 */ "JournalMode" OpHelp(""),
- /* 10 */ "Vacuum" OpHelp(""),
- /* 11 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
- /* 12 */ "VUpdate" OpHelp("data=r[P3@P2]"),
- /* 13 */ "Goto" OpHelp(""),
- /* 14 */ "Gosub" OpHelp(""),
- /* 15 */ "InitCoroutine" OpHelp(""),
- /* 16 */ "Yield" OpHelp(""),
- /* 17 */ "MustBeInt" OpHelp(""),
- /* 18 */ "Jump" OpHelp(""),
+ /* 4 */ "Prev" OpHelp(""),
+ /* 5 */ "Next" OpHelp(""),
+ /* 6 */ "Checkpoint" OpHelp(""),
+ /* 7 */ "JournalMode" OpHelp(""),
+ /* 8 */ "Vacuum" OpHelp(""),
+ /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
+ /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"),
+ /* 11 */ "Goto" OpHelp(""),
+ /* 12 */ "Gosub" OpHelp(""),
+ /* 13 */ "InitCoroutine" OpHelp(""),
+ /* 14 */ "Yield" OpHelp(""),
+ /* 15 */ "MustBeInt" OpHelp(""),
+ /* 16 */ "Jump" OpHelp(""),
+ /* 17 */ "Once" OpHelp(""),
+ /* 18 */ "If" OpHelp(""),
/* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
- /* 20 */ "Once" OpHelp(""),
- /* 21 */ "If" OpHelp(""),
- /* 22 */ "IfNot" OpHelp(""),
- /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
- /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"),
- /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"),
- /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"),
- /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"),
- /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"),
- /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"),
- /* 30 */ "Found" OpHelp("key=r[P3@P4]"),
- /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"),
- /* 32 */ "NotExists" OpHelp("intkey=r[P3]"),
- /* 33 */ "Last" OpHelp(""),
- /* 34 */ "IfSmaller" OpHelp(""),
- /* 35 */ "SorterSort" OpHelp(""),
- /* 36 */ "Sort" OpHelp(""),
- /* 37 */ "Rewind" OpHelp(""),
- /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"),
- /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"),
- /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 20 */ "IfNot" OpHelp(""),
+ /* 21 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
+ /* 22 */ "SeekLT" OpHelp("key=r[P3@P4]"),
+ /* 23 */ "SeekLE" OpHelp("key=r[P3@P4]"),
+ /* 24 */ "SeekGE" OpHelp("key=r[P3@P4]"),
+ /* 25 */ "SeekGT" OpHelp("key=r[P3@P4]"),
+ /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
+ /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 29 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
+ /* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 32 */ "Last" OpHelp(""),
+ /* 33 */ "IfSmaller" OpHelp(""),
+ /* 34 */ "SorterSort" OpHelp(""),
+ /* 35 */ "Sort" OpHelp(""),
+ /* 36 */ "Rewind" OpHelp(""),
+ /* 37 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 38 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 39 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 40 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 41 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 42 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
/* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
/* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 46 */ "Program" OpHelp(""),
- /* 47 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 48 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 49 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 45 */ "Program" OpHelp(""),
+ /* 46 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 47 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 48 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 49 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
/* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
/* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
@@ -30140,115 +31871,121 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
/* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
/* 58 */ "ElseNotEq" OpHelp(""),
- /* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 60 */ "IncrVacuum" OpHelp(""),
- /* 61 */ "VNext" OpHelp(""),
- /* 62 */ "Init" OpHelp("Start at P2"),
- /* 63 */ "Return" OpHelp(""),
- /* 64 */ "EndCoroutine" OpHelp(""),
- /* 65 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 66 */ "Halt" OpHelp(""),
- /* 67 */ "Integer" OpHelp("r[P2]=P1"),
- /* 68 */ "Int64" OpHelp("r[P2]=P4"),
- /* 69 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 70 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 71 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 72 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 73 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 74 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 75 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 76 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 77 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 78 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 79 */ "CollSeq" OpHelp(""),
- /* 80 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 81 */ "RealAffinity" OpHelp(""),
- /* 82 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 83 */ "Permutation" OpHelp(""),
- /* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
- /* 87 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
- /* 88 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 89 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 90 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 91 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 92 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 94 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
- /* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 96 */ "Column" OpHelp("r[P3]=PX"),
- /* 97 */ "String8" OpHelp("r[P2]='P4'"),
- /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 100 */ "Count" OpHelp("r[P2]=count()"),
- /* 101 */ "ReadCookie" OpHelp(""),
- /* 102 */ "SetCookie" OpHelp(""),
- /* 103 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 104 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 105 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 106 */ "OpenDup" OpHelp(""),
- /* 107 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 108 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 109 */ "SorterOpen" OpHelp(""),
- /* 110 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 111 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
- /* 112 */ "Close" OpHelp(""),
- /* 113 */ "ColumnsUsed" OpHelp(""),
- /* 114 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
- /* 115 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 116 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 117 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 118 */ "Delete" OpHelp(""),
- /* 119 */ "ResetCount" OpHelp(""),
- /* 120 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 121 */ "SorterData" OpHelp("r[P2]=data"),
- /* 122 */ "RowData" OpHelp("r[P2]=data"),
- /* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 124 */ "NullRow" OpHelp(""),
- /* 125 */ "SeekEnd" OpHelp(""),
- /* 126 */ "SorterInsert" OpHelp("key=r[P2]"),
- /* 127 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 128 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 129 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
- /* 130 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 131 */ "Destroy" OpHelp(""),
- /* 132 */ "Real" OpHelp("r[P2]=P4"),
- /* 133 */ "Clear" OpHelp(""),
- /* 134 */ "ResetSorter" OpHelp(""),
- /* 135 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
- /* 136 */ "SqlExec" OpHelp(""),
- /* 137 */ "ParseSchema" OpHelp(""),
- /* 138 */ "LoadAnalysis" OpHelp(""),
- /* 139 */ "DropTable" OpHelp(""),
- /* 140 */ "DropIndex" OpHelp(""),
- /* 141 */ "DropTrigger" OpHelp(""),
- /* 142 */ "IntegrityCk" OpHelp(""),
- /* 143 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 144 */ "Param" OpHelp(""),
- /* 145 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 146 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 147 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
- /* 148 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 149 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 150 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 151 */ "Expire" OpHelp(""),
- /* 152 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 153 */ "VBegin" OpHelp(""),
- /* 154 */ "VCreate" OpHelp(""),
- /* 155 */ "VDestroy" OpHelp(""),
- /* 156 */ "VOpen" OpHelp(""),
- /* 157 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 158 */ "VRename" OpHelp(""),
- /* 159 */ "Pagecount" OpHelp(""),
- /* 160 */ "MaxPgcnt" OpHelp(""),
- /* 161 */ "PureFunc0" OpHelp(""),
- /* 162 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 163 */ "PureFunc" OpHelp(""),
- /* 164 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 165 */ "CursorHint" OpHelp(""),
- /* 166 */ "Noop" OpHelp(""),
- /* 167 */ "Explain" OpHelp(""),
+ /* 59 */ "IncrVacuum" OpHelp(""),
+ /* 60 */ "VNext" OpHelp(""),
+ /* 61 */ "Init" OpHelp("Start at P2"),
+ /* 62 */ "PureFunc0" OpHelp(""),
+ /* 63 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 64 */ "PureFunc" OpHelp(""),
+ /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 66 */ "Return" OpHelp(""),
+ /* 67 */ "EndCoroutine" OpHelp(""),
+ /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 69 */ "Halt" OpHelp(""),
+ /* 70 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 71 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 82 */ "CollSeq" OpHelp(""),
+ /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 84 */ "RealAffinity" OpHelp(""),
+ /* 85 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 86 */ "Permutation" OpHelp(""),
+ /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
+ /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
+ /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
+ /* 90 */ "Column" OpHelp("r[P3]=PX"),
+ /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 92 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 93 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 94 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 95 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 96 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 97 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 98 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 99 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 100 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 101 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 102 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 103 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
+ /* 104 */ "Count" OpHelp("r[P2]=count()"),
+ /* 105 */ "ReadCookie" OpHelp(""),
+ /* 106 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 107 */ "SetCookie" OpHelp(""),
+ /* 108 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 109 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 110 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 111 */ "OpenDup" OpHelp(""),
+ /* 112 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 113 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 114 */ "SorterOpen" OpHelp(""),
+ /* 115 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 116 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 117 */ "Close" OpHelp(""),
+ /* 118 */ "ColumnsUsed" OpHelp(""),
+ /* 119 */ "SeekHit" OpHelp("seekHit=P2"),
+ /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 123 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 124 */ "Delete" OpHelp(""),
+ /* 125 */ "ResetCount" OpHelp(""),
+ /* 126 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 127 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 128 */ "RowData" OpHelp("r[P2]=data"),
+ /* 129 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 130 */ "NullRow" OpHelp(""),
+ /* 131 */ "SeekEnd" OpHelp(""),
+ /* 132 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 133 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 134 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 135 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
+ /* 136 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 137 */ "Destroy" OpHelp(""),
+ /* 138 */ "Clear" OpHelp(""),
+ /* 139 */ "ResetSorter" OpHelp(""),
+ /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
+ /* 141 */ "Real" OpHelp("r[P2]=P4"),
+ /* 142 */ "SqlExec" OpHelp(""),
+ /* 143 */ "ParseSchema" OpHelp(""),
+ /* 144 */ "LoadAnalysis" OpHelp(""),
+ /* 145 */ "DropTable" OpHelp(""),
+ /* 146 */ "DropIndex" OpHelp(""),
+ /* 147 */ "DropTrigger" OpHelp(""),
+ /* 148 */ "IntegrityCk" OpHelp(""),
+ /* 149 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 150 */ "Param" OpHelp(""),
+ /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
+ /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"),
+ /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 159 */ "Expire" OpHelp(""),
+ /* 160 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 161 */ "VBegin" OpHelp(""),
+ /* 162 */ "VCreate" OpHelp(""),
+ /* 163 */ "VDestroy" OpHelp(""),
+ /* 164 */ "VOpen" OpHelp(""),
+ /* 165 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 166 */ "VRename" OpHelp(""),
+ /* 167 */ "Pagecount" OpHelp(""),
+ /* 168 */ "MaxPgcnt" OpHelp(""),
+ /* 169 */ "Trace" OpHelp(""),
+ /* 170 */ "CursorHint" OpHelp(""),
+ /* 171 */ "Noop" OpHelp(""),
+ /* 172 */ "Explain" OpHelp(""),
+ /* 173 */ "Abortable" OpHelp(""),
};
return azName[i];
}
@@ -30394,12 +32131,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
/*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
+** If we are to be thread-safe, include the pthreads header.
*/
#if SQLITE_THREADSAFE
/* # include <pthread.h> */
-# define SQLITE_UNIX_THREADS 1
#endif
/*
@@ -30487,6 +32222,9 @@ struct unixFile {
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
unsigned fsFlags; /* cached details from statfs() */
#endif
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ unsigned iBusyTimeout; /* Wait this many millisec on locks */
+#endif
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID */
#endif
@@ -30925,7 +32663,11 @@ static struct unix_syscall {
#endif
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
+#if defined(HAVE_FCHOWN)
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
+#else
+ { "geteuid", (sqlite3_syscall_ptr)0, 0 },
+#endif
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
@@ -30940,7 +32682,7 @@ static struct unix_syscall {
#else
{ "munmap", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
+#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent)
#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
@@ -30970,7 +32712,15 @@ static struct unix_syscall {
#endif
#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+# ifdef __ANDROID__
+ { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
+# else
{ "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
+# endif
+#else
+ { "ioctl", (sqlite3_syscall_ptr)0, 0 },
+#endif
#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
}; /* End of the overrideable system calls */
@@ -31148,16 +32898,30 @@ static int robust_open(const char *z, int f, mode_t m){
** unixEnterMutex()
** assert( unixMutexHeld() );
** unixEnterLeave()
+**
+** To prevent deadlock, the global unixBigLock must must be acquired
+** before the unixInodeInfo.pLockMutex mutex, if both are held. It is
+** OK to get the pLockMutex without holding unixBigLock first, but if
+** that happens, the unixBigLock mutex must not be acquired until after
+** pLockMutex is released.
+**
+** OK: enter(unixBigLock), enter(pLockInfo)
+** OK: enter(unixBigLock)
+** OK: enter(pLockInfo)
+** ERROR: enter(pLockInfo), enter(unixBigLock)
*/
+static sqlite3_mutex *unixBigLock = 0;
static void unixEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */
+ sqlite3_mutex_enter(unixBigLock);
}
static void unixLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ assert( sqlite3_mutex_held(unixBigLock) );
+ sqlite3_mutex_leave(unixBigLock);
}
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ return sqlite3_mutex_held(unixBigLock);
}
#endif
@@ -31547,22 +33311,39 @@ struct unixFileId {
/*
** An instance of the following structure is allocated for each open
-** inode. Or, on LinuxThreads, there is one of these structures for
-** each inode opened by each thread.
+** inode.
**
** A single inode can have multiple file descriptors, so each unixFile
** structure contains a pointer to an instance of this object and this
** object keeps a count of the number of unixFile pointing to it.
+**
+** Mutex rules:
+**
+** (1) Only the pLockMutex mutex must be held in order to read or write
+** any of the locking fields:
+** nShared, nLock, eFileLock, bProcessLock, pUnused
+**
+** (2) When nRef>0, then the following fields are unchanging and can
+** be read (but not written) without holding any mutex:
+** fileId, pLockMutex
+**
+** (3) With the exceptions above, all the fields may only be read
+** or written while holding the global unixBigLock mutex.
+**
+** Deadlock prevention: The global unixBigLock mutex may not
+** be acquired while holding the pLockMutex mutex. If both unixBigLock
+** and pLockMutex are needed, then unixBigLock must be acquired first.
*/
struct unixInodeInfo {
struct unixFileId fileId; /* The lookup key */
- int nShared; /* Number of SHARED locks held */
- unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
- unsigned char bProcessLock; /* An exclusive process lock is held */
+ sqlite3_mutex *pLockMutex; /* Hold this mutex for... */
+ int nShared; /* Number of SHARED locks held */
+ int nLock; /* Number of outstanding file locks */
+ unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+ unsigned char bProcessLock; /* An exclusive process lock is held */
+ UnixUnusedFd *pUnused; /* Unused file descriptors to close */
int nRef; /* Number of pointers to this structure */
unixShmNode *pShmNode; /* Shared memory associated with this inode */
- int nLock; /* Number of outstanding file locks */
- UnixUnusedFd *pUnused; /* Unused file descriptors to close */
unixInodeInfo *pNext; /* List of all unixInodeInfo objects */
unixInodeInfo *pPrev; /* .... doubly linked */
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -31576,9 +33357,26 @@ struct unixInodeInfo {
/*
** A lists of all unixInodeInfo objects.
+**
+** Must hold unixBigLock in order to read or write this variable.
*/
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
-static unsigned int nUnusedFd = 0; /* Total unused file descriptors */
+
+#ifdef SQLITE_DEBUG
+/*
+** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
+** This routine is used only within assert() to help verify correct mutex
+** usage.
+*/
+int unixFileMutexHeld(unixFile *pFile){
+ assert( pFile->pInode );
+ return sqlite3_mutex_held(pFile->pInode->pLockMutex);
+}
+int unixFileMutexNotheld(unixFile *pFile){
+ assert( pFile->pInode );
+ return sqlite3_mutex_notheld(pFile->pInode->pLockMutex);
+}
+#endif
/*
**
@@ -31684,11 +33482,11 @@ static void closePendingFds(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
UnixUnusedFd *p;
UnixUnusedFd *pNext;
+ assert( unixFileMutexHeld(pFile) );
for(p=pInode->pUnused; p; p=pNext){
pNext = p->pNext;
robust_close(pFile, p->fd, __LINE__);
sqlite3_free(p);
- nUnusedFd--;
}
pInode->pUnused = 0;
}
@@ -31696,17 +33494,20 @@ static void closePendingFds(unixFile *pFile){
/*
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must be held when this routine is called, but the mutex
+** on the inode being deleted must NOT be held.
*/
static void releaseInodeInfo(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
assert( unixMutexHeld() );
+ assert( unixFileMutexNotheld(pFile) );
if( ALWAYS(pInode) ){
pInode->nRef--;
if( pInode->nRef==0 ){
assert( pInode->pShmNode==0 );
+ sqlite3_mutex_enter(pInode->pLockMutex);
closePendingFds(pFile);
+ sqlite3_mutex_leave(pInode->pLockMutex);
if( pInode->pPrev ){
assert( pInode->pPrev->pNext==pInode );
pInode->pPrev->pNext = pInode->pNext;
@@ -31718,10 +33519,10 @@ static void releaseInodeInfo(unixFile *pFile){
assert( pInode->pNext->pPrev==pInode );
pInode->pNext->pPrev = pInode->pPrev;
}
+ sqlite3_mutex_free(pInode->pLockMutex);
sqlite3_free(pInode);
}
}
- assert( inodeList!=0 || nUnusedFd==0 );
}
/*
@@ -31729,8 +33530,7 @@ static void releaseInodeInfo(unixFile *pFile){
** describes that file descriptor. Create a new one if necessary. The
** return value might be uninitialized if an error occurs.
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must held when calling this routine.
**
** Return an appropriate error code.
*/
@@ -31791,7 +33591,7 @@ static int findInodeInfo(
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
- assert( inodeList!=0 || nUnusedFd==0 );
+ assert( unixMutexHeld() );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
@@ -31803,7 +33603,15 @@ static int findInodeInfo(
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
+ if( sqlite3GlobalConfig.bCoreMutex ){
+ pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if( pInode->pLockMutex==0 ){
+ sqlite3_free(pInode);
+ return SQLITE_NOMEM_BKPT;
+ }
+ }
pInode->nRef = 1;
+ assert( unixMutexHeld() );
pInode->pNext = inodeList;
pInode->pPrev = 0;
if( inodeList ) inodeList->pPrev = pInode;
@@ -31881,7 +33689,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
assert( pFile );
assert( pFile->eFileLock<=SHARED_LOCK );
- unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+ sqlite3_mutex_enter(pFile->pInode->pLockMutex);
/* Check if a thread in this process holds such a lock */
if( pFile->pInode->eFileLock>SHARED_LOCK ){
@@ -31906,7 +33714,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
}
#endif
- unixLeaveMutex();
+ sqlite3_mutex_leave(pFile->pInode->pLockMutex);
OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
*pResOut = reserved;
@@ -31914,6 +33722,43 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
}
/*
+** Set a posix-advisory-lock.
+**
+** There are two versions of this routine. If compiled with
+** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
+** which is a pointer to a unixFile. If the unixFile->iBusyTimeout
+** value is set, then it is the number of milliseconds to wait before
+** failing the lock. The iBusyTimeout value is always reset back to
+** zero on each call.
+**
+** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking
+** attempt to set the lock.
+*/
+#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
+# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
+#else
+static int osSetPosixAdvisoryLock(
+ int h, /* The file descriptor on which to take the lock */
+ struct flock *pLock, /* The description of the lock */
+ unixFile *pFile /* Structure holding timeout value */
+){
+ int rc = osFcntl(h,F_SETLK,pLock);
+ while( rc<0 && pFile->iBusyTimeout>0 ){
+ /* On systems that support some kind of blocking file lock with a timeout,
+ ** make appropriate changes here to invoke that blocking file lock. On
+ ** generic posix, however, there is no such API. So we simply try the
+ ** lock once every millisecond until either the timeout expires, or until
+ ** the lock is obtained. */
+ usleep(1000);
+ rc = osFcntl(h,F_SETLK,pLock);
+ pFile->iBusyTimeout--;
+ }
+ return rc;
+}
+#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
+
+
+/*
** Attempt to set a system-lock on the file pFile. The lock is
** described by pLock.
**
@@ -31935,8 +33780,8 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
static int unixFileLock(unixFile *pFile, struct flock *pLock){
int rc;
unixInodeInfo *pInode = pFile->pInode;
- assert( unixMutexHeld() );
assert( pInode!=0 );
+ assert( sqlite3_mutex_held(pInode->pLockMutex) );
if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( pInode->bProcessLock==0 ){
struct flock lock;
@@ -31945,7 +33790,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
lock.l_start = SHARED_FIRST;
lock.l_len = SHARED_SIZE;
lock.l_type = F_WRLCK;
- rc = osFcntl(pFile->h, F_SETLK, &lock);
+ rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
if( rc<0 ) return rc;
pInode->bProcessLock = 1;
pInode->nLock++;
@@ -31953,7 +33798,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
rc = 0;
}
}else{
- rc = osFcntl(pFile->h, F_SETLK, pLock);
+ rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
}
return rc;
}
@@ -32055,8 +33900,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){
/* This mutex is needed because pFile->pInode is shared across threads
*/
- unixEnterMutex();
pInode = pFile->pInode;
+ sqlite3_mutex_enter(pInode->pLockMutex);
/* If some thread using this PID has a lock via a different unixFile*
** handle that precludes the requested lock, return BUSY.
@@ -32199,7 +34044,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
}
end_lock:
- unixLeaveMutex();
+ sqlite3_mutex_leave(pInode->pLockMutex);
OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock),
rc==SQLITE_OK ? "ok" : "failed"));
return rc;
@@ -32212,11 +34057,11 @@ end_lock:
static void setPendingFd(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
UnixUnusedFd *p = pFile->pPreallocatedUnused;
+ assert( unixFileMutexHeld(pFile) );
p->pNext = pInode->pUnused;
pInode->pUnused = p;
pFile->h = -1;
pFile->pPreallocatedUnused = 0;
- nUnusedFd++;
}
/*
@@ -32247,8 +34092,8 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( pFile->eFileLock<=eFileLock ){
return SQLITE_OK;
}
- unixEnterMutex();
pInode = pFile->pInode;
+ sqlite3_mutex_enter(pInode->pLockMutex);
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
@@ -32374,14 +34219,14 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
*/
pInode->nLock--;
assert( pInode->nLock>=0 );
- if( pInode->nLock==0 ){
- closePendingFds(pFile);
- }
+ if( pInode->nLock==0 ) closePendingFds(pFile);
}
end_unlock:
- unixLeaveMutex();
- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
+ sqlite3_mutex_leave(pInode->pLockMutex);
+ if( rc==SQLITE_OK ){
+ pFile->eFileLock = eFileLock;
+ }
return rc;
}
@@ -32452,15 +34297,20 @@ static int closeUnixFile(sqlite3_file *id){
static int unixClose(sqlite3_file *id){
int rc = SQLITE_OK;
unixFile *pFile = (unixFile *)id;
+ unixInodeInfo *pInode = pFile->pInode;
+
+ assert( pInode!=0 );
verifyDbFile(pFile);
unixUnlock(id, NO_LOCK);
+ assert( unixFileMutexNotheld(pFile) );
unixEnterMutex();
/* unixFile.pInode is always valid here. Otherwise, a different close
** routine (e.g. nolockClose()) would be called instead.
*/
assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
- if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
+ sqlite3_mutex_enter(pInode->pLockMutex);
+ if( pInode->nLock ){
/* If there are outstanding locks, do not actually close the file just
** yet because that would clear those locks. Instead, add the file
** descriptor to pInode->pUnused list. It will be automatically closed
@@ -32468,6 +34318,7 @@ static int unixClose(sqlite3_file *id){
*/
setPendingFd(pFile);
}
+ sqlite3_mutex_leave(pInode->pLockMutex);
releaseInodeInfo(pFile);
rc = closeUnixFile(id);
unixLeaveMutex();
@@ -33065,6 +34916,7 @@ static int semXClose(sqlite3_file *id) {
unixFile *pFile = (unixFile*)id;
semXUnlock(id, NO_LOCK);
assert( pFile );
+ assert( unixFileMutexNotheld(pFile) );
unixEnterMutex();
releaseInodeInfo(pFile);
unixLeaveMutex();
@@ -33179,8 +35031,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
*pResOut = 1;
return SQLITE_OK;
}
- unixEnterMutex(); /* Because pFile->pInode is shared across threads */
-
+ sqlite3_mutex_enter(pFile->pInode->pLockMutex);
/* Check if a thread in this process holds such a lock */
if( pFile->pInode->eFileLock>SHARED_LOCK ){
reserved = 1;
@@ -33204,7 +35055,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
}
}
- unixLeaveMutex();
+ sqlite3_mutex_leave(pFile->pInode->pLockMutex);
OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
*pResOut = reserved;
@@ -33267,8 +35118,8 @@ static int afpLock(sqlite3_file *id, int eFileLock){
/* This mutex is needed because pFile->pInode is shared across threads
*/
- unixEnterMutex();
pInode = pFile->pInode;
+ sqlite3_mutex_enter(pInode->pLockMutex);
/* If some thread using this PID has a lock via a different unixFile*
** handle that precludes the requested lock, return BUSY.
@@ -33404,7 +35255,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
}
afp_end_lock:
- unixLeaveMutex();
+ sqlite3_mutex_leave(pInode->pLockMutex);
OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock),
rc==SQLITE_OK ? "ok" : "failed"));
return rc;
@@ -33436,8 +35287,8 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
if( pFile->eFileLock<=eFileLock ){
return SQLITE_OK;
}
- unixEnterMutex();
pInode = pFile->pInode;
+ sqlite3_mutex_enter(pInode->pLockMutex);
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
@@ -33506,14 +35357,14 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
if( rc==SQLITE_OK ){
pInode->nLock--;
assert( pInode->nLock>=0 );
- if( pInode->nLock==0 ){
- closePendingFds(pFile);
- }
+ if( pInode->nLock==0 ) closePendingFds(pFile);
}
}
- unixLeaveMutex();
- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
+ sqlite3_mutex_leave(pInode->pLockMutex);
+ if( rc==SQLITE_OK ){
+ pFile->eFileLock = eFileLock;
+ }
return rc;
}
@@ -33525,14 +35376,20 @@ static int afpClose(sqlite3_file *id) {
unixFile *pFile = (unixFile*)id;
assert( id!=0 );
afpUnlock(id, NO_LOCK);
+ assert( unixFileMutexNotheld(pFile) );
unixEnterMutex();
- if( pFile->pInode && pFile->pInode->nLock ){
- /* If there are outstanding locks, do not actually close the file just
- ** yet because that would clear those locks. Instead, add the file
- ** descriptor to pInode->aPending. It will be automatically closed when
- ** the last lock is cleared.
- */
- setPendingFd(pFile);
+ if( pFile->pInode ){
+ unixInodeInfo *pInode = pFile->pInode;
+ sqlite3_mutex_enter(pInode->pLockMutex);
+ if( pInode->nLock ){
+ /* If there are outstanding locks, do not actually close the file just
+ ** yet because that would clear those locks. Instead, add the file
+ ** descriptor to pInode->aPending. It will be automatically closed when
+ ** the last lock is cleared.
+ */
+ setPendingFd(pFile);
+ }
+ sqlite3_mutex_leave(pInode->pLockMutex);
}
releaseInodeInfo(pFile);
sqlite3_free(pFile->lockingContext);
@@ -34191,7 +36048,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
do{
err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
}while( err==EINTR );
- if( err ) return SQLITE_IOERR_WRITE;
+ if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE;
#else
/* If the OS does not have posix_fallocate(), fake it. Write a
** single byte to the last byte in each block that falls entirely
@@ -34317,6 +36174,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(int*)pArg = fileHasMoved(pFile);
return SQLITE_OK;
}
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ case SQLITE_FCNTL_LOCK_TIMEOUT: {
+ pFile->iBusyTimeout = *(int*)pArg;
+ return SQLITE_OK;
+ }
+#endif
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
@@ -34407,7 +36270,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0;
if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
- return pFile->sectorSize;
+ return;
}
if( !strcmp(fsInfo.f_basetype, "tmp") ) {
@@ -34550,21 +36413,22 @@ static int unixGetpagesize(void){
**
** The following fields are read-only after the object is created:
**
-** fid
+** hShm
** zFilename
**
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
+** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
** unixMutexHeld() is true when reading or writing any other field
** in this structure.
*/
struct unixShmNode {
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
- sqlite3_mutex *mutex; /* Mutex to access this object */
+ sqlite3_mutex *pShmMutex; /* Mutex to access this object */
char *zFilename; /* Name of the mmapped file */
- int h; /* Open file descriptor */
+ int hShm; /* Open file descriptor */
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
+ u8 isUnlocked; /* True if no DMS lock held */
char **apRegion; /* Array of mapped shared-memory regions */
int nRef; /* Number of unixShm objects pointing to this */
unixShm *pFirst; /* All unixShm objects pointing to this */
@@ -34582,16 +36446,16 @@ struct unixShmNode {
** The following fields are initialized when this object is created and
** are read-only thereafter:
**
-** unixShm.pFile
+** unixShm.pShmNode
** unixShm.id
**
-** All other fields are read/write. The unixShm.pFile->mutex must be held
-** while accessing any read/write fields.
+** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
+** be held while accessing any read/write fields.
*/
struct unixShm {
unixShmNode *pShmNode; /* The underlying unixShmNode object */
unixShm *pNext; /* Next unixShm with the same unixShmNode */
- u8 hasMutex; /* True if holding the unixShmNode mutex */
+ u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
u8 id; /* Id of this connection within its unixShmNode */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
@@ -34621,7 +36485,8 @@ static int unixShmSystemLock(
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
- assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
+ assert( pShmNode->nRef>0 || unixMutexHeld() );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
@@ -34629,15 +36494,13 @@ static int unixShmSystemLock(
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* Initialize the locking parameters */
- memset(&f, 0, sizeof(f));
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
-
- rc = osFcntl(pShmNode->h, F_SETLK, &f);
+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
@@ -34709,18 +36572,18 @@ static void unixShmPurge(unixFile *pFd){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
- sqlite3_mutex_free(p->mutex);
+ sqlite3_mutex_free(p->pShmMutex);
for(i=0; i<p->nRegion; i+=nShmPerMap){
- if( p->h>=0 ){
+ if( p->hShm>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
sqlite3_free(p->apRegion[i]);
}
}
sqlite3_free(p->apRegion);
- if( p->h>=0 ){
- robust_close(pFd, p->h, __LINE__);
- p->h = -1;
+ if( p->hShm>=0 ){
+ robust_close(pFd, p->hShm, __LINE__);
+ p->hShm = -1;
}
p->pInode->pShmNode = 0;
sqlite3_free(p);
@@ -34728,6 +36591,69 @@ static void unixShmPurge(unixFile *pFd){
}
/*
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** If the DMS cannot be locked because this is a readonly_shm=1
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
+ struct flock lock;
+ int rc = SQLITE_OK;
+
+ /* Use F_GETLK to determine the locks other processes are holding
+ ** on the DMS byte. If it indicates that another process is holding
+ ** a SHARED lock, then this process may also take a SHARED lock
+ ** and proceed with opening the *-shm file.
+ **
+ ** Or, if no other process is holding any lock, then this process
+ ** is the first to open it. In this case take an EXCLUSIVE lock on the
+ ** DMS byte and truncate the *-shm file to zero bytes in size. Then
+ ** downgrade to a SHARED lock on the DMS byte.
+ **
+ ** If another process is holding an EXCLUSIVE lock on the DMS byte,
+ ** return SQLITE_BUSY to the caller (it will try again). An earlier
+ ** version of this code attempted the SHARED lock at this point. But
+ ** this introduced a subtle race condition: if the process holding
+ ** EXCLUSIVE failed just before truncating the *-shm file, then this
+ ** process might open and use the *-shm file without truncating it.
+ ** And if the *-shm file has been corrupted by a power failure or
+ ** system crash, the database itself may also become corrupt. */
+ lock.l_whence = SEEK_SET;
+ lock.l_start = UNIX_SHM_DMS;
+ lock.l_len = 1;
+ lock.l_type = F_WRLCK;
+ if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
+ rc = SQLITE_IOERR_LOCK;
+ }else if( lock.l_type==F_UNLCK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ rc = SQLITE_READONLY_CANTINIT;
+ }else{
+ rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
+ /* The first connection to attach must truncate the -shm file. We
+ ** truncate to 3 bytes (an arbitrary small number, less than the
+ ** -shm header size) rather than 0 as a system debugging aid, to
+ ** help detect if a -shm file truncation is legitimate or is the work
+ ** or a rogue process. */
+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
+ rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
+ }
+ }
+ }else if( lock.l_type==F_WRLCK ){
+ rc = SQLITE_BUSY;
+ }
+
+ if( rc==SQLITE_OK ){
+ assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+ }
+ return rc;
+}
+
+/*
** Open a shared-memory area associated with open database file pDbFd.
** This particular implementation uses mmapped files.
**
@@ -34765,9 +36691,9 @@ static void unixShmPurge(unixFile *pFd){
static int unixOpenSharedMemory(unixFile *pDbFd){
struct unixShm *p = 0; /* The connection to be opened */
struct unixShmNode *pShmNode; /* The underlying mmapped file */
- int rc; /* Result code */
+ int rc = SQLITE_OK; /* Result code */
unixInodeInfo *pInode; /* The inode of fd */
- char *zShmFilename; /* Name of the file used for SHM */
+ char *zShm; /* Name of the file used for SHM */
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
@@ -34779,6 +36705,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
/* Check to see if a unixShmNode object already exists. Reuse an existing
** one if present. Create a new one if necessary.
*/
+ assert( unixFileMutexNotheld(pDbFd) );
unixEnterMutex();
pInode = pDbFd->pInode;
pShmNode = pInode->pShmNode;
@@ -34808,57 +36735,47 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
- zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
+ zShm = pShmNode->zFilename = (char*)&pShmNode[1];
#ifdef SQLITE_SHM_DIRECTORY
- sqlite3_snprintf(nShmFilename, zShmFilename,
+ sqlite3_snprintf(nShmFilename, zShm,
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
- sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
+ sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
+ sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
- pShmNode->h = -1;
+ pShmNode->hShm = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
if( sqlite3GlobalConfig.bCoreMutex ){
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
+ pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if( pShmNode->pShmMutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
}
if( pInode->bProcessLock==0 ){
- int openFlags = O_RDWR | O_CREAT;
- if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- openFlags = O_RDONLY;
- pShmNode->isReadonly = 1;
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
}
- pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
- if( pShmNode->h<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
- goto shm_open_err;
+ if( pShmNode->hShm<0 ){
+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ if( pShmNode->hShm<0 ){
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
+ goto shm_open_err;
+ }
+ pShmNode->isReadonly = 1;
}
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
- robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
-
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- rc = SQLITE_OK;
- if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
- if( robust_ftruncate(pShmNode->h, 0) ){
- rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
- }
- }
- if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
+ robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
+
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
}
@@ -34875,14 +36792,14 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** the cover of the unixEnterMutex() mutex and the pointer from the
** new (struct unixShm) object to the pShmNode has been set. All that is
** left to do is to link the new object into the linked list starting
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
- ** mutex.
+ ** at pShmNode->pFirst. This must be done while holding the
+ ** pShmNode->pShmMutex.
*/
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
- sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
+ return rc;
/* Jump here on any error */
shm_open_err:
@@ -34933,11 +36850,16 @@ static int unixShmMap(
p = pDbFd->pShm;
pShmNode = p->pShmNode;
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
+ if( pShmNode->isUnlocked ){
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Minimum number of regions required to be mapped. */
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
@@ -34949,12 +36871,12 @@ static int unixShmMap(
pShmNode->szRegion = szRegion;
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* The requested region is not mapped into this processes address space.
** Check to see if it has been allocated (i.e. if the wal-index file is
** large enough to contain the requested region).
*/
- if( osFstat(pShmNode->h, &sStat) ){
+ if( osFstat(pShmNode->hShm, &sStat) ){
rc = SQLITE_IOERR_SHMSIZE;
goto shmpage_out;
}
@@ -34982,7 +36904,7 @@ static int unixShmMap(
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
int x = 0;
- if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
+ if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
@@ -35005,22 +36927,22 @@ static int unixShmMap(
int nMap = szRegion*nShmPerMap;
int i;
void *pMem;
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
+ MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
- pMem = sqlite3Malloc(szRegion);
+ pMem = sqlite3Malloc(nMap);
if( pMem==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
- memset(pMem, 0, szRegion);
+ memset(pMem, 0, nMap);
}
for(i=0; i<nShmPerMap; i++){
@@ -35037,7 +36959,7 @@ shmpage_out:
*pp = 0;
}
if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
return rc;
}
@@ -35071,12 +36993,12 @@ static int unixShmLock(
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
@@ -35149,7 +37071,7 @@ static int unixShmLock(
}
}
}
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
@@ -35166,6 +37088,9 @@ static void unixShmBarrier(
){
UNUSED_PARAMETER(fd);
sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
+ assert( fd->pMethods->xLock==nolockLock
+ || unixFileMutexNotheld((unixFile*)fd)
+ );
unixEnterMutex(); /* Also mutex, for redundancy */
unixLeaveMutex();
}
@@ -35196,22 +37121,23 @@ static int unixShmUnmap(
/* Remove connection p from the set of connections associated
** with pShmNode */
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
*pp = p->pNext;
/* Free the connection p */
sqlite3_free(p);
pDbFd->pShm = 0;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
/* If pShmNode->nRef has reached 0, then close the underlying
** shared-memory file, too */
+ assert( unixFileMutexNotheld(pDbFd) );
unixEnterMutex();
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ){
+ if( deleteFlag && pShmNode->hShm>=0 ){
osUnlink(pShmNode->zFilename);
}
unixShmPurge(pDbFd);
@@ -35533,7 +37459,7 @@ IOMETHODS(
IOMETHODS(
nolockIoFinder, /* Finder function name */
nolockIoMethods, /* sqlite3_io_methods object name */
- 3, /* shared memory is disabled */
+ 3, /* shared memory and mmap are enabled */
nolockClose, /* xClose method */
nolockLock, /* xLock method */
nolockUnlock, /* xUnlock method */
@@ -36055,7 +37981,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
**
** Even if a subsequent open() call does succeed, the consequences of
** not searching for a reusable file descriptor are not dire. */
- if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){
+ if( inodeList!=0 && 0==osStat(zPath, &sStat) ){
unixInodeInfo *pInode;
pInode = inodeList;
@@ -36065,12 +37991,14 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
}
if( pInode ){
UnixUnusedFd **pp;
+ assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
+ sqlite3_mutex_enter(pInode->pLockMutex);
for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
pUnused = *pp;
if( pUnused ){
- nUnusedFd--;
*pp = pUnused->pNext;
}
+ sqlite3_mutex_leave(pInode->pLockMutex);
}
}
unixLeaveMutex();
@@ -36228,7 +38156,7 @@ static int unixOpen(
** a file-descriptor on the directory too. The first time unixSync()
** is called the directory file descriptor will be fsync()ed and close()d.
*/
- int syncDir = (isCreate && (
+ int isNewJrnl = (isCreate && (
eType==SQLITE_OPEN_MASTER_JOURNAL
|| eType==SQLITE_OPEN_MAIN_JOURNAL
|| eType==SQLITE_OPEN_WAL
@@ -36275,7 +38203,6 @@ static int unixOpen(
randomnessPid = osGetpid(0);
sqlite3_randomness(0,0);
}
-
memset(p, 0, sizeof(unixFile));
if( eType==SQLITE_OPEN_MAIN_DB ){
@@ -36298,7 +38225,7 @@ static int unixOpen(
}else if( !zName ){
/* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !syncDir);
+ assert(isDelete && !isNewJrnl);
rc = unixGetTempname(pVfs->mxPathname, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
@@ -36333,17 +38260,24 @@ static int unixOpen(
fd = robust_open(zName, openFlags, openMode);
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
assert( !isExclusive || (openFlags & O_CREAT)!=0 );
- if( fd<0 && errno!=EISDIR && isReadWrite ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
+ if( fd<0 ){
+ if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
+ /* If unable to create a journal because the directory is not
+ ** writable, change the error code to indicate that. */
+ rc = SQLITE_READONLY_DIRECTORY;
+ }else if( errno!=EISDIR && isReadWrite ){
+ /* Failed to open the file for read/write access. Try read-only. */
+ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+ openFlags &= ~(O_RDWR|O_CREAT);
+ flags |= SQLITE_OPEN_READONLY;
+ openFlags |= O_RDONLY;
+ isReadonly = 1;
+ fd = robust_open(zName, openFlags, openMode);
+ }
}
if( fd<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ if( rc==SQLITE_OK ) rc = rc2;
goto open_finished;
}
@@ -36403,7 +38337,7 @@ static int unixOpen(
if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY;
noLock = eType!=SQLITE_OPEN_MAIN_DB;
if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK;
- if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC;
+ if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC;
if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -36604,7 +38538,7 @@ static int unixFullPathname(
if( bLink ){
if( zDel==0 ){
- zDel = sqlite3_malloc(nOut);
+ zDel = sqlite3Malloc(nOut);
if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
}else if( ++nLink>SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
@@ -38165,6 +40099,7 @@ SQLITE_API int sqlite3_os_init(void){
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
sqlite3_vfs_register(&aVfs[i], i==0);
}
+ unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
return SQLITE_OK;
}
@@ -38178,6 +40113,7 @@ SQLITE_API int sqlite3_os_init(void){
** This routine is a no-op for unix.
*/
SQLITE_API int sqlite3_os_end(void){
+ unixBigLock = 0;
return SQLITE_OK;
}
#endif /* !SQLITE_OS_WIN */
@@ -38706,22 +40642,6 @@ struct winVfsAppData {
#endif
/*
- * The value used with sqlite3_win32_set_directory() to specify that
- * the data directory should be changed.
- */
-#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
-# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
-#endif
-
-/*
- * The value used with sqlite3_win32_set_directory() to specify that
- * the temporary directory should be changed.
- */
-#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
-# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
-#endif
-
-/*
* If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
* various Win32 API heap functions instead of our own.
*/
@@ -40314,13 +42234,13 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
}
/*
-** This function sets the data directory or the temporary directory based on
-** the provided arguments. The type argument must be 1 in order to set the
-** data directory or 2 in order to set the temporary directory. The zValue
-** argument is the name of the directory to use. The return value will be
-** SQLITE_OK if successful.
+** This function is the same as sqlite3_win32_set_directory (below); however,
+** it accepts a UTF-8 string.
*/
-SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+SQLITE_API int sqlite3_win32_set_directory8(
+ unsigned long type, /* Identifier for directory being set or reset */
+ const char *zValue /* New value for directory being set or reset */
+){
char **ppDirectory = 0;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -40336,21 +42256,54 @@ SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
);
assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
if( ppDirectory ){
- char *zValueUtf8 = 0;
+ char *zCopy = 0;
if( zValue && zValue[0] ){
- zValueUtf8 = winUnicodeToUtf8(zValue);
- if ( zValueUtf8==0 ){
+ zCopy = sqlite3_mprintf("%s", zValue);
+ if ( zCopy==0 ){
return SQLITE_NOMEM_BKPT;
}
}
sqlite3_free(*ppDirectory);
- *ppDirectory = zValueUtf8;
+ *ppDirectory = zCopy;
return SQLITE_OK;
}
return SQLITE_ERROR;
}
/*
+** This function is the same as sqlite3_win32_set_directory (below); however,
+** it accepts a UTF-16 string.
+*/
+SQLITE_API int sqlite3_win32_set_directory16(
+ unsigned long type, /* Identifier for directory being set or reset */
+ const void *zValue /* New value for directory being set or reset */
+){
+ int rc;
+ char *zUtf8 = 0;
+ if( zValue ){
+ zUtf8 = sqlite3_win32_unicode_to_utf8(zValue);
+ if( zUtf8==0 ) return SQLITE_NOMEM_BKPT;
+ }
+ rc = sqlite3_win32_set_directory8(type, zUtf8);
+ if( zUtf8 ) sqlite3_free(zUtf8);
+ return rc;
+}
+
+/*
+** This function sets the data directory or the temporary directory based on
+** the provided arguments. The type argument must be 1 in order to set the
+** data directory or 2 in order to set the temporary directory. The zValue
+** argument is the name of the directory to use. The return value will be
+** SQLITE_OK if successful.
+*/
+SQLITE_API int sqlite3_win32_set_directory(
+ unsigned long type, /* Identifier for directory being set or reset */
+ void *zValue /* New value for directory being set or reset */
+){
+ return sqlite3_win32_set_directory16(type, zValue);
+}
+
+/*
** The return value of winGetLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
@@ -41274,6 +43227,9 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
winFile *pFile = (winFile*)id; /* File handle object */
int rc = SQLITE_OK; /* Return code for this function */
DWORD lastErrno;
+#if SQLITE_MAX_MMAP_SIZE>0
+ sqlite3_int64 oldMmapSize;
+#endif
assert( pFile );
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
@@ -41289,6 +43245,15 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
}
+#if SQLITE_MAX_MMAP_SIZE>0
+ if( pFile->pMapRegion ){
+ oldMmapSize = pFile->mmapSize;
+ }else{
+ oldMmapSize = 0;
+ }
+ winUnmapfile(pFile);
+#endif
+
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
if( winSeekFile(pFile, nByte) ){
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
@@ -41301,12 +43266,12 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
}
#if SQLITE_MAX_MMAP_SIZE>0
- /* If the file was truncated to a size smaller than the currently
- ** mapped region, reduce the effective mapping size as well. SQLite will
- ** use read() and write() to access data beyond this point from now on.
- */
- if( pFile->pMapRegion && nByte<pFile->mmapSize ){
- pFile->mmapSize = nByte;
+ if( rc==SQLITE_OK && oldMmapSize>0 ){
+ if( oldMmapSize>nByte ){
+ winMapfile(pFile, -1);
+ }else{
+ winMapfile(pFile, oldMmapSize);
+ }
}
#endif
@@ -42018,15 +43983,16 @@ static SYSTEM_INFO winSysInfo;
** assert( winShmMutexHeld() );
** winShmLeaveMutex()
*/
+static sqlite3_mutex *winBigLock = 0;
static void winShmEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ sqlite3_mutex_enter(winBigLock);
}
static void winShmLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ sqlite3_mutex_leave(winBigLock);
}
#ifndef NDEBUG
static int winShmMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
+ return sqlite3_mutex_held(winBigLock);
}
#endif
@@ -42060,6 +44026,9 @@ struct winShmNode {
int szRegion; /* Size of shared-memory regions */
int nRegion; /* Size of array apRegion */
+ u8 isReadonly; /* True if read-only */
+ u8 isUnlocked; /* True if no DMS lock held */
+
struct ShmRegion {
HANDLE hMap; /* File handle from CreateFileMapping */
void *pMap;
@@ -42126,7 +44095,7 @@ static int winShmSystemLock(
int rc = 0; /* Result code form Lock/UnlockFileEx() */
/* Access to the winShmNode object is serialized by the caller */
- assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
+ assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) );
OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
pFile->hFile.h, lockType, ofst, nByte));
@@ -42208,6 +44177,37 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
}
/*
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** If the DMS cannot be locked because this is a readonly_shm=1
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int winLockSharedMemory(winShmNode *pShmNode){
+ int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
+
+ if( rc==SQLITE_OK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return SQLITE_READONLY_CANTINIT;
+ }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+ "winLockSharedMemory", pShmNode->zFilename);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ }
+
+ return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
+}
+
+/*
** Open the shared-memory area associated with database file pDbFd.
**
** When opening a new shared-memory file, if no other instances of that
@@ -42216,9 +44216,9 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
*/
static int winOpenSharedMemory(winFile *pDbFd){
struct winShm *p; /* The connection to be opened */
- struct winShmNode *pShmNode = 0; /* The underlying mmapped file */
- int rc; /* Result code */
- struct winShmNode *pNew; /* Newly allocated winShmNode */
+ winShmNode *pShmNode = 0; /* The underlying mmapped file */
+ int rc = SQLITE_OK; /* Result code */
+ winShmNode *pNew; /* Newly allocated winShmNode */
int nName; /* Size of zName in bytes */
assert( pDbFd->pShm==0 ); /* Not previously opened */
@@ -42251,6 +44251,9 @@ static int winOpenSharedMemory(winFile *pDbFd){
if( pShmNode ){
sqlite3_free(pNew);
}else{
+ int inFlags = SQLITE_OPEN_WAL;
+ int outFlags = 0;
+
pShmNode = pNew;
pNew = 0;
((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
@@ -42265,30 +44268,23 @@ static int winOpenSharedMemory(winFile *pDbFd){
}
}
- rc = winOpen(pDbFd->pVfs,
- pShmNode->zFilename, /* Name of the file (UTF-8) */
- (sqlite3_file*)&pShmNode->hFile, /* File handle here */
- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
- 0);
- if( SQLITE_OK!=rc ){
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ }else{
+ inFlags |= SQLITE_OPEN_READONLY;
+ }
+ rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
+ (sqlite3_file*)&pShmNode->hFile,
+ inFlags, &outFlags);
+ if( rc!=SQLITE_OK ){
+ rc = winLogError(rc, osGetLastError(), "winOpenShm",
+ pShmNode->zFilename);
goto shm_open_err;
}
+ if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
- if( rc!=SQLITE_OK ){
- rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winOpenShm", pDbFd->zPath);
- }
- }
- if( rc==SQLITE_OK ){
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
- rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
@@ -42311,7 +44307,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
+ return rc;
/* Jump here on any error */
shm_open_err:
@@ -42515,6 +44511,8 @@ static int winShmMap(
winFile *pDbFd = (winFile*)fd;
winShm *pShm = pDbFd->pShm;
winShmNode *pShmNode;
+ DWORD protect = PAGE_READWRITE;
+ DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
int rc = SQLITE_OK;
if( !pShm ){
@@ -42525,6 +44523,11 @@ static int winShmMap(
pShmNode = pShm->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
+ if( pShmNode->isUnlocked ){
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
if( pShmNode->nRegion<=iRegion ){
@@ -42571,21 +44574,26 @@ static int winShmMap(
}
pShmNode->aRegion = apNew;
+ if( pShmNode->isReadonly ){
+ protect = PAGE_READONLY;
+ flags = FILE_MAP_READ;
+ }
+
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap = NULL; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, nByte, NULL
+ NULL, protect, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
hMap = osCreateFileMappingA(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
@@ -42595,11 +44603,11 @@ static int winShmMap(
int iOffset = pShmNode->nRegion*szRegion;
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
#if SQLITE_OS_WINRT
- pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+ pMap = osMapViewOfFileFromApp(hMap, flags,
iOffset - iOffsetShift, szRegion + iOffsetShift
);
#else
- pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+ pMap = osMapViewOfFile(hMap, flags,
0, iOffset - iOffsetShift, szRegion + iOffsetShift
);
#endif
@@ -42630,6 +44638,7 @@ shmpage_out:
}else{
*pp = 0;
}
+ if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
sqlite3_mutex_leave(pShmNode->mutex);
return rc;
}
@@ -43486,8 +45495,10 @@ static int winOpen(
&extendedParameters);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
- int isRO = 0;
- int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -43501,8 +45512,10 @@ static int winOpen(
NULL);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
- int isRO = 0;
- int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -43519,8 +45532,10 @@ static int winOpen(
NULL);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
- int isRO = 0;
- int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -44458,6 +46473,10 @@ SQLITE_API int sqlite3_os_init(void){
sqlite3_vfs_register(&winLongPathNolockVfs, 0);
#endif
+#ifndef SQLITE_OMIT_WAL
+ winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
+#endif
+
return SQLITE_OK;
}
@@ -44468,12 +46487,609 @@ SQLITE_API int sqlite3_os_end(void){
sleepObj = NULL;
}
#endif
+
+#ifndef SQLITE_OMIT_WAL
+ winBigLock = 0;
+#endif
+
return SQLITE_OK;
}
#endif /* SQLITE_OS_WIN */
/************** End of os_win.c **********************************************/
+/************** Begin file memdb.c *******************************************/
+/*
+** 2016-09-07
+**
+** 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 an in-memory VFS. A database is held as a contiguous
+** block of memory.
+**
+** This file also implements interface sqlite3_serialize() and
+** sqlite3_deserialize().
+*/
+/* #include "sqliteInt.h" */
+#ifdef SQLITE_ENABLE_DESERIALIZE
+
+/*
+** Forward declaration of objects used by this utility
+*/
+typedef struct sqlite3_vfs MemVfs;
+typedef struct MemFile MemFile;
+
+/* Access to a lower-level VFS that (might) implement dynamic loading,
+** access to randomness, etc.
+*/
+#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
+
+/* An open file */
+struct MemFile {
+ sqlite3_file base; /* IO methods */
+ sqlite3_int64 sz; /* Size of the file */
+ sqlite3_int64 szMax; /* Space allocated to aData */
+ unsigned char *aData; /* content of the file */
+ int nMmap; /* Number of memory mapped pages */
+ unsigned mFlags; /* Flags */
+ int eLock; /* Most recent lock against this file */
+};
+
+/*
+** Methods for MemFile
+*/
+static int memdbClose(sqlite3_file*);
+static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
+static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
+static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
+static int memdbSync(sqlite3_file*, int flags);
+static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
+static int memdbLock(sqlite3_file*, int);
+/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
+static int memdbFileControl(sqlite3_file*, int op, void *pArg);
+/* static int memdbSectorSize(sqlite3_file*); // not used */
+static int memdbDeviceCharacteristics(sqlite3_file*);
+static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+
+/*
+** Methods for MemVfs
+*/
+static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
+/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
+static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
+static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
+static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
+static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
+static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
+static void memdbDlClose(sqlite3_vfs*, void*);
+static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
+static int memdbSleep(sqlite3_vfs*, int microseconds);
+/* static int memdbCurrentTime(sqlite3_vfs*, double*); */
+static int memdbGetLastError(sqlite3_vfs*, int, char *);
+static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
+
+static sqlite3_vfs memdb_vfs = {
+ 2, /* iVersion */
+ 0, /* szOsFile (set when registered) */
+ 1024, /* mxPathname */
+ 0, /* pNext */
+ "memdb", /* zName */
+ 0, /* pAppData (set when registered) */
+ memdbOpen, /* xOpen */
+ 0, /* memdbDelete, */ /* xDelete */
+ memdbAccess, /* xAccess */
+ memdbFullPathname, /* xFullPathname */
+ memdbDlOpen, /* xDlOpen */
+ memdbDlError, /* xDlError */
+ memdbDlSym, /* xDlSym */
+ memdbDlClose, /* xDlClose */
+ memdbRandomness, /* xRandomness */
+ memdbSleep, /* xSleep */
+ 0, /* memdbCurrentTime, */ /* xCurrentTime */
+ memdbGetLastError, /* xGetLastError */
+ memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
+};
+
+static const sqlite3_io_methods memdb_io_methods = {
+ 3, /* iVersion */
+ memdbClose, /* xClose */
+ memdbRead, /* xRead */
+ memdbWrite, /* xWrite */
+ memdbTruncate, /* xTruncate */
+ memdbSync, /* xSync */
+ memdbFileSize, /* xFileSize */
+ memdbLock, /* xLock */
+ memdbLock, /* xUnlock - same as xLock in this case */
+ 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
+ memdbFileControl, /* xFileControl */
+ 0, /* memdbSectorSize,*/ /* xSectorSize */
+ memdbDeviceCharacteristics, /* xDeviceCharacteristics */
+ 0, /* xShmMap */
+ 0, /* xShmLock */
+ 0, /* xShmBarrier */
+ 0, /* xShmUnmap */
+ memdbFetch, /* xFetch */
+ memdbUnfetch /* xUnfetch */
+};
+
+
+
+/*
+** Close an memdb-file.
+**
+** The pData pointer is owned by the application, so there is nothing
+** to free.
+*/
+static int memdbClose(sqlite3_file *pFile){
+ MemFile *p = (MemFile *)pFile;
+ if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
+ return SQLITE_OK;
+}
+
+/*
+** Read data from an memdb-file.
+*/
+static int memdbRead(
+ sqlite3_file *pFile,
+ void *zBuf,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ MemFile *p = (MemFile *)pFile;
+ if( iOfst+iAmt>p->sz ){
+ memset(zBuf, 0, iAmt);
+ if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
+ return SQLITE_IOERR_SHORT_READ;
+ }
+ memcpy(zBuf, p->aData+iOfst, iAmt);
+ return SQLITE_OK;
+}
+
+/*
+** Try to enlarge the memory allocation to hold at least sz bytes
+*/
+static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
+ unsigned char *pNew;
+ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
+ return SQLITE_FULL;
+ }
+ pNew = sqlite3_realloc64(p->aData, newSz);
+ if( pNew==0 ) return SQLITE_NOMEM;
+ p->aData = pNew;
+ p->szMax = newSz;
+ return SQLITE_OK;
+}
+
+/*
+** Write data to an memdb-file.
+*/
+static int memdbWrite(
+ sqlite3_file *pFile,
+ const void *z,
+ int iAmt,
+ sqlite_int64 iOfst
+){
+ MemFile *p = (MemFile *)pFile;
+ if( iOfst+iAmt>p->sz ){
+ int rc;
+ if( iOfst+iAmt>p->szMax
+ && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
+ ){
+ return rc;
+ }
+ if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
+ p->sz = iOfst+iAmt;
+ }
+ memcpy(p->aData+iOfst, z, iAmt);
+ return SQLITE_OK;
+}
+
+/*
+** Truncate an memdb-file.
+**
+** In rollback mode (which is always the case for memdb, as it does not
+** support WAL mode) the truncate() method is only used to reduce
+** the size of a file, never to increase the size.
+*/
+static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
+ MemFile *p = (MemFile *)pFile;
+ if( NEVER(size>p->sz) ) return SQLITE_FULL;
+ p->sz = size;
+ return SQLITE_OK;
+}
+
+/*
+** Sync an memdb-file.
+*/
+static int memdbSync(sqlite3_file *pFile, int flags){
+ return SQLITE_OK;
+}
+
+/*
+** Return the current file-size of an memdb-file.
+*/
+static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+ MemFile *p = (MemFile *)pFile;
+ *pSize = p->sz;
+ return SQLITE_OK;
+}
+
+/*
+** Lock an memdb-file.
+*/
+static int memdbLock(sqlite3_file *pFile, int eLock){
+ MemFile *p = (MemFile *)pFile;
+ p->eLock = eLock;
+ return SQLITE_OK;
+}
+
+#if 0 /* Never used because memdbAccess() always returns false */
+/*
+** Check if another file-handle holds a RESERVED lock on an memdb-file.
+*/
+static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
+ *pResOut = 0;
+ return SQLITE_OK;
+}
+#endif
+
+/*
+** File control method. For custom operations on an memdb-file.
+*/
+static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
+ MemFile *p = (MemFile *)pFile;
+ int rc = SQLITE_NOTFOUND;
+ if( op==SQLITE_FCNTL_VFSNAME ){
+ *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
+ rc = SQLITE_OK;
+ }
+ return rc;
+}
+
+#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
+/*
+** Return the sector-size in bytes for an memdb-file.
+*/
+static int memdbSectorSize(sqlite3_file *pFile){
+ return 1024;
+}
+#endif
+
+/*
+** Return the device characteristic flags supported by an memdb-file.
+*/
+static int memdbDeviceCharacteristics(sqlite3_file *pFile){
+ return SQLITE_IOCAP_ATOMIC |
+ SQLITE_IOCAP_POWERSAFE_OVERWRITE |
+ SQLITE_IOCAP_SAFE_APPEND |
+ SQLITE_IOCAP_SEQUENTIAL;
+}
+
+/* Fetch a page of a memory-mapped file */
+static int memdbFetch(
+ sqlite3_file *pFile,
+ sqlite3_int64 iOfst,
+ int iAmt,
+ void **pp
+){
+ MemFile *p = (MemFile *)pFile;
+ p->nMmap++;
+ *pp = (void*)(p->aData + iOfst);
+ return SQLITE_OK;
+}
+
+/* Release a memory-mapped page */
+static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
+ MemFile *p = (MemFile *)pFile;
+ p->nMmap--;
+ return SQLITE_OK;
+}
+
+/*
+** Open an mem file handle.
+*/
+static int memdbOpen(
+ sqlite3_vfs *pVfs,
+ const char *zName,
+ sqlite3_file *pFile,
+ int flags,
+ int *pOutFlags
+){
+ MemFile *p = (MemFile*)pFile;
+ if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
+ return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
+ }
+ memset(p, 0, sizeof(*p));
+ p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
+ assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
+ *pOutFlags = flags | SQLITE_OPEN_MEMORY;
+ p->base.pMethods = &memdb_io_methods;
+ return SQLITE_OK;
+}
+
+#if 0 /* Only used to delete rollback journals, master journals, and WAL
+ ** files, none of which exist in memdb. So this routine is never used */
+/*
+** Delete the file located at zPath. If the dirSync argument is true,
+** ensure the file-system modifications are synced to disk before
+** returning.
+*/
+static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+ return SQLITE_IOERR_DELETE;
+}
+#endif
+
+/*
+** Test for access permissions. Return true if the requested permission
+** is available, or false otherwise.
+**
+** With memdb, no files ever exist on disk. So always return false.
+*/
+static int memdbAccess(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int flags,
+ int *pResOut
+){
+ *pResOut = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Populate buffer zOut with the full canonical pathname corresponding
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
+** of at least (INST_MAX_PATHNAME+1) bytes.
+*/
+static int memdbFullPathname(
+ sqlite3_vfs *pVfs,
+ const char *zPath,
+ int nOut,
+ char *zOut
+){
+ sqlite3_snprintf(nOut, zOut, "%s", zPath);
+ return SQLITE_OK;
+}
+
+/*
+** Open the dynamic library located at zPath and return a handle.
+*/
+static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
+}
+
+/*
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
+** utf-8 string describing the most recent error encountered associated
+** with dynamic libraries.
+*/
+static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
+}
+
+/*
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
+*/
+static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
+ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
+}
+
+/*
+** Close the dynamic library handle pHandle.
+*/
+static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
+ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
+}
+
+/*
+** Populate the buffer pointed to by zBufOut with nByte bytes of
+** random data.
+*/
+static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
+}
+
+/*
+** Sleep for nMicro microseconds. Return the number of microseconds
+** actually slept.
+*/
+static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
+ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
+}
+
+#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
+/*
+** Return the current time as a Julian Day number in *pTimeOut.
+*/
+static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
+}
+#endif
+
+static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
+}
+static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
+ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
+}
+
+/*
+** Translate a database connection pointer and schema name into a
+** MemFile pointer.
+*/
+static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
+ MemFile *p = 0;
+ int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
+ if( rc ) return 0;
+ if( p->base.pMethods!=&memdb_io_methods ) return 0;
+ return p;
+}
+
+/*
+** Return the serialization of a database
+*/
+SQLITE_API unsigned char *sqlite3_serialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which database within the connection */
+ sqlite3_int64 *piSize, /* Write size here, if not NULL */
+ unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
+){
+ MemFile *p;
+ int iDb;
+ Btree *pBt;
+ sqlite3_int64 sz;
+ int szPage = 0;
+ sqlite3_stmt *pStmt = 0;
+ unsigned char *pOut;
+ char *zSql;
+ int rc;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+
+ if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
+ p = memdbFromDbSchema(db, zSchema);
+ iDb = sqlite3FindDbName(db, zSchema);
+ if( piSize ) *piSize = -1;
+ if( iDb<0 ) return 0;
+ if( p ){
+ if( piSize ) *piSize = p->sz;
+ if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
+ pOut = p->aData;
+ }else{
+ pOut = sqlite3_malloc64( p->sz );
+ if( pOut ) memcpy(pOut, p->aData, p->sz);
+ }
+ return pOut;
+ }
+ pBt = db->aDb[iDb].pBt;
+ if( pBt==0 ) return 0;
+ szPage = sqlite3BtreeGetPageSize(pBt);
+ zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
+ rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
+ sqlite3_free(zSql);
+ if( rc ) return 0;
+ rc = sqlite3_step(pStmt);
+ if( rc!=SQLITE_ROW ){
+ pOut = 0;
+ }else{
+ sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ if( piSize ) *piSize = sz;
+ if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
+ pOut = 0;
+ }else{
+ pOut = sqlite3_malloc64( sz );
+ if( pOut ){
+ int nPage = sqlite3_column_int(pStmt, 0);
+ Pager *pPager = sqlite3BtreePager(pBt);
+ int pgno;
+ for(pgno=1; pgno<=nPage; pgno++){
+ DbPage *pPage = 0;
+ unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
+ if( rc==SQLITE_OK ){
+ memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
+ }else{
+ memset(pTo, 0, szPage);
+ }
+ sqlite3PagerUnref(pPage);
+ }
+ }
+ }
+ }
+ sqlite3_finalize(pStmt);
+ return pOut;
+}
+
+/* Convert zSchema to a MemDB and initialize its content.
+*/
+SQLITE_API int sqlite3_deserialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to reopen with the deserialization */
+ unsigned char *pData, /* The serialized database content */
+ sqlite3_int64 szDb, /* Number bytes in the deserialization */
+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */
+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
+){
+ MemFile *p;
+ char *zSql;
+ sqlite3_stmt *pStmt = 0;
+ int rc;
+ int iDb;
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+ if( szDb<0 ) return SQLITE_MISUSE_BKPT;
+ if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
+#endif
+
+ sqlite3_mutex_enter(db->mutex);
+ if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
+ iDb = sqlite3FindDbName(db, zSchema);
+ if( iDb<0 ){
+ rc = SQLITE_ERROR;
+ goto end_deserialize;
+ }
+ zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( rc ) goto end_deserialize;
+ db->init.iDb = (u8)iDb;
+ db->init.reopenMemdb = 1;
+ rc = sqlite3_step(pStmt);
+ db->init.reopenMemdb = 0;
+ if( rc!=SQLITE_DONE ){
+ rc = SQLITE_ERROR;
+ goto end_deserialize;
+ }
+ p = memdbFromDbSchema(db, zSchema);
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p->aData = pData;
+ p->sz = szDb;
+ p->szMax = szBuf;
+ p->mFlags = mFlags;
+ rc = SQLITE_OK;
+ }
+
+end_deserialize:
+ sqlite3_finalize(pStmt);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
+/*
+** This routine is called when the extension is loaded.
+** Register the new VFS.
+*/
+SQLITE_PRIVATE int sqlite3MemdbInit(void){
+ sqlite3_vfs *pLower = sqlite3_vfs_find(0);
+ int sz = pLower->szOsFile;
+ memdb_vfs.pAppData = pLower;
+ /* In all known configurations of SQLite, the size of a default
+ ** sqlite3_file is greater than the size of a memdb sqlite3_file.
+ ** Should that ever change, remove the following NEVER() */
+ if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
+ memdb_vfs.szOsFile = sz;
+ return sqlite3_vfs_register(&memdb_vfs, 0);
+}
+#endif /* SQLITE_ENABLE_DESERIALIZE */
+
+/************** End of memdb.c ***********************************************/
/************** Begin file bitvec.c ******************************************/
/*
** 2008 February 16
@@ -45322,7 +47938,7 @@ SQLITE_PRIVATE int sqlite3PcacheFetchStress(
sqlite3_log(SQLITE_FULL,
"spill page %d making room for %d - cache used: %d/%d",
pPg->pgno, pgno,
- sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
+ sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache),
numberOfCachePages(pCache));
#endif
pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
@@ -45457,16 +48073,15 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
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);
- }
+ assert( (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);
}
}
@@ -47151,30 +49766,23 @@ struct RowSet {
#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
/*
-** Turn bulk memory into a RowSet object. N bytes of memory
-** are available at pSpace. The db pointer is used as a memory context
-** for any subsequent allocations that need to occur.
-** Return a pointer to the new RowSet object.
-**
-** It must be the case that N is sufficient to make a Rowset. If not
-** an assertion fault occurs.
-**
-** If N is larger than the minimum, use the surplus as an initial
-** allocation of entries available to be filled.
+** Allocate a RowSet object. Return NULL if a memory allocation
+** error occurs.
*/
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
- RowSet *p;
- assert( N >= ROUND8(sizeof(*p)) );
- p = pSpace;
- p->pChunk = 0;
- p->db = db;
- p->pEntry = 0;
- p->pLast = 0;
- p->pForest = 0;
- p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
- p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
- p->rsFlags = ROWSET_SORTED;
- p->iBatch = 0;
+SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){
+ RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p));
+ if( p ){
+ int N = sqlite3DbMallocSize(db, p);
+ p->pChunk = 0;
+ p->db = db;
+ p->pEntry = 0;
+ p->pLast = 0;
+ p->pForest = 0;
+ p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+ p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
+ p->rsFlags = ROWSET_SORTED;
+ p->iBatch = 0;
+ }
return p;
}
@@ -47183,7 +49791,8 @@ SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int
** the RowSet has allocated over its lifetime. This routine is
** the destructor for the RowSet.
*/
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
+SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){
+ RowSet *p = (RowSet*)pArg;
struct RowSetChunk *pChunk, *pNextChunk;
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
pNextChunk = pChunk->pNextChunk;
@@ -47198,6 +49807,16 @@ SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
}
/*
+** Deallocate all chunks from a RowSet. This frees all memory that
+** the RowSet has allocated over its lifetime. This routine is
+** the destructor for the RowSet.
+*/
+SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){
+ sqlite3RowSetClear(pArg);
+ sqlite3DbFree(((RowSet*)pArg)->db, pArg);
+}
+
+/*
** Allocate a new RowSetEntry object that is associated with the
** given RowSet. Return a pointer to the new and completely uninitialized
** objected.
@@ -47684,6 +50303,8 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
+SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -48379,7 +51000,7 @@ struct Pager {
char *zJournal; /* Name of the journal file */
int (*xBusyHandler)(void*); /* Function to call when busy */
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
- int aStat[3]; /* Total cache hits, misses and writes */
+ int aStat[4]; /* Total cache hits, misses, writes, spills */
#ifdef SQLITE_TEST
int nRead; /* Database pages read */
#endif
@@ -48407,6 +51028,7 @@ struct Pager {
#define PAGER_STAT_HIT 0
#define PAGER_STAT_MISS 1
#define PAGER_STAT_WRITE 2
+#define PAGER_STAT_SPILL 3
/*
** The following global variables hold counters used for
@@ -48676,8 +51298,12 @@ static int assert_pager_state(Pager *p){
** to "print *pPager" in gdb:
**
** (gdb) printf "%s", print_pager_state(pPager)
+**
+** This routine has external linkage in order to suppress compiler warnings
+** about an unused function. It is enclosed within SQLITE_DEBUG and so does
+** not appear in normal builds.
*/
-static char *print_pager_state(Pager *p){
+char *print_pager_state(Pager *p){
static char zRet[1024];
sqlite3_snprintf(1024, zRet,
@@ -48893,7 +51519,7 @@ static int jrnlBufferSize(Pager *pPager){
#endif
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- if( dc&SQLITE_IOCAP_BATCH_ATOMIC ){
+ if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){
return -1;
}
#endif
@@ -49443,7 +52069,6 @@ static void pager_reset(Pager *pPager){
** Return the pPager->iDataVersion value
*/
SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
- assert( pPager->eState>PAGER_OPEN );
return pPager->iDataVersion;
}
@@ -49809,7 +52434,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
rc = pager_truncate(pPager, pPager->dbSize);
}
- if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
+ if( rc==SQLITE_OK && bCommit ){
rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
}
@@ -50628,9 +53253,7 @@ end_playback:
** assertion that the transaction counter was modified.
*/
#ifdef SQLITE_DEBUG
- if( pPager->fd->pMethods ){
- sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
- }
+ sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
#endif
/* If this playback is happening automatically as a result of an IO or
@@ -51383,20 +54006,18 @@ static int pagerOpentemp(
** retried. If it returns zero, then the SQLITE_BUSY error is
** returned to the caller of the pager API function.
*/
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
+SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(
Pager *pPager, /* Pager object */
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
){
+ void **ap;
pPager->xBusyHandler = xBusyHandler;
pPager->pBusyHandlerArg = pBusyHandlerArg;
-
- if( isOpen(pPager->fd) ){
- void **ap = (void **)&pPager->xBusyHandler;
- assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
- assert( ap[1]==pBusyHandlerArg );
- sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
- }
+ ap = (void **)&pPager->xBusyHandler;
+ assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
+ assert( ap[1]==pBusyHandlerArg );
+ sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
}
/*
@@ -51782,6 +54403,30 @@ static void pagerFreeMapHdrs(Pager *pPager){
}
}
+/* Verify that the database file has not be deleted or renamed out from
+** under the pager. Return SQLITE_OK if the database is still where it ought
+** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
+** code from sqlite3OsAccess()) if the database has gone missing.
+*/
+static int databaseIsUnmoved(Pager *pPager){
+ int bHasMoved = 0;
+ int rc;
+
+ if( pPager->tempFile ) return SQLITE_OK;
+ if( pPager->dbSize==0 ) return SQLITE_OK;
+ assert( pPager->zFilename && pPager->zFilename[0] );
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+ if( rc==SQLITE_NOTFOUND ){
+ /* If the HAS_MOVED file-control is unimplemented, assume that the file
+ ** has not been moved. That is the historical behavior of SQLite: prior to
+ ** version 3.8.3, it never checked */
+ rc = SQLITE_OK;
+ }else if( rc==SQLITE_OK && bHasMoved ){
+ rc = SQLITE_READONLY_DBMOVED;
+ }
+ return rc;
+}
+
/*
** Shutdown the page cache. Free all memory and close all files.
@@ -51798,8 +54443,7 @@ static void pagerFreeMapHdrs(Pager *pPager){
** to the caller.
*/
SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
- u8 *pTmp = (u8 *)pPager->pTmpSpace;
-
+ u8 *pTmp = (u8*)pPager->pTmpSpace;
assert( db || pagerUseWal(pPager)==0 );
assert( assert_pager_state(pPager) );
disable_simulated_io_errors();
@@ -51808,11 +54452,17 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
- assert( db || pPager->pWal==0 );
- sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,
- (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
- );
- pPager->pWal = 0;
+ {
+ u8 *a = 0;
+ assert( db || pPager->pWal==0 );
+ if( db && 0==(db->flags & SQLITE_NoCkptOnClose)
+ && SQLITE_OK==databaseIsUnmoved(pPager)
+ ){
+ a = pTmp;
+ }
+ sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
+ pPager->pWal = 0;
+ }
#endif
pager_reset(pPager);
if( MEMDB ){
@@ -52269,6 +54919,7 @@ static int pagerStress(void *p, PgHdr *pPg){
return SQLITE_OK;
}
+ pPager->aStat[PAGER_STAT_SPILL]++;
pPg->pDirty = 0;
if( pagerUseWal(pPager) ){
/* Write a single frame for this page to the log. */
@@ -52374,6 +55025,11 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
int rc = SQLITE_OK; /* Return code */
int tempFile = 0; /* True for temp files (incl. in-memory files) */
int memDb = 0; /* True if this is an in-memory file */
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ int memJM = 0; /* Memory journal mode */
+#else
+# define memJM 0
+#endif
int readOnly = 0; /* True if this is a read-only file */
int journalFileSize; /* Bytes to allocate for each journal fd */
char *zPathname = 0; /* Full path to database file */
@@ -52501,7 +55157,10 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
int fout = 0; /* VFS flags returned by xOpen() */
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
assert( !memDb );
- readOnly = (fout&SQLITE_OPEN_READONLY);
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
+#endif
+ readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
/* If the file was successfully opened for read/write access,
** choose a default page size in case we have to create the
@@ -52632,7 +55291,7 @@ act_like_temp_file:
setSectorSize(pPager);
if( !useJournal ){
pPager->journalMode = PAGER_JOURNALMODE_OFF;
- }else if( memDb ){
+ }else if( memDb || memJM ){
pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
}
/* pPager->xBusyHandler = 0; */
@@ -52647,30 +55306,6 @@ act_like_temp_file:
}
-/* Verify that the database file has not be deleted or renamed out from
-** under the pager. Return SQLITE_OK if the database is still were it ought
-** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
-** code from sqlite3OsAccess()) if the database has gone missing.
-*/
-static int databaseIsUnmoved(Pager *pPager){
- int bHasMoved = 0;
- int rc;
-
- if( pPager->tempFile ) return SQLITE_OK;
- if( pPager->dbSize==0 ) return SQLITE_OK;
- assert( pPager->zFilename && pPager->zFilename[0] );
- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
- if( rc==SQLITE_NOTFOUND ){
- /* If the HAS_MOVED file-control is unimplemented, assume that the file
- ** has not been moved. That is the historical behavior of SQLite: prior to
- ** version 3.8.3, it never checked */
- rc = SQLITE_OK;
- }else if( rc==SQLITE_OK && bHasMoved ){
- rc = SQLITE_READONLY_DBMOVED;
- }
- return rc;
-}
-
/*
** This function is called after transitioning from PAGER_UNLOCK to
@@ -53259,7 +55894,7 @@ static int getPageMMap(
}
if( pPg==0 ){
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
- }else{
+ }else{
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
}
if( pPg ){
@@ -53358,6 +55993,7 @@ SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
+ sqlite3PagerResetLockTimeout(pPager);
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
@@ -53953,12 +56589,9 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
*/
SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
int rc = SQLITE_OK;
-
- if( isOpen(pPager->fd) ){
- void *pArg = (void*)zMaster;
- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
- if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
- }
+ void *pArg = (void*)zMaster;
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
if( rc==SQLITE_OK && !pPager->noSync ){
assert( !MEMDB );
rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
@@ -54053,9 +56686,10 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
** backup in progress needs to be restarted. */
sqlite3BackupRestart(pPager->pBackup);
}else{
+ PgHdr *pList;
if( pagerUseWal(pPager) ){
- PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
PgHdr *pPageOne = 0;
+ pList = sqlite3PcacheDirtyList(pPager->pPCache);
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
@@ -54076,14 +56710,14 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
** should be used. No rollback journal is created if batch-atomic-write
** is enabled.
*/
- sqlite3_file *fd = pPager->fd;
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
- const int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
+ sqlite3_file *fd = pPager->fd;
+ int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
&& (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
&& !pPager->noSync
&& sqlite3JournalIsInMemory(pPager->jfd);
#else
-# define bBatch 0
+# define bBatch 0
#endif
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
@@ -54135,15 +56769,16 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
}
}
}
-#else
+#else /* SQLITE_ENABLE_ATOMIC_WRITE */
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
if( zMaster ){
rc = sqlite3JournalCreate(pPager->jfd);
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ assert( bBatch==0 );
}
#endif
rc = pager_incr_changecounter(pPager, 0);
-#endif
+#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
/* Write the master journal name into the journal file. If a master
@@ -54167,23 +56802,36 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
rc = syncJournal(pPager, 0);
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ pList = sqlite3PcacheDirtyList(pPager->pPCache);
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
if( bBatch ){
- /* The pager is now in DBMOD state. But regardless of what happens
- ** next, attempting to play the journal back into the database would
- ** be unsafe. Close it now to make sure that does not happen. */
- sqlite3OsClose(pPager->jfd);
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- }
- rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
- if( bBatch ){
if( rc==SQLITE_OK ){
- rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
+ rc = pager_write_pagelist(pPager, pList);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
+ }
+ }
+
+ if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsClose(pPager->jfd);
+ goto commit_phase_one_exit;
+ }
+ bBatch = 0;
}else{
- sqlite3OsFileControl(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
+ sqlite3OsClose(pPager->jfd);
}
}
+#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+ if( bBatch==0 ){
+ rc = pager_write_pagelist(pPager, pList);
+ }
if( rc!=SQLITE_OK ){
assert( rc!=SQLITE_IOERR_BLOCKED );
goto commit_phase_one_exit;
@@ -54404,8 +57052,12 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
#endif
/*
-** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
-** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
+** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
+** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
+** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because
+** it was added later.
+**
+** Before returning, *pnVal is incremented by the
** current cache hit or miss count, according to the value of eStat. If the
** reset parameter is non-zero, the cache hit or miss count is zeroed before
** returning.
@@ -54415,15 +57067,18 @@ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, i
assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
|| eStat==SQLITE_DBSTATUS_CACHE_MISS
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE
+ || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
);
assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
- assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
+ assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1
+ && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 );
- *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
+ eStat -= SQLITE_DBSTATUS_CACHE_HIT;
+ *pnVal += pPager->aStat[eStat];
if( reset ){
- pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
+ pPager->aStat[eStat] = 0;
}
}
@@ -54627,6 +57282,16 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+/*
+** Reset the lock timeout for pager.
+*/
+SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
+ int x = 0;
+ sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
+}
+#endif
+
/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
@@ -54918,13 +57583,6 @@ SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
u8 eOld = pPager->journalMode; /* Prior journalmode */
-#ifdef SQLITE_DEBUG
- /* The print_pager_state() routine is intended to be used by the debugger
- ** only. We invoke it once here to suppress a compiler warning. */
- print_pager_state(pPager);
-#endif
-
-
/* The eMode parameter is always valid */
assert( eMode==PAGER_JOURNALMODE_DELETE
|| eMode==PAGER_JOURNALMODE_TRUNCATE
@@ -55087,6 +57745,7 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
+ sqlite3PagerResetLockTimeout(pPager);
}
return rc;
}
@@ -55292,6 +57951,38 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){
}
return rc;
}
+
+/*
+** The caller currently has a read transaction open on the database.
+** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise,
+** this function takes a SHARED lock on the CHECKPOINTER slot and then
+** checks if the snapshot passed as the second argument is still
+** available. If so, SQLITE_OK is returned.
+**
+** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
+** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
+** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
+** lock is released before returning.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){
+ int rc;
+ if( pPager->pWal ){
+ rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ return rc;
+}
+
+/*
+** Release a lock obtained by an earlier successful call to
+** sqlite3PagerSnapshotCheck().
+*/
+SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
+ assert( pPager->pWal );
+ return sqlite3WalSnapshotUnlock(pPager->pWal);
+}
+
#endif /* SQLITE_ENABLE_SNAPSHOT */
#endif /* !SQLITE_OMIT_WAL */
@@ -55447,6 +58138,10 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
** on a network filesystem. All users of the database must be able to
** share memory.
**
+** In the default unix and windows implementation, the wal-index is a mmapped
+** file whose name is the database name with a "-shm" suffix added. For that
+** reason, the wal-index is sometimes called the "shm" file.
+**
** The wal-index is transient. After a crash, the wal-index can (and should
** be) reconstructed from the original WAL file. In fact, the VFS is required
** to either truncate or zero the header of the wal-index when the last
@@ -55570,6 +58265,18 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
#endif
/*
+** WAL mode depends on atomic aligned 32-bit loads and stores in a few
+** places. The following macros try to make this explicit.
+*/
+#if GCC_VESRION>=5004000
+# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
+# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
+#else
+# define AtomicLoad(PTR) (*(PTR))
+# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
+#endif
+
+/*
** The maximum (and only) versions of the wal and wal-index formats
** that may be interpreted by this version of SQLite.
**
@@ -55586,9 +58293,18 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
#define WALINDEX_MAX_VERSION 3007000
/*
-** Indices of various locking bytes. WAL_NREADER is the number
+** Index numbers for various locking bytes. WAL_NREADER is the number
** of available reader locks and should be at least 3. The default
** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
+**
+** Technically, the various VFSes are free to implement these locks however
+** they see fit. However, compatibility is encouraged so that VFSes can
+** interoperate. The standard implemention used on both unix and windows
+** is for the index number to indicate a byte offset into the
+** WalCkptInfo.aLock[] array in the wal-index header. In other words, all
+** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which
+** should be 120) is the location in the shm file for the first locking
+** byte.
*/
#define WAL_WRITE_LOCK 0
#define WAL_ALL_BUT_WRITE 1
@@ -55712,7 +58428,6 @@ struct WalCkptInfo {
#define WAL_FRAME_HDRSIZE 24
/* Size of write ahead log header, including checksum. */
-/* #define WAL_HDRSIZE 24 */
#define WAL_HDRSIZE 32
/* WAL magic value. Either this value, or the same value with the least
@@ -55758,6 +58473,7 @@ struct Wal {
u8 truncateOnCommit; /* True to truncate WAL file on commit */
u8 syncHeader; /* Fsync the WAL header if true */
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
+ u8 bShmUnreliable; /* SHM content is read-only and unreliable */
WalIndexHdr hdr; /* Wal-index header for current transaction */
u32 minFrame; /* Ignore wal frames before this one */
u32 iReCksum; /* On commit, recalculate checksums from here */
@@ -55847,11 +58563,20 @@ struct WalIterator {
** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
** numbered from zero.
**
+** If the wal-index is currently smaller the iPage pages then the size
+** of the wal-index might be increased, but only if it is safe to do
+** so. It is safe to enlarge the wal-index if pWal->writeLock is true
+** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
+**
** If this call is successful, *ppPage is set to point to the wal-index
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
** then an SQLite error code is returned and *ppPage is set to 0.
*/
-static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
+static SQLITE_NOINLINE int walIndexPageRealloc(
+ Wal *pWal, /* The WAL context */
+ int iPage, /* The page we seek */
+ volatile u32 **ppPage /* Write the page pointer here */
+){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
@@ -55870,16 +58595,19 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
}
/* Request a pointer to the required page from the VFS */
- 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_BKPT;
- }else{
- rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
- pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
- );
+ assert( 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_BKPT;
+ }else{
+ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
+ pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
+ );
+ assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
+ testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
+ if( (rc&0xff)==SQLITE_READONLY ){
+ pWal->readOnly |= WAL_SHM_RDONLY;
if( rc==SQLITE_READONLY ){
- pWal->readOnly |= WAL_SHM_RDONLY;
rc = SQLITE_OK;
}
}
@@ -55889,6 +58617,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
return rc;
}
+static int walIndexPage(
+ Wal *pWal, /* The WAL context */
+ int iPage, /* The page we seek */
+ volatile u32 **ppPage /* Write the page pointer here */
+){
+ if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
+ return walIndexPageRealloc(pWal, iPage, ppPage);
+ }
+ return SQLITE_OK;
+}
/*
** Return a pointer to the WalCkptInfo structure in the wal-index.
@@ -56160,48 +58898,51 @@ static int walNextHash(int iPriorHash){
return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
}
+/*
+** An instance of the WalHashLoc object is used to describe the location
+** of a page hash table in the wal-index. This becomes the return value
+** from walHashGet().
+*/
+typedef struct WalHashLoc WalHashLoc;
+struct WalHashLoc {
+ volatile ht_slot *aHash; /* Start of the wal-index hash table */
+ volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */
+ u32 iZero; /* One less than the frame number of first indexed*/
+};
+
/*
** Return pointers to the hash table and page number array stored on
** page iHash of the wal-index. The wal-index is broken into 32KB pages
** numbered starting from 0.
**
-** Set output variable *paHash to point to the start of the hash table
-** in the wal-index file. Set *piZero to one less than the frame
+** Set output variable pLoc->aHash to point to the start of the hash table
+** in the wal-index file. Set pLoc->iZero to one less than the frame
** number of the first frame indexed by this hash table. If a
** slot in the hash table is set to N, it refers to frame number
-** (*piZero+N) in the log.
+** (pLoc->iZero+N) in the log.
**
-** Finally, set *paPgno so that *paPgno[1] is the page number of the
-** first frame indexed by the hash table, frame (*piZero+1).
+** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
+** first frame indexed by the hash table, frame (pLoc->iZero+1).
*/
static int walHashGet(
Wal *pWal, /* WAL handle */
int iHash, /* Find the iHash'th table */
- volatile ht_slot **paHash, /* OUT: Pointer to hash index */
- volatile u32 **paPgno, /* OUT: Pointer to page number array */
- u32 *piZero /* OUT: Frame associated with *paPgno[0] */
+ WalHashLoc *pLoc /* OUT: Hash table location */
){
int rc; /* Return code */
- volatile u32 *aPgno;
- rc = walIndexPage(pWal, iHash, &aPgno);
+ rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
assert( rc==SQLITE_OK || iHash>0 );
if( rc==SQLITE_OK ){
- u32 iZero;
- volatile ht_slot *aHash;
-
- aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
+ pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
if( iHash==0 ){
- aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
- iZero = 0;
+ pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
+ pLoc->iZero = 0;
}else{
- iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
+ pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
}
-
- *paPgno = &aPgno[-1];
- *paHash = aHash;
- *piZero = iZero;
+ pLoc->aPgno = &pLoc->aPgno[-1];
}
return rc;
}
@@ -56247,9 +58988,7 @@ static u32 walFramePgno(Wal *pWal, u32 iFrame){
** actually needed.
*/
static void walCleanupHash(Wal *pWal){
- volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */
- volatile u32 *aPgno = 0; /* Page number array for hash table */
- u32 iZero = 0; /* frame == (aHash[x]+iZero) */
+ WalHashLoc sLoc; /* Hash table location */
int iLimit = 0; /* Zero values greater than this */
int nByte; /* Number of bytes to zero in aPgno[] */
int i; /* Used to iterate through aHash[] */
@@ -56267,24 +59006,24 @@ static void walCleanupHash(Wal *pWal){
*/
assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
- walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
+ walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
/* Zero all hash-table entries that correspond to frame numbers greater
** than pWal->hdr.mxFrame.
*/
- iLimit = pWal->hdr.mxFrame - iZero;
+ iLimit = pWal->hdr.mxFrame - sLoc.iZero;
assert( iLimit>0 );
for(i=0; i<HASHTABLE_NSLOT; i++){
- if( aHash[i]>iLimit ){
- aHash[i] = 0;
+ if( sLoc.aHash[i]>iLimit ){
+ sLoc.aHash[i] = 0;
}
}
/* Zero the entries in the aPgno array that correspond to frames with
** frame numbers greater than pWal->hdr.mxFrame.
*/
- nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
- memset((void *)&aPgno[iLimit+1], 0, nByte);
+ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
+ memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
/* Verify that the every entry in the mapping region is still reachable
@@ -56294,10 +59033,10 @@ static void walCleanupHash(Wal *pWal){
int j; /* Loop counter */
int iKey; /* Hash key */
for(j=1; j<=iLimit; j++){
- for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){
- if( aHash[iKey]==j ) break;
+ for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
+ if( sLoc.aHash[iKey]==j ) break;
}
- assert( aHash[iKey]==j );
+ assert( sLoc.aHash[iKey]==j );
}
}
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
@@ -56310,11 +59049,9 @@ static void walCleanupHash(Wal *pWal){
*/
static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
int rc; /* Return code */
- u32 iZero = 0; /* One less than frame number of aPgno[1] */
- volatile u32 *aPgno = 0; /* Page number array */
- volatile ht_slot *aHash = 0; /* Hash table */
+ WalHashLoc sLoc; /* Wal-index hash table location */
- rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
+ rc = walHashGet(pWal, walFramePage(iFrame), &sLoc);
/* Assuming the wal-index file was successfully mapped, populate the
** page number array and hash table entry.
@@ -56324,15 +59061,16 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
int idx; /* Value to write to hash-table slot */
int nCollide; /* Number of hash collisions */
- idx = iFrame - iZero;
+ idx = iFrame - sLoc.iZero;
assert( idx <= HASHTABLE_NSLOT/2 + 1 );
/* If this is the first entry to be added to this hash-table, zero the
** entire hash table and aPgno[] array before proceeding.
*/
if( idx==1 ){
- int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
- memset((void*)&aPgno[1], 0, nByte);
+ int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
+ - (u8 *)&sLoc.aPgno[1]);
+ memset((void*)&sLoc.aPgno[1], 0, nByte);
}
/* If the entry in aPgno[] is already set, then the previous writer
@@ -56341,18 +59079,18 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
** Remove the remnants of that writers uncommitted transaction from
** the hash-table before writing any new entries.
*/
- if( aPgno[idx] ){
+ if( sLoc.aPgno[idx] ){
walCleanupHash(pWal);
- assert( !aPgno[idx] );
+ assert( !sLoc.aPgno[idx] );
}
/* Write the aPgno[] array entry and the hash-table slot. */
nCollide = idx;
- for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
+ for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
}
- aPgno[idx] = iPage;
- aHash[iKey] = (ht_slot)idx;
+ sLoc.aPgno[idx] = iPage;
+ sLoc.aHash[iKey] = (ht_slot)idx;
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
/* Verify that the number of entries in the hash table exactly equals
@@ -56361,7 +59099,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
{
int i; /* Loop counter */
int nEntry = 0; /* Number of entries in the hash table */
- for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
+ for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; }
assert( nEntry==idx );
}
@@ -56373,10 +59111,12 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
if( (idx&0x3ff)==0 ){
int i; /* Loop counter */
for(i=1; i<=idx; i++){
- for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
- if( aHash[iKey]==i ) break;
+ for(iKey=walHash(sLoc.aPgno[i]);
+ sLoc.aHash[iKey];
+ iKey=walNextHash(iKey)){
+ if( sLoc.aHash[iKey]==i ) break;
}
- assert( aHash[iKey]==i );
+ assert( sLoc.aHash[iKey]==i );
}
}
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
@@ -56402,7 +59142,6 @@ static int walIndexRecover(Wal *pWal){
i64 nSize; /* Size of log file */
u32 aFrameCksum[2] = {0, 0};
int iLock; /* Lock offset to lock for checkpoint */
- int nLock; /* Number of locks to hold */
/* Obtain an exclusive lock on all byte in the locking range not already
** locked by the caller. The caller is guaranteed to have locked the
@@ -56415,11 +59154,17 @@ static int walIndexRecover(Wal *pWal){
assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
assert( pWal->writeLock );
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
- nLock = SQLITE_SHM_NLOCK - iLock;
- rc = walLockExclusive(pWal, iLock, nLock);
+ rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ if( rc==SQLITE_OK ){
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+ if( rc!=SQLITE_OK ){
+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ }
+ }
if( rc ){
return rc;
}
+
WALTRACE(("WAL%p: recovery begin...\n", pWal));
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
@@ -56557,7 +59302,8 @@ finished:
recovery_error:
WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
- walUnlockExclusive(pWal, iLock, nLock);
+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
return rc;
}
@@ -56565,13 +59311,14 @@ recovery_error:
** Close an open wal-index.
*/
static void walIndexClose(Wal *pWal, int isDelete){
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){
int i;
for(i=0; i<pWal->nWiData; i++){
sqlite3_free((void *)pWal->apWiData[i]);
pWal->apWiData[i] = 0;
}
- }else{
+ }
+ if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
}
}
@@ -56858,8 +59605,9 @@ static void walIteratorFree(WalIterator *p){
/*
** Construct a WalInterator object that can be used to loop over all
-** pages in the WAL in ascending order. The caller must hold the checkpoint
-** lock.
+** pages in the WAL following frame nBackfill in ascending order. Frames
+** nBackfill or earlier may be included - excluding them is an optimization
+** only. The caller must hold the checkpoint lock.
**
** On success, make *pp point to the newly allocated WalInterator object
** return SQLITE_OK. Otherwise, return an error code. If this routine
@@ -56868,7 +59616,7 @@ static void walIteratorFree(WalIterator *p){
** The calling routine should invoke walIteratorFree() to destroy the
** WalIterator object when it has finished with it.
*/
-static int walIteratorInit(Wal *pWal, WalIterator **pp){
+static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
WalIterator *p; /* Return value */
int nSegment; /* Number of segments to merge */
u32 iLast; /* Last frame in log */
@@ -56905,40 +59653,39 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
rc = SQLITE_NOMEM_BKPT;
}
- for(i=0; rc==SQLITE_OK && i<nSegment; i++){
- volatile ht_slot *aHash;
- u32 iZero;
- volatile u32 *aPgno;
+ for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
+ WalHashLoc sLoc;
- rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
+ rc = walHashGet(pWal, i, &sLoc);
if( rc==SQLITE_OK ){
int j; /* Counter variable */
int nEntry; /* Number of entries in this segment */
ht_slot *aIndex; /* Sorted index for this segment */
- aPgno++;
+ sLoc.aPgno++;
if( (i+1)==nSegment ){
- nEntry = (int)(iLast - iZero);
+ nEntry = (int)(iLast - sLoc.iZero);
}else{
- nEntry = (int)((u32*)aHash - (u32*)aPgno);
+ nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
}
- aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
- iZero++;
+ aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero];
+ sLoc.iZero++;
for(j=0; j<nEntry; j++){
aIndex[j] = (ht_slot)j;
}
- walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
- p->aSegment[i].iZero = iZero;
+ walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry);
+ p->aSegment[i].iZero = sLoc.iZero;
p->aSegment[i].nEntry = nEntry;
p->aSegment[i].aIndex = aIndex;
- p->aSegment[i].aPgno = (u32 *)aPgno;
+ p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
}
}
sqlite3_free(aTmp);
if( rc!=SQLITE_OK ){
walIteratorFree(p);
+ p = 0;
}
*pp = p;
return rc;
@@ -57061,13 +59808,6 @@ static int walCheckpoint(
pInfo = walCkptInfo(pWal);
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
- /* Allocate the iterator */
- rc = walIteratorInit(pWal, &pIter);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pIter );
-
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
@@ -57104,10 +59844,15 @@ static int walCheckpoint(
}
}
- if( pInfo->nBackfill<mxSafeFrame
+ /* Allocate the iterator */
+ if( pInfo->nBackfill<mxSafeFrame ){
+ rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
+ assert( rc==SQLITE_OK || pIter==0 );
+ }
+
+ if( pIter
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
){
- i64 nSize; /* Current size of database file */
u32 nBackfill = pInfo->nBackfill;
pInfo->nBackfillAttempted = mxSafeFrame;
@@ -57120,6 +59865,7 @@ static int walCheckpoint(
*/
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
+ i64 nSize; /* Current size of database file */
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
@@ -57365,6 +60111,12 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
}
/*
+** This is the value that walTryBeginRead returns when it needs to
+** be retried.
+*/
+#define WAL_RETRY (-1)
+
+/*
** Read the wal-index header from the wal-index and into pWal->hdr.
** If the wal-header appears to be corrupt, try to reconstruct the
** wal-index from the WAL before returning.
@@ -57387,9 +60139,29 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
assert( pChanged );
rc = walIndexPage(pWal, 0, &page0);
if( rc!=SQLITE_OK ){
- return rc;
- };
- assert( page0 || pWal->writeLock==0 );
+ assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */
+ if( rc==SQLITE_READONLY_CANTINIT ){
+ /* The SQLITE_READONLY_CANTINIT return means that the shared-memory
+ ** was openable but is not writable, and this thread is unable to
+ ** confirm that another write-capable connection has the shared-memory
+ ** open, and hence the content of the shared-memory is unreliable,
+ ** since the shared-memory might be inconsistent with the WAL file
+ ** and there is no writer on hand to fix it. */
+ assert( page0==0 );
+ assert( pWal->writeLock==0 );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ pWal->bShmUnreliable = 1;
+ pWal->exclusiveMode = WAL_HEAPMEMORY_MODE;
+ *pChanged = 1;
+ }else{
+ return rc; /* Any other non-OK return is just an error */
+ }
+ }else{
+ /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
+ ** is zero, which prevents the SHM from growing */
+ testcase( page0!=0 );
+ }
+ assert( page0!=0 || pWal->writeLock==0 );
/* If the first page of the wal-index has been mapped, try to read the
** wal-index header immediately, without holding any lock. This usually
@@ -57403,7 +60175,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
*/
assert( badHdr==0 || pWal->writeLock==0 );
if( badHdr ){
- if( pWal->readOnly & WAL_SHM_RDONLY ){
+ if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
@@ -57433,15 +60205,193 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
rc = SQLITE_CANTOPEN_BKPT;
}
+ if( pWal->bShmUnreliable ){
+ if( rc!=SQLITE_OK ){
+ walIndexClose(pWal, 0);
+ pWal->bShmUnreliable = 0;
+ assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
+ /* walIndexRecover() might have returned SHORT_READ if a concurrent
+ ** writer truncated the WAL out from under it. If that happens, it
+ ** indicates that a writer has fixed the SHM file for us, so retry */
+ if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
+ }
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
+ }
return rc;
}
/*
-** This is the value that walTryBeginRead returns when it needs to
-** be retried.
+** Open a transaction in a connection where the shared-memory is read-only
+** and where we cannot verify that there is a separate write-capable connection
+** on hand to keep the shared-memory up-to-date with the WAL file.
+**
+** This can happen, for example, when the shared-memory is implemented by
+** memory-mapping a *-shm file, where a prior writer has shut down and
+** left the *-shm file on disk, and now the present connection is trying
+** to use that database but lacks write permission on the *-shm file.
+** Other scenarios are also possible, depending on the VFS implementation.
+**
+** Precondition:
+**
+** The *-wal file has been read and an appropriate wal-index has been
+** constructed in pWal->apWiData[] using heap memory instead of shared
+** memory.
+**
+** If this function returns SQLITE_OK, then the read transaction has
+** been successfully opened. In this case output variable (*pChanged)
+** is set to true before returning if the caller should discard the
+** contents of the page cache before proceeding. Or, if it returns
+** WAL_RETRY, then the heap memory wal-index has been discarded and
+** the caller should retry opening the read transaction from the
+** beginning (including attempting to map the *-shm file).
+**
+** If an error occurs, an SQLite error code is returned.
*/
-#define WAL_RETRY (-1)
+static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
+ i64 szWal; /* Size of wal file on disk in bytes */
+ i64 iOffset; /* Current offset when reading wal file */
+ u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */
+ u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */
+ int szFrame; /* Number of bytes in buffer aFrame[] */
+ u8 *aData; /* Pointer to data part of aFrame buffer */
+ volatile void *pDummy; /* Dummy argument for xShmMap */
+ int rc; /* Return code */
+ u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */
+
+ assert( pWal->bShmUnreliable );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ assert( pWal->nWiData>0 && pWal->apWiData[0] );
+
+ /* Take WAL_READ_LOCK(0). This has the effect of preventing any
+ ** writers from running a checkpoint, but does not stop them
+ ** from running recovery. */
+ rc = walLockShared(pWal, WAL_READ_LOCK(0));
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+ pWal->readLock = 0;
+
+ /* Check to see if a separate writer has attached to the shared-memory area,
+ ** thus making the shared-memory "reliable" again. Do this by invoking
+ ** the xShmMap() routine of the VFS and looking to see if the return
+ ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
+ **
+ ** If the shared-memory is now "reliable" return WAL_RETRY, which will
+ ** cause the heap-memory WAL-index to be discarded and the actual
+ ** shared memory to be used in its place.
+ **
+ ** This step is important because, even though this connection is holding
+ ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
+ ** have already checkpointed the WAL file and, while the current
+ ** is active, wrap the WAL and start overwriting frames that this
+ ** process wants to use.
+ **
+ ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
+ ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
+ ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
+ ** even if some external agent does a "chmod" to make the shared-memory
+ ** writable by us, until sqlite3OsShmUnmap() has been called.
+ ** This is a requirement on the VFS implementation.
+ */
+ rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
+ assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
+ if( rc!=SQLITE_READONLY_CANTINIT ){
+ rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* We reach this point only if the real shared-memory is still unreliable.
+ ** Assume the in-memory WAL-index substitute is correct and load it
+ ** into pWal->hdr.
+ */
+ memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));
+
+ /* Make sure some writer hasn't come in and changed the WAL file out
+ ** from under us, then disconnected, while we were not looking.
+ */
+ rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( szWal<WAL_HDRSIZE ){
+ /* If the wal file is too small to contain a wal-header and the
+ ** wal-index header has mxFrame==0, then it must be safe to proceed
+ ** reading the database file only. However, the page cache cannot
+ ** be trusted, as a read/write connection may have connected, written
+ ** the db, run a checkpoint, truncated the wal file and disconnected
+ ** since this client's last read transaction. */
+ *pChanged = 1;
+ rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Check the salt keys at the start of the wal file still match. */
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
+ /* Some writer has wrapped the WAL file while we were not looking.
+ ** Return WAL_RETRY which will cause the in-memory WAL-index to be
+ ** rebuilt. */
+ rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Allocate a buffer to read frames into */
+ szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
+ aFrame = (u8 *)sqlite3_malloc64(szFrame);
+ if( aFrame==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto begin_unreliable_shm_out;
+ }
+ aData = &aFrame[WAL_FRAME_HDRSIZE];
+
+ /* Check to see if a complete transaction has been appended to the
+ ** wal file since the heap-memory wal-index was created. If so, the
+ ** heap-memory wal-index is discarded and WAL_RETRY returned to
+ ** the caller. */
+ aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
+ aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
+ for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
+ iOffset+szFrame<=szWal;
+ iOffset+=szFrame
+ ){
+ u32 pgno; /* Database page number for frame */
+ u32 nTruncate; /* dbsize field from frame header */
+
+ /* Read and decode the next log frame. */
+ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
+ if( rc!=SQLITE_OK ) break;
+ if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;
+
+ /* If nTruncate is non-zero, then a complete transaction has been
+ ** appended to this wal file. Set rc to WAL_RETRY and break out of
+ ** the loop. */
+ if( nTruncate ){
+ rc = WAL_RETRY;
+ break;
+ }
+ }
+ pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
+ pWal->hdr.aFrameCksum[1] = aSaveCksum[1];
+
+ begin_unreliable_shm_out:
+ sqlite3_free(aFrame);
+ if( rc!=SQLITE_OK ){
+ int i;
+ for(i=0; i<pWal->nWiData; i++){
+ sqlite3_free((void*)pWal->apWiData[i]);
+ pWal->apWiData[i] = 0;
+ }
+ pWal->bShmUnreliable = 0;
+ sqlite3WalEndReadTransaction(pWal);
+ *pChanged = 1;
+ }
+ return rc;
+}
/*
** Attempt to start a read transaction. This might fail due to a race or
@@ -57457,7 +60407,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
** checkpointed. If useWal==0 then this routine calls walIndexReadHdr()
** to make a copy of the wal-index header into pWal->hdr. If the
** wal-index header has changed, *pChanged is set to 1 (as an indication
-** to the caller that the local paget cache is obsolete and needs to be
+** to the caller that the local page cache is obsolete and needs to be
** flushed.) When useWal==1, the wal-index header is assumed to already
** be loaded and the pChanged parameter is unused.
**
@@ -57503,6 +60453,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
assert( pWal->readLock<0 ); /* Not currently locked */
+ /* useWal may only be set for read/write connections */
+ assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
+
/* Take steps to avoid spinning forever if there is a protocol error.
**
** Circumstances that cause a RETRY should only last for the briefest
@@ -57531,7 +60484,10 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
if( !useWal ){
- rc = walIndexReadHdr(pWal, pChanged);
+ assert( rc==SQLITE_OK );
+ if( pWal->bShmUnreliable==0 ){
+ rc = walIndexReadHdr(pWal, pChanged);
+ }
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
** then convert BUSY errors to WAL_RETRY. If recovery is known to
@@ -57560,13 +60516,17 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
if( rc!=SQLITE_OK ){
return rc;
}
+ else if( pWal->bShmUnreliable ){
+ return walBeginShmUnreliable(pWal, pChanged);
+ }
}
+ assert( pWal->nWiData>0 );
+ assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
+ if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
- || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
+ && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
@@ -57613,7 +60573,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
#endif
for(i=1; i<WAL_NREADER; i++){
- u32 thisMark = pInfo->aReadMark[i];
+ u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
if( mxReadMark<=thisMark && thisMark<=mxFrame ){
assert( thisMark!=READMARK_NOT_USED );
mxReadMark = thisMark;
@@ -57626,7 +60586,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
- mxReadMark = pInfo->aReadMark[i] = mxFrame;
+ mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
@@ -57637,7 +60597,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
if( mxI==0 ){
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
- return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
+ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
}
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
@@ -57678,9 +60638,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** we can guarantee that the checkpointer that set nBackfill could not
** see any pages past pWal->hdr.mxFrame, this problem does not come up.
*/
- pWal->minFrame = pInfo->nBackfill+1;
+ pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
walShmBarrier(pWal);
- if( pInfo->aReadMark[mxI]!=mxReadMark
+ if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
@@ -57731,16 +60691,14 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
}else{
u32 i = pInfo->nBackfillAttempted;
for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
- volatile ht_slot *dummy;
- volatile u32 *aPgno; /* Array of page numbers */
- u32 iZero; /* Frame corresponding to aPgno[0] */
+ WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
i64 iWalOff; /* Offset of wal file entry */
- rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
+ rc = walHashGet(pWal, walFramePage(i), &sLoc);
if( rc!=SQLITE_OK ) break;
- pgno = aPgno[i-iZero];
+ pgno = sLoc.aPgno[i-sLoc.iZero];
iDbOff = (i64)(pgno-1) * szPage;
if( iDbOff+szPage<=szDb ){
@@ -57781,7 +60739,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
**
** If the database contents have changes since the previous read
** transaction, then *pChanged is set to 1 before returning. The
-** Pager layer will use this to know that is cache is stale and
+** Pager layer will use this to know that its cache is stale and
** needs to be flushed.
*/
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
@@ -57843,7 +60801,7 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
- ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
+ ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
** with *pSnapshot and set *pChanged as appropriate for opening the
** snapshot. */
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
@@ -57853,11 +60811,12 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
*pChanged = bChanged;
}else{
- rc = SQLITE_BUSY_SNAPSHOT;
+ rc = SQLITE_ERROR_SNAPSHOT;
}
/* Release the shared CKPT lock obtained above. */
walUnlockShared(pWal, WAL_CKPT_LOCK);
+ pWal->minFrame = 1;
}
@@ -57909,7 +60868,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
** then the WAL is ignored by the reader so return early, as if the
** WAL were empty.
*/
- if( iLast==0 || pWal->readLock==0 ){
+ if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){
*piRead = 0;
return SQLITE_OK;
}
@@ -57940,22 +60899,21 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
** table after the current read-transaction had started.
*/
iMinHash = walFramePage(pWal->minFrame);
- for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
- volatile ht_slot *aHash; /* Pointer to hash table */
- volatile u32 *aPgno; /* Pointer to array of page numbers */
- u32 iZero; /* Frame number corresponding to aPgno[0] */
+ for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
+ WalHashLoc sLoc; /* Hash table location */
int iKey; /* Hash slot index */
int nCollide; /* Number of hash collisions remaining */
int rc; /* Error code */
- rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
+ rc = walHashGet(pWal, iHash, &sLoc);
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
- for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
- u32 iFrame = aHash[iKey] + iZero;
- if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
+ for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
+ u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
+ if( iFrame<=iLast && iFrame>=pWal->minFrame
+ && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
@@ -57963,6 +60921,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
return SQLITE_CORRUPT_BKPT;
}
}
+ if( iRead ) break;
}
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
@@ -57972,8 +60931,8 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
{
u32 iRead2 = 0;
u32 iTest;
- assert( pWal->minFrame>0 );
- for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
+ assert( pWal->bShmUnreliable || pWal->minFrame>0 );
+ for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){
if( walFramePgno(pWal, iTest)==pgno ){
iRead2 = iTest;
break;
@@ -58749,24 +61708,24 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
if( op==0 ){
- if( pWal->exclusiveMode ){
- pWal->exclusiveMode = 0;
+ if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
- pWal->exclusiveMode = 1;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
- rc = pWal->exclusiveMode==0;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}else{
/* Already in locking_mode=NORMAL */
rc = 0;
}
}else if( op>0 ){
- assert( pWal->exclusiveMode==0 );
+ assert( pWal->exclusiveMode==WAL_NORMAL_MODE );
assert( pWal->readLock>=0 );
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
- pWal->exclusiveMode = 1;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
rc = 1;
}else{
- rc = pWal->exclusiveMode==0;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}
return rc;
}
@@ -58829,6 +61788,43 @@ SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
return 0;
}
+
+/*
+** The caller currently has a read transaction open on the database.
+** This function takes a SHARED lock on the CHECKPOINTER slot and then
+** checks if the snapshot passed as the second argument is still
+** available. If so, SQLITE_OK is returned.
+**
+** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
+** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
+** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
+** lock is released before returning.
+*/
+SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){
+ int rc;
+ rc = walLockShared(pWal, WAL_CKPT_LOCK);
+ if( rc==SQLITE_OK ){
+ WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot;
+ if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+ || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted
+ ){
+ rc = SQLITE_ERROR_SNAPSHOT;
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
+ }
+ }
+ return rc;
+}
+
+/*
+** Release a lock obtained by an earlier successful call to
+** sqlite3WalSnapshotCheck().
+*/
+SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){
+ assert( pWal );
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
+}
+
+
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -59377,20 +62373,20 @@ struct BtCursor {
u8 curFlags; /* zero or more BTCF_* flags defined below */
u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
u8 hints; /* As configured by CursorSetHints() */
- int nOvflAlloc; /* Allocated size of aOverflow[] array */
+ int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
+ ** Error code if eState==CURSOR_FAULT */
Btree *pBtree; /* The Btree to which this cursor belongs */
- BtShared *pBt; /* The BtShared this cursor points to */
- BtCursor *pNext; /* Forms a linked list of all cursors */
Pgno *aOverflow; /* Cache of overflow page locations */
- CellInfo info; /* A parse of the cell we are pointing at */
- i64 nKey; /* Size of pKey, or last integer key */
void *pKey; /* Saved key that was cursor last known position */
- Pgno pgnoRoot; /* The root page of this tree */
- int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
- ** Error code if eState==CURSOR_FAULT */
/* All fields above are zeroed when the cursor is allocated. See
** sqlite3BtreeCursorZero(). Fields that follow must be manually
** initialized. */
+#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */
+ BtShared *pBt; /* The BtShared this cursor points to */
+ BtCursor *pNext; /* Forms a linked list of all cursors */
+ CellInfo info; /* A parse of the cell we are pointing at */
+ i64 nKey; /* Size of pKey, or last integer key */
+ Pgno pgnoRoot; /* The root page of this tree */
i8 iPage; /* Index of current page in apPage */
u8 curIntKey; /* Value of apPage[0]->intKey */
u16 ix; /* Current index for apPage[iPage] */
@@ -59440,8 +62436,8 @@ struct BtCursor {
** Do nothing else with this cursor. Any attempt to use the cursor
** should return the error code stored in BtCursor.skipNext
*/
-#define CURSOR_INVALID 0
-#define CURSOR_VALID 1
+#define CURSOR_VALID 0
+#define CURSOR_INVALID 1
#define CURSOR_SKIPNEXT 2
#define CURSOR_REQUIRESEEK 3
#define CURSOR_FAULT 4
@@ -59758,10 +62754,10 @@ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){
skipOk = 0;
}
}
- db->skipBtreeMutex = skipOk;
+ db->noSharedCache = skipOk;
}
SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
- if( db->skipBtreeMutex==0 ) btreeEnterAll(db);
+ if( db->noSharedCache==0 ) btreeEnterAll(db);
}
static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
int i;
@@ -59773,7 +62769,7 @@ static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
}
}
SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
- if( db->skipBtreeMutex==0 ) btreeLeaveAll(db);
+ if( db->noSharedCache==0 ) btreeLeaveAll(db);
}
#ifndef NDEBUG
@@ -59986,6 +62982,34 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){
#define hasReadConflicts(a, b) 0
#endif
+/*
+** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
+** (MemPage*) as an argument. The (MemPage*) must not be NULL.
+**
+** If SQLITE_DEBUG is not defined, then this macro is equivalent to
+** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
+** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
+** with the page number and filename associated with the (MemPage*).
+*/
+#ifdef SQLITE_DEBUG
+int corruptPageError(int lineno, MemPage *p){
+ char *zMsg;
+ sqlite3BeginBenignMalloc();
+ zMsg = sqlite3_mprintf("database corruption page %d of %s",
+ (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
+ );
+ sqlite3EndBenignMalloc();
+ if( zMsg ){
+ sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
+ }
+ sqlite3_free(zMsg);
+ return SQLITE_CORRUPT_BKPT;
+}
+# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
+#else
+# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
+#endif
+
#ifndef SQLITE_OMIT_SHARED_CACHE
#ifdef SQLITE_DEBUG
@@ -60710,7 +63734,11 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
** back to where it ought to be if this routine returns true.
*/
SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
- return pCur->eState!=CURSOR_VALID;
+ assert( EIGHT_BYTE_ALIGNMENT(pCur)
+ || pCur==sqlite3BtreeFakeValidCursor() );
+ assert( offsetof(BtCursor, eState)==0 );
+ assert( sizeof(pCur->eState)==1 );
+ return CURSOR_VALID != *(u8*)pCur;
}
/*
@@ -61274,7 +64302,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]);
if( top>=iFree ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFree2 ){
assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
@@ -61308,13 +64336,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** if PRAGMA cell_size_check=ON.
*/
if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( pc>=iCellFirst && pc<=iCellLast );
size = pPage->xCellSize(pPage, &src[pc]);
cbrk -= size;
if( cbrk<iCellFirst || pc+size>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
testcase( cbrk+size==usableSize );
@@ -61334,7 +64362,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
defragment_out:
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
@@ -61378,7 +64406,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
testcase( x==4 );
testcase( x==3 );
if( size+pc > usableSize ){
- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
return 0;
}else if( x<4 ){
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -61401,7 +64429,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
if( pc<iAddr+size ) break;
}
if( pc ){
- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
}
return 0;
@@ -61449,7 +64477,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
}else{
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
@@ -61539,12 +64567,12 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
if( iFreeBlk<iPtr+4 ){
if( iFreeBlk==0 ) break;
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
iPtr = iFreeBlk;
}
if( iFreeBlk>pPage->pBt->usableSize-4 ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( iFreeBlk>iPtr || iFreeBlk==0 );
@@ -61556,10 +64584,10 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
- if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
if( iEnd > pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
@@ -61572,13 +64600,13 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( iPtr>hdr+1 ){
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){
- if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage);
nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr;
iStart = iPtr;
}
}
- if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
data[hdr+7] -= nFrag;
}
x = get2byte(&data[hdr+5]);
@@ -61586,7 +64614,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
- if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd);
}else{
@@ -61659,7 +64687,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
}else{
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
** an error. */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->max1bytePayload = pBt->max1bytePayload;
return SQLITE_OK;
@@ -61700,7 +64728,7 @@ static int btreeInitPage(MemPage *pPage){
/* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
** the b-tree page type. */
if( decodeFlags(pPage, data[hdr]) ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -61719,7 +64747,7 @@ static int btreeInitPage(MemPage *pPage){
pPage->nCell = get2byte(&data[hdr+3]);
if( pPage->nCell>MX_CELL(pBt) ){
/* To many cells for a single page. The page must be corrupt */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
testcase( pPage->nCell==MX_CELL(pBt) );
/* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
@@ -61747,12 +64775,12 @@ static int btreeInitPage(MemPage *pPage){
testcase( pc==iCellFirst );
testcase( pc==iCellLast );
if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
sz = pPage->xCellSize(pPage, &data[pc]);
testcase( pc+sz==usableSize );
if( pc+sz>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
if( !pPage->leaf ) iCellLast++;
@@ -61770,12 +64798,12 @@ static int btreeInitPage(MemPage *pPage){
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock.
*/
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
while( 1 ){
if( pc>iCellLast ){
/* Freeblock off the end of the page */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]);
@@ -61785,11 +64813,11 @@ static int btreeInitPage(MemPage *pPage){
}
if( next>0 ){
/* Freeblock not in ascending order */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( pc+size>(unsigned int)usableSize ){
/* Last freeblock extends past page end */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
@@ -61801,7 +64829,7 @@ static int btreeInitPage(MemPage *pPage){
** area, according to the page header, lies within the page.
*/
if( nFree>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
pPage->isInit = 1;
@@ -62077,7 +65105,8 @@ static int btreeInvokeBusyHandler(void *pArg){
BtShared *pBt = (BtShared*)pArg;
assert( pBt->db );
assert( sqlite3_mutex_held(pBt->db->mutex) );
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
+ return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
+ sqlite3PagerFile(pBt->pPager));
}
/*
@@ -62255,7 +65284,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
}
pBt->openFlags = (u8)flags;
pBt->db = db;
- sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
+ sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
p->pBt = pBt;
pBt->pCursor = 0;
@@ -62817,6 +65846,10 @@ static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
# define setDefaultSyncFlag(pBt,safety_level)
#endif
+/* Forward declaration */
+static int newDatabase(BtShared*);
+
+
/*
** Get a reference to pPage1 of the database file. This will
** also acquire a readlock on that file.
@@ -62848,6 +65881,9 @@ static int lockBtree(BtShared *pBt){
if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
nPage = nPageFile;
}
+ if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
+ nPage = 0;
+ }
if( nPage>0 ){
u32 pageSize;
u32 usableSize;
@@ -63134,7 +66170,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
+SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
int rc = SQLITE_OK;
@@ -63150,6 +66186,12 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
}
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
+ if( (p->db->flags & SQLITE_ResetDatabase)
+ && sqlite3PagerIsreadonly(pBt->pPager)==0
+ ){
+ pBt->btsFlags &= ~BTS_READ_ONLY;
+ }
+
/* Write transactions are not possible on a read-only database */
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
rc = SQLITE_READONLY;
@@ -63209,6 +66251,11 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
+ }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
+ /* if there was no transaction opened when this function was
+ ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
+ ** code to SQLITE_BUSY. */
+ rc = SQLITE_BUSY;
}
}
}
@@ -63218,6 +66265,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
+ sqlite3PagerResetLockTimeout(pBt->pPager);
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
@@ -63259,14 +66307,18 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
}
}
-
trans_begun:
- if( rc==SQLITE_OK && wrflag ){
- /* This call makes sure that the pager has the correct number of
- ** open savepoints. If the second parameter is greater than 0 and
- ** the sub-journal is not already open, then it will be opened here.
- */
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
+ if( rc==SQLITE_OK ){
+ if( pSchemaVersion ){
+ *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
+ }
+ if( wrflag ){
+ /* This call makes sure that the pager has the correct number of
+ ** open savepoints. If the second parameter is greater than 0 and
+ ** the sub-journal is not already open, then it will be opened here.
+ */
+ rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
+ }
}
btreeIntegrity(p);
@@ -63332,7 +66384,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW2 ){
/* The pointer is always the first 4 bytes of the page in this case. */
if( get4byte(pPage->aData)!=iFrom ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(pPage->aData, iTo);
}else{
@@ -63351,7 +66403,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload ){
if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFrom==get4byte(pCell+info.nSize-4) ){
put4byte(pCell+info.nSize-4, iTo);
@@ -63369,7 +66421,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( i==nCell ){
if( eType!=PTRMAP_BTREE ||
get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
}
@@ -64191,7 +67243,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
** of run-time by skipping the initialization of those elements.
*/
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
- memset(p, 0, offsetof(BtCursor, iPage));
+ memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT));
}
/*
@@ -64234,11 +67286,19 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
** Using this cache reduces the number of calls to btreeParseCell().
*/
#ifndef NDEBUG
+ static int cellInfoEqual(CellInfo *a, CellInfo *b){
+ if( a->nKey!=b->nKey ) return 0;
+ if( a->pPayload!=b->pPayload ) return 0;
+ if( a->nPayload!=b->nPayload ) return 0;
+ if( a->nLocal!=b->nLocal ) return 0;
+ if( a->nSize!=b->nSize ) return 0;
+ return 1;
+ }
static void assertCellInfo(BtCursor *pCur){
CellInfo info;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->pPage, pCur->ix, &info);
- assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
+ assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
}
#else
#define assertCellInfo(x)
@@ -64281,6 +67341,20 @@ SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
return pCur->info.nKey;
}
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/*
+** Return the offset into the database file for the start of the
+** payload to which the cursor is pointing.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pCur->eState==CURSOR_VALID );
+ getCellInfo(pCur);
+ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
+ (i64)(pCur->info.pPayload - pCur->pPage->aData);
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
/*
** Return the number of bytes of payload for the entry that pCur is
** currently pointing to. For table btrees, this will be the amount
@@ -64467,7 +67541,7 @@ static int accessPayload(
** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
** but is recast into its current form to avoid integer overflow problems
*/
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
/* Check if data must be read/written to/from the btree page itself. */
@@ -64500,14 +67574,15 @@ static int accessPayload(
*/
if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
- if( nOvfl>pCur->nOvflAlloc ){
+ if( pCur->aOverflow==0
+ || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
+ ){
Pgno *aNew = (Pgno*)sqlite3Realloc(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
return SQLITE_NOMEM_BKPT;
}else{
- pCur->nOvflAlloc = nOvfl*2;
pCur->aOverflow = aNew;
}
}
@@ -64615,7 +67690,7 @@ static int accessPayload(
if( rc==SQLITE_OK && amt>0 ){
/* Overflow chain ends prematurely */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
return rc;
}
@@ -64893,7 +67968,7 @@ static int moveToRoot(BtCursor *pCur){
** (or the freelist). */
assert( pRoot->intKey==1 || pRoot->intKey==0 );
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
- return SQLITE_CORRUPT_PGNO(pCur->pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pCur->pPage);
}
skip_init:
@@ -64990,6 +68065,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
return rc;
}
+/*
+** This function is a no-op if cursor pCur does not point to a valid row.
+** Otherwise, if pCur is valid, configure it so that the next call to
+** sqlite3BtreeNext() is a no-op.
+*/
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){
+ /* We believe that the cursor must always be in the valid state when
+ ** this routine is called, but the proof is difficult, so we add an
+ ** ALWaYS() test just in case we are wrong. */
+ if( ALWAYS(pCur->eState==CURSOR_VALID) ){
+ pCur->eState = CURSOR_SKIPNEXT;
+ pCur->skipNext = 1;
+ }
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
/* Move the cursor to the last entry in the table. Return SQLITE_OK
** on success. Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
@@ -65166,7 +68258,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
if( pPage->intKeyLeaf ){
while( 0x80 <= *(pCell++) ){
if( pCell>=pPage->aDataEnd ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
}
@@ -65240,7 +68332,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 ){
- rc = SQLITE_CORRUPT_PGNO(pPage->pgno);
+ rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
pCellKey = sqlite3Malloc( nCell+18 );
@@ -65394,7 +68486,16 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
pPage = pCur->pPage;
idx = ++pCur->ix;
- assert( pPage->isInit );
+ if( !pPage->isInit ){
+ /* The only known way for this to happen is for there to be a
+ ** recursive SQL function that does a DELETE operation as part of a
+ ** SELECT which deletes content out from under an active cursor
+ ** in a corrupt database file where the table being DELETE-ed from
+ ** has pages in common with the table being queried. See TH3
+ ** module cov1/btree78.test testcase 220 (2018-06-08) for an
+ ** example. */
+ return SQLITE_CORRUPT_BKPT;
+ }
/* If the database file is corrupt, it is possible for the value of idx
** to be invalid here. This can only occur if a second cursor modifies
@@ -66021,9 +69122,8 @@ static void freePage(MemPage *pPage, int *pRC){
}
/*
-** Free any overflow pages associated with the given Cell. Write the
-** local Cell size (the number of bytes on the original page, omitting
-** overflow) into *pnSize.
+** Free any overflow pages associated with the given Cell. Store
+** size information about the cell in pInfo.
*/
static int clearCell(
MemPage *pPage, /* The page that contains the Cell */
@@ -66041,9 +69141,11 @@ static int clearCell(
if( pInfo->nLocal==pInfo->nPayload ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
- if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
+ testcase( pCell + pInfo->nSize == pPage->aDataEnd );
+ testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
+ if( pCell + pInfo->nSize > pPage->aDataEnd ){
/* Cell extends past end of page */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
ovflPgno = get4byte(pCell + pInfo->nSize - 4);
pBt = pPage->pBt;
@@ -67227,7 +70329,7 @@ static int balance_nonroot(
}
/* Load b.apCell[] with pointers to all cells in pOld. If pOld
- ** constains overflow cells, include them in the b.apCell[] array
+ ** contains overflow cells, include them in the b.apCell[] array
** in the correct spot.
**
** Note that when there are multiple overflow cells, it is always the
@@ -67967,6 +71069,94 @@ static int balance(BtCursor *pCur){
return rc;
}
+/* Overwrite content from pX into pDest. Only do the write if the
+** content is different from what is already there.
+*/
+static int btreeOverwriteContent(
+ MemPage *pPage, /* MemPage on which writing will occur */
+ u8 *pDest, /* Pointer to the place to start writing */
+ const BtreePayload *pX, /* Source of data to write */
+ int iOffset, /* Offset of first byte to write */
+ int iAmt /* Number of bytes to be written */
+){
+ int nData = pX->nData - iOffset;
+ if( nData<=0 ){
+ /* Overwritting with zeros */
+ int i;
+ for(i=0; i<iAmt && pDest[i]==0; i++){}
+ if( i<iAmt ){
+ int rc = sqlite3PagerWrite(pPage->pDbPage);
+ if( rc ) return rc;
+ memset(pDest + i, 0, iAmt - i);
+ }
+ }else{
+ if( nData<iAmt ){
+ /* Mixed read data and zeros at the end. Make a recursive call
+ ** to write the zeros then fall through to write the real data */
+ int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData,
+ iAmt-nData);
+ if( rc ) return rc;
+ iAmt = nData;
+ }
+ if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
+ int rc = sqlite3PagerWrite(pPage->pDbPage);
+ if( rc ) return rc;
+ memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Overwrite the cell that cursor pCur is pointing to with fresh content
+** contained in pX.
+*/
+static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
+ int iOffset; /* Next byte of pX->pData to write */
+ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
+ int rc; /* Return code */
+ MemPage *pPage = pCur->pPage; /* Page being written */
+ BtShared *pBt; /* Btree */
+ Pgno ovflPgno; /* Next overflow page to write */
+ u32 ovflPageSize; /* Size to write on overflow page */
+
+ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ /* Overwrite the local portion first */
+ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
+ 0, pCur->info.nLocal);
+ if( rc ) return rc;
+ if( pCur->info.nLocal==nTotal ) return SQLITE_OK;
+
+ /* Now overwrite the overflow pages */
+ iOffset = pCur->info.nLocal;
+ assert( nTotal>=0 );
+ assert( iOffset>=0 );
+ ovflPgno = get4byte(pCur->info.pPayload + iOffset);
+ pBt = pPage->pBt;
+ ovflPageSize = pBt->usableSize - 4;
+ do{
+ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
+ if( rc ) return rc;
+ if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ if( iOffset+ovflPageSize<(u32)nTotal ){
+ ovflPgno = get4byte(pPage->aData);
+ }else{
+ ovflPageSize = nTotal - iOffset;
+ }
+ rc = btreeOverwriteContent(pPage, pPage->aData+4, pX,
+ iOffset, ovflPageSize);
+ }
+ sqlite3PagerUnref(pPage->pDbPage);
+ if( rc ) return rc;
+ iOffset += ovflPageSize;
+ }while( iOffset<nTotal );
+ return SQLITE_OK;
+}
+
/*
** Insert a new record into the BTree. The content of the new record
@@ -68057,35 +71247,86 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
- ** to a row with the same key as the new entry being inserted. */
- assert( (flags & BTREE_SAVEPOSITION)==0 ||
- ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
+ ** to a row with the same key as the new entry being inserted.
+ */
+#ifdef SQLITE_DEBUG
+ if( flags & BTREE_SAVEPOSITION ){
+ assert( pCur->curFlags & BTCF_ValidNKey );
+ assert( pX->nKey==pCur->info.nKey );
+ assert( pCur->info.nSize!=0 );
+ assert( loc==0 );
+ }
+#endif
- /* If the cursor is currently on the last row and we are appending a
- ** new row onto the end, set the "loc" to avoid an unnecessary
- ** btreeMoveto() call */
+ /* On the other hand, BTREE_SAVEPOSITION==0 does not imply
+ ** that the cursor is not pointing to a row to be overwritten.
+ ** So do a complete check.
+ */
if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
- loc = 0;
+ /* The cursor is pointing to the entry that is to be
+ ** overwritten */
+ assert( pX->nData>=0 && pX->nZero>=0 );
+ if( pCur->info.nSize!=0
+ && pCur->info.nPayload==(u32)pX->nData+pX->nZero
+ ){
+ /* New entry is the same size as the old. Do an overwrite */
+ return btreeOverwriteCell(pCur, pX);
+ }
+ assert( loc==0 );
}else if( loc==0 ){
+ /* The cursor is *not* pointing to the cell to be overwritten, nor
+ ** to an adjacent cell. Move the cursor so that it is pointing either
+ ** to the cell to be overwritten or an adjacent cell.
+ */
rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
if( rc ) return rc;
}
- }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
- if( pX->nMem ){
- UnpackedRecord r;
- r.pKeyInfo = pCur->pKeyInfo;
- r.aMem = pX->aMem;
- r.nField = pX->nMem;
- r.default_rc = 0;
- r.errCode = 0;
- r.r1 = 0;
- r.r2 = 0;
- r.eqSeen = 0;
- rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
- }else{
- rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
+ }else{
+ /* This is an index or a WITHOUT ROWID table */
+
+ /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
+ ** to a row with the same key as the new entry being inserted.
+ */
+ assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 );
+
+ /* If the cursor is not already pointing either to the cell to be
+ ** overwritten, or if a new cell is being inserted, if the cursor is
+ ** not pointing to an immediately adjacent cell, then move the cursor
+ ** so that it does.
+ */
+ if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
+ if( pX->nMem ){
+ UnpackedRecord r;
+ r.pKeyInfo = pCur->pKeyInfo;
+ r.aMem = pX->aMem;
+ r.nField = pX->nMem;
+ r.default_rc = 0;
+ r.errCode = 0;
+ r.r1 = 0;
+ r.r2 = 0;
+ r.eqSeen = 0;
+ rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
+ }else{
+ rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
+ }
+ if( rc ) return rc;
+ }
+
+ /* If the cursor is currently pointing to an entry to be overwritten
+ ** and the new content is the same as as the old, then use the
+ ** overwrite optimization.
+ */
+ if( loc==0 ){
+ getCellInfo(pCur);
+ if( pCur->info.nKey==pX->nKey ){
+ BtreePayload x2;
+ x2.pData = pX->pKey;
+ x2.nData = pX->nKey;
+ x2.nZero = 0;
+ return btreeOverwriteCell(pCur, &x2);
+ }
}
- if( rc ) return rc;
+
}
assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
@@ -68924,14 +72165,14 @@ static void checkAppendMsg(
pCheck->nErr++;
va_start(ap, zFormat);
if( pCheck->errMsg.nChar ){
- sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
+ sqlite3_str_append(&pCheck->errMsg, "\n", 1);
}
if( pCheck->zPfx ){
- sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
+ sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
}
- sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
+ sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
va_end(ap);
- if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
+ if( pCheck->errMsg.accError==SQLITE_NOMEM ){
pCheck->mallocFailed = 1;
}
}
@@ -68966,8 +72207,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage){
- if( iPage==0 ) return 1;
- if( iPage>pCheck->nPage ){
+ if( iPage>pCheck->nPage || iPage==0 ){
checkAppendMsg(pCheck, "invalid page number %d", iPage);
return 1;
}
@@ -69022,17 +72262,12 @@ static void checkList(
){
int i;
int expected = N;
- int iFirst = iPage;
- while( N-- > 0 && pCheck->mxErr ){
+ int nErrAtStart = pCheck->nErr;
+ while( iPage!=0 && pCheck->mxErr ){
DbPage *pOvflPage;
unsigned char *pOvflData;
- if( iPage<1 ){
- checkAppendMsg(pCheck,
- "%d of %d pages missing from overflow list starting at %d",
- N+1, expected, iFirst);
- break;
- }
if( checkRef(pCheck, iPage) ) break;
+ N--;
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
checkAppendMsg(pCheck, "failed to get page %d", iPage);
break;
@@ -69076,10 +72311,12 @@ static void checkList(
#endif
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
-
- if( isFreeList && N<(iPage!=0) ){
- checkAppendMsg(pCheck, "free-page count in header is too small");
- }
+ }
+ if( N && nErrAtStart==pCheck->nErr ){
+ checkAppendMsg(pCheck,
+ "%s is %d but should be %d",
+ isFreeList ? "size" : "overflow list length",
+ expected-N, expected);
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -69473,6 +72710,24 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
/* Check all the tables.
*/
+#ifndef SQLITE_OMIT_AUTOVACUUM
+ if( pBt->autoVacuum ){
+ int mx = 0;
+ int mxInHdr;
+ for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
+ mxInHdr = get4byte(&pBt->pPage1->aData[52]);
+ if( mx!=mxInHdr ){
+ checkAppendMsg(&sCheck,
+ "max rootpage (%d) disagrees with header (%d)",
+ mx, mxInHdr
+ );
+ }
+ }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
+ checkAppendMsg(&sCheck,
+ "incremental_vacuum enabled with a max rootpage of zero"
+ );
+ }
+#endif
testcase( pBt->db->flags & SQLITE_CellSizeCk );
pBt->db->flags &= ~SQLITE_CellSizeCk;
for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
@@ -69515,11 +72770,11 @@ integrity_ck_cleanup:
sqlite3PageFree(sCheck.heap);
sqlite3_free(sCheck.aPgRef);
if( sCheck.mallocFailed ){
- sqlite3StrAccumReset(&sCheck.errMsg);
+ sqlite3_str_reset(&sCheck.errMsg);
sCheck.nErr++;
}
*pnErr = sCheck.nErr;
- if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
+ if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
/* Make sure this analysis did not leave any unref() pages. */
assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
sqlite3BtreeLeave(p);
@@ -69754,11 +73009,11 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
pBt->btsFlags &= ~BTS_NO_WAL;
if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;
- rc = sqlite3BtreeBeginTrans(pBtree, 0);
+ rc = sqlite3BtreeBeginTrans(pBtree, 0, 0);
if( rc==SQLITE_OK ){
u8 *aData = pBt->pPage1->aData;
if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
- rc = sqlite3BtreeBeginTrans(pBtree, 2);
+ rc = sqlite3BtreeBeginTrans(pBtree, 2, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc==SQLITE_OK ){
@@ -70198,7 +73453,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
** before this function exits.
*/
if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
- rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
+ rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
bCloseTrans = 1;
}
@@ -70214,10 +73469,10 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
/* Lock the destination database, if it is not locked already. */
if( SQLITE_OK==rc && p->bDestLocked==0
- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
+ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
+ (int*)&p->iDestSchema))
){
p->bDestLocked = 1;
- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
}
/* Do not allow backup if the destination database is in WAL mode
@@ -70661,8 +73916,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
- assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
- |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
+ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
/* If MEM_Null is set, then either the value is a pure NULL (the usual
** case) or it is a pointer set using sqlite3_bind_pointer() or
@@ -70712,6 +73966,51 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
+#ifdef SQLITE_DEBUG
+/*
+** Check that string value of pMem agrees with its integer or real value.
+**
+** A single int or real value always converts to the same strings. But
+** many different strings can be converted into the same int or real.
+** If a table contains a numeric value and an index is based on the
+** corresponding string value, then it is important that the string be
+** derived from the numeric value, not the other way around, to ensure
+** that the index and table are consistent. See ticket
+** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for
+** an example.
+**
+** This routine looks at pMem to verify that if it has both a numeric
+** representation and a string representation then the string rep has
+** been derived from the numeric and not the other way around. It returns
+** true if everything is ok and false if there is a problem.
+**
+** This routine is for use inside of assert() statements only.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
+ char zBuf[100];
+ char *z;
+ int i, j, incr;
+ if( (p->flags & MEM_Str)==0 ) return 1;
+ if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
+ if( p->flags & MEM_Int ){
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
+ }else{
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
+ }
+ z = p->z;
+ i = j = 0;
+ incr = 1;
+ if( p->enc!=SQLITE_UTF8 ){
+ incr = 2;
+ if( p->enc==SQLITE_UTF16BE ) z++;
+ }
+ while( zBuf[j] ){
+ if( zBuf[j++]!=z[i] ) return 0;
+ i += incr;
+ }
+ return 1;
+}
+#endif /* SQLITE_DEBUG */
/*
** If pMem is an object with a valid string representation, this routine
@@ -70730,7 +74029,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
#ifndef SQLITE_OMIT_UTF16
int rc;
#endif
- assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
|| desiredEnc==SQLITE_UTF16BE );
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
@@ -70763,7 +74062,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
*/
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( sqlite3VdbeCheckMemInvariants(pMem) );
- assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
testcase( pMem->db==0 );
/* If the bPreserve flag is set to true, then the memory cell must already
@@ -70851,7 +74150,7 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
*/
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
@@ -70876,7 +74175,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
int nByte;
assert( pMem->flags & MEM_Zero );
assert( pMem->flags&MEM_Blob );
- assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
/* Set nByte to the number of bytes required to store the expanded blob. */
@@ -70931,7 +74230,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) );
- assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -70969,29 +74268,56 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
** otherwise.
*/
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
- int rc = SQLITE_OK;
- if( ALWAYS(pFunc && pFunc->xFinalize) ){
- sqlite3_context ctx;
- Mem t;
- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&ctx, 0, sizeof(ctx));
- memset(&t, 0, sizeof(t));
- t.flags = MEM_Null;
- t.db = pMem->db;
- ctx.pOut = &t;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
- assert( (pMem->flags & MEM_Dyn)==0 );
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
- memcpy(pMem, &t, sizeof(t));
- rc = ctx.isError;
- }
- return rc;
+ sqlite3_context ctx;
+ Mem t;
+ assert( pFunc!=0 );
+ assert( pFunc->xFinalize!=0 );
+ assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ memset(&ctx, 0, sizeof(ctx));
+ memset(&t, 0, sizeof(t));
+ t.flags = MEM_Null;
+ t.db = pMem->db;
+ ctx.pOut = &t;
+ ctx.pMem = pMem;
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ memcpy(pMem, &t, sizeof(t));
+ return ctx.isError;
}
/*
+** Memory cell pAccum contains the context of an aggregate function.
+** This routine calls the xValue method for that function and stores
+** the results in memory cell pMem.
+**
+** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK
+** otherwise.
+*/
+#ifndef SQLITE_OMIT_WINDOWFUNC
+SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
+ sqlite3_context ctx;
+ Mem t;
+ assert( pFunc!=0 );
+ assert( pFunc->xValue!=0 );
+ assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
+ assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
+ memset(&ctx, 0, sizeof(ctx));
+ memset(&t, 0, sizeof(t));
+ t.flags = MEM_Null;
+ t.db = pAccum->db;
+ sqlite3VdbeMemSetNull(pOut);
+ ctx.pOut = pOut;
+ ctx.pMem = pAccum;
+ ctx.pFunc = pFunc;
+ pFunc->xValue(&ctx);
+ return ctx.isError;
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+/*
** If the memory cell contains a value that must be freed by
** invoking the external callback in Mem.xDel, then this routine
** will free that value. It also sets Mem.flags to MEM_Null.
@@ -71009,15 +74335,8 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
testcase( p->flags & MEM_Dyn );
}
if( p->flags&MEM_Dyn ){
- assert( (p->flags&MEM_RowSet)==0 );
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
p->xDel((void *)p->z);
- }else if( p->flags&MEM_RowSet ){
- sqlite3RowSetClear(p->u.pRowSet);
- }else if( p->flags&MEM_Frame ){
- VdbeFrame *pFrame = p->u.pFrame;
- pFrame->pParent = pFrame->v->pDelFrame;
- pFrame->v->pDelFrame = pFrame;
}
p->flags = MEM_Null;
}
@@ -71149,13 +74468,23 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
}
/*
+** Return 1 if pMem represents true, and return 0 if pMem represents false.
+** Return the value ifNull if pMem is NULL.
+*/
+SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
+ if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
+ if( pMem->flags & MEM_Null ) return ifNull;
+ return sqlite3VdbeRealValue(pMem)!=0.0;
+}
+
+/*
** The MEM structure is already a MEM_Real. Try to also make it a
** MEM_Int if we can.
*/
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
i64 ix;
assert( pMem->flags & MEM_Real );
- assert( (pMem->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -71182,7 +74511,7 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
*/
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
pMem->u.i = sqlite3VdbeIntValue(pMem);
@@ -71203,6 +74532,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
return SQLITE_OK;
}
+/* Compare a floating point value to an integer. Return true if the two
+** values are the same within the precision of the floating point value.
+**
+** For some versions of GCC on 32-bit machines, if you do the more obvious
+** comparison of "r1==(double)i" you sometimes get an answer of false even
+** though the r1 and (double)i values are bit-for-bit the same.
+*/
+static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
+ double r2 = (double)i;
+ return memcmp(&r1, &r2, sizeof(r1))==0;
+}
+
/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
@@ -71222,7 +74563,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
}else{
i64 i = pMem->u.i;
sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
- if( rc==1 && pMem->u.r==(double)i ){
+ if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
pMem->u.i = i;
MemSetTypeFlag(pMem, MEM_Int);
}else{
@@ -71354,7 +74695,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
}
/* A no-op destructor */
-static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
+SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
/*
** Set the value stored in *pMem should already be a NULL.
@@ -71388,26 +74729,36 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
}
#endif
+#ifdef SQLITE_DEBUG
+/*
+** Return true if the Mem holds a RowSet object. This routine is intended
+** for use inside of assert() statements.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){
+ return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn)
+ && pMem->xDel==sqlite3RowSetDelete;
+}
+#endif
+
/*
** Delete any previous value and set the value of pMem to be an
** empty boolean index.
+**
+** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
+** error occurs.
*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
+SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){
sqlite3 *db = pMem->db;
+ RowSet *p;
assert( db!=0 );
- assert( (pMem->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
- if( db->mallocFailed ){
- pMem->flags = MEM_Null;
- pMem->szMalloc = 0;
- }else{
- assert( pMem->zMalloc );
- pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
- assert( pMem->u.pRowSet!=0 );
- pMem->flags = MEM_RowSet;
- }
+ p = sqlite3RowSetInit(db);
+ if( p==0 ) return SQLITE_NOMEM;
+ pMem->z = (char*)p;
+ pMem->flags = MEM_Blob|MEM_Dyn;
+ pMem->xDel = sqlite3RowSetDelete;
+ return SQLITE_OK;
}
/*
@@ -71440,7 +74791,21 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
Mem *pX;
for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
- pX->flags |= MEM_Undefined;
+ /* If pX is marked as a shallow copy of pMem, then verify that
+ ** no significant changes have been made to pX since the OP_SCopy.
+ ** A significant change would indicated a missed call to this
+ ** function for pX. Minor changes, such as adding or removing a
+ ** dual type, are allowed, as long as the underlying value is the
+ ** same. */
+ u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
+ assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
+ assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
+ assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
+ assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
+
+ /* pMem is the register that is changing. But also mark pX as
+ ** undefined so that we can quickly detect the shallow-copy error */
+ pX->flags = MEM_Undefined;
pX->pScopyFrom = 0;
}
}
@@ -71461,7 +74826,7 @@ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
}
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
- assert( (pFrom->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pFrom) );
assert( pTo->db==pFrom->db );
if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
memcpy(pTo, pFrom, MEMCELLSIZE);
@@ -71479,7 +74844,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
int rc = SQLITE_OK;
- assert( (pFrom->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pFrom) );
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
@@ -71537,7 +74902,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
u16 flags = 0; /* New value for pMem->flags */
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
if( !z ){
@@ -71659,7 +75024,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
- assert( (pMem->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem) );
zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
assert( zData!=0 );
@@ -71683,7 +75048,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert( pVal!=0 );
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
- assert( (pVal->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pVal) );
assert( (pVal->flags & (MEM_Null))==0 );
if( pVal->flags & (MEM_Blob|MEM_Str) ){
if( ExpandBlob(pVal) ) return 0;
@@ -71705,6 +75070,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
+ assert( sqlite3VdbeMemConsistentDualRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -71725,8 +75091,9 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
if( !pVal ) return 0;
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
- assert( (pVal->flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pVal) );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
+ assert( sqlite3VdbeMemConsistentDualRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
@@ -71942,7 +75309,11 @@ static int valueFromExpr(
assert( pExpr!=0 );
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
+#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
+ if( op==TK_REGISTER ) op = pExpr->op2;
+#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
+#endif
/* Compressed expressions only appear when parsing the DEFAULT clause
** on a table column definition, and hence only when pCtx==0. This
@@ -72026,18 +75397,25 @@ static int valueFromExpr(
0, SQLITE_DYNAMIC);
}
#endif
-
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
else if( op==TK_FUNCTION && pCtx!=0 ){
rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
}
#endif
+ else if( op==TK_TRUEFALSE ){
+ pVal = valueNew(db, pCtx);
+ pVal->flags = MEM_Int;
+ pVal->u.i = pExpr->u.zToken[4]==0;
+ }
*ppVal = pVal;
return rc;
no_mem:
- sqlite3OomFault(db);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pCtx==0 || pCtx->pParse->nErr==0 )
+#endif
+ sqlite3OomFault(db);
sqlite3DbFree(db, zVal);
assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -72280,11 +75658,11 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
int iCol, /* Column to extract */
sqlite3_value **ppVal /* OUT: Extracted value */
){
- u32 t; /* a column type code */
+ u32 t = 0; /* a column type code */
int nHdr; /* Size of the header in the record */
int iHdr; /* Next unread header byte */
int iField; /* Next unread data byte */
- int szField; /* Size of the current data field */
+ int szField = 0; /* Size of the current data field */
int i; /* Column index */
u8 *a = (u8*)pRec; /* Typecast byte array */
Mem *pMem = *ppVal; /* Write result into this Mem object */
@@ -72577,14 +75955,6 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
- int jj, kk;
- Parse *pParse = p->pParse;
- for(jj=kk=0; jj<pParse->nColCache; jj++){
- struct yColCache *x = pParse->aColCache + jj;
- printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
- kk++;
- }
- if( kk ) printf("\n");
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
test_addop_breakpoint();
}
@@ -72687,6 +76057,49 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(
return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
}
+#ifndef SQLITE_OMIT_EXPLAIN
+/*
+** Return the address of the current EXPLAIN QUERY PLAN baseline.
+** 0 means "none".
+*/
+SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
+ VdbeOp *pOp;
+ if( pParse->addrExplain==0 ) return 0;
+ pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
+ return pOp->p2;
+}
+
+/*
+** Add a new OP_Explain opcode.
+**
+** If the bPush flag is true, then make this opcode the parent for
+** subsequent Explains until sqlite3VdbeExplainPop() is called.
+*/
+SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
+ if( pParse->explain==2 ){
+ char *zMsg;
+ Vdbe *v;
+ va_list ap;
+ int iThis;
+ va_start(ap, zFmt);
+ zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
+ va_end(ap);
+ v = pParse->pVdbe;
+ iThis = v->nOp;
+ sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
+ zMsg, P4_DYNAMIC);
+ if( bPush) pParse->addrExplain = iThis;
+ }
+}
+
+/*
+** Pop the EXPLAIN QUERY PLAN stack one level.
+*/
+SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
+ pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
+}
+#endif /* SQLITE_OMIT_EXPLAIN */
+
/*
** Add an OP_ParseSchema opcode. This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
@@ -72776,6 +76189,12 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
assert( j<p->nLabel );
assert( j>=0 );
if( p->aLabel ){
+#ifdef SQLITE_DEBUG
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
+ }
+#endif
+ assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
p->aLabel[j] = v->nOp;
}
}
@@ -72925,6 +76344,32 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
+#ifdef SQLITE_DEBUG
+/*
+** Increment the nWrite counter in the VDBE if the cursor is not an
+** ephemeral cursor, or if the cursor argument is NULL.
+*/
+SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){
+ if( pC==0
+ || (pC->eCurType!=CURTYPE_SORTER
+ && pC->eCurType!=CURTYPE_PSEUDO
+ && !pC->isEphemeral)
+ ){
+ p->nWrite++;
+ }
+}
+#endif
+
+#ifdef SQLITE_DEBUG
+/*
+** Assert if an Abort at this point in time might result in a corrupt
+** database.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){
+ assert( p->nWrite==0 || p->usesStmtJournal );
+}
+#endif
+
/*
** This routine is called after all opcodes have been inserted. It loops
** through all the opcodes and fixes up some details.
@@ -72985,7 +76430,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
break;
}
case OP_Next:
- case OP_NextIfOpen:
case OP_SorterNext: {
pOp->p4.xAdvance = sqlite3BtreeNext;
pOp->p4type = P4_ADVANCE;
@@ -72995,8 +76439,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
assert( pOp->p2>=0 );
break;
}
- case OP_Prev:
- case OP_PrevIfOpen: {
+ case OP_Prev: {
pOp->p4.xAdvance = sqlite3BtreePrevious;
pOp->p4type = P4_ADVANCE;
/* The code generator never codes any of these opcodes as a jump
@@ -73085,6 +76528,17 @@ SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
#endif
/*
+** Generate code (a single OP_Abortable opcode) that will
+** verify that the VDBE program can safely call Abort in the current
+** context.
+*/
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){
+ if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable);
+}
+#endif
+
+/*
** This function returns a pointer to the array of opcodes associated with
** the Vdbe passed as the first argument. It is the callers responsibility
** to arrange for the returned array to be eventually freed using the
@@ -73250,6 +76704,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
+ case P4_DYNBLOB:
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
@@ -73627,23 +77082,23 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
const char *zOp = 0;
switch( pExpr->op ){
case TK_STRING:
- sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
+ sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
break;
case TK_INTEGER:
- sqlite3XPrintf(p, "%d", pExpr->u.iValue);
+ sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
break;
case TK_NULL:
- sqlite3XPrintf(p, "NULL");
+ sqlite3_str_appendf(p, "NULL");
break;
case TK_REGISTER: {
- sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
+ sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
break;
}
case TK_COLUMN: {
if( pExpr->iColumn<0 ){
- sqlite3XPrintf(p, "rowid");
+ sqlite3_str_appendf(p, "rowid");
}else{
- sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
+ sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
}
break;
}
@@ -73675,18 +77130,18 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
case TK_NOTNULL: zOp = "NOTNULL"; break;
default:
- sqlite3XPrintf(p, "%s", "expr");
+ sqlite3_str_appendf(p, "%s", "expr");
break;
}
if( zOp ){
- sqlite3XPrintf(p, "%s(", zOp);
+ sqlite3_str_appendf(p, "%s(", zOp);
displayP4Expr(p, pExpr->pLeft);
if( pExpr->pRight ){
- sqlite3StrAccumAppend(p, ",", 1);
+ sqlite3_str_append(p, ",", 1);
displayP4Expr(p, pExpr->pRight);
}
- sqlite3StrAccumAppend(p, ")", 1);
+ sqlite3_str_append(p, ")", 1);
}
}
#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
@@ -73707,14 +77162,15 @@ static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
- sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
+ sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
for(j=0; j<pKeyInfo->nKeyField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "";
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
- sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
+ sqlite3_str_appendf(&x, ",%s%s",
+ pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
}
- sqlite3StrAccumAppend(&x, ")", 1);
+ sqlite3_str_append(&x, ")", 1);
break;
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -73725,31 +77181,31 @@ static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
#endif
case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl;
- sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
+ sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
FuncDef *pDef = pOp->p4.pFunc;
- sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+ sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX: {
FuncDef *pDef = pOp->p4.pCtx->pFunc;
- sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+ sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
#endif
case P4_INT64: {
- sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
+ sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
break;
}
case P4_INT32: {
- sqlite3XPrintf(&x, "%d", pOp->p4.i);
+ sqlite3_str_appendf(&x, "%d", pOp->p4.i);
break;
}
case P4_REAL: {
- sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
+ sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
break;
}
case P4_MEM: {
@@ -73757,9 +77213,9 @@ static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
}else if( pMem->flags & MEM_Int ){
- sqlite3XPrintf(&x, "%lld", pMem->u.i);
+ sqlite3_str_appendf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
- sqlite3XPrintf(&x, "%.16g", pMem->u.r);
+ sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
}else if( pMem->flags & MEM_Null ){
zP4 = "NULL";
}else{
@@ -73771,7 +77227,7 @@ static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
#ifndef SQLITE_OMIT_VIRTUALTABLE
case P4_VTAB: {
sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
- sqlite3XPrintf(&x, "vtab:%p", pVtab);
+ sqlite3_str_appendf(&x, "vtab:%p", pVtab);
break;
}
#endif
@@ -73781,22 +77237,23 @@ static const char *displayP4(Op *pOp, char *zTemp, int nTemp){
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
- sqlite3XPrintf(&x, ",%d", ai[i]);
+ sqlite3_str_appendf(&x, ",%d", ai[i]);
}
zTemp[0] = '[';
- sqlite3StrAccumAppend(&x, "]", 1);
+ sqlite3_str_append(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
- sqlite3XPrintf(&x, "program");
+ sqlite3_str_appendf(&x, "program");
break;
}
+ case P4_DYNBLOB:
case P4_ADVANCE: {
zTemp[0] = 0;
break;
}
case P4_TABLE: {
- sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
+ sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
break;
}
default: {
@@ -73897,7 +77354,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){
+SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
const char *zP4;
char zPtr[50];
char zCom[100];
@@ -73966,9 +77423,8 @@ static void releaseMemArray(Mem *p, int N){
*/
testcase( p->flags & MEM_Agg );
testcase( p->flags & MEM_Dyn );
- testcase( p->flags & MEM_Frame );
- testcase( p->flags & MEM_RowSet );
- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
+ testcase( p->xDel==sqlite3VdbeFrameMemDel );
+ if( p->flags&(MEM_Agg|MEM_Dyn) ){
sqlite3VdbeMemRelease(p);
}else if( p->szMalloc ){
sqlite3DbFreeNN(db, p->zMalloc);
@@ -73980,6 +77436,35 @@ static void releaseMemArray(Mem *p, int N){
}
}
+#ifdef SQLITE_DEBUG
+/*
+** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is
+** and false if something is wrong.
+**
+** This routine is intended for use inside of assert() statements only.
+*/
+SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
+ if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
+ return 1;
+}
+#endif
+
+
+/*
+** This is a destructor on a Mem object (which is really an sqlite3_value)
+** that deletes the Frame object that is attached to it as a blob.
+**
+** This routine does not delete the Frame right away. It merely adds the
+** frame to a list of frames to be deleted when the Vdbe halts.
+*/
+SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
+ VdbeFrame *pFrame = (VdbeFrame*)pArg;
+ assert( sqlite3VdbeFrameIsValid(pFrame) );
+ pFrame->pParent = pFrame->v->pDelFrame;
+ pFrame->v->pDelFrame = pFrame;
+}
+
+
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
@@ -73988,6 +77473,7 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
int i;
Mem *aMem = VdbeFrameMem(p);
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
+ assert( sqlite3VdbeFrameIsValid(p) );
for(i=0; i<p->nChildCsr; i++){
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
}
@@ -74008,6 +77494,9 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
** p->explain==2, only OP_Explain instructions are listed and these
** are shown in a different format. p->explain==2 is used to implement
** EXPLAIN QUERY PLAN.
+** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers
+** are also shown, so that the boundaries between the main program and
+** each trigger are clear.
**
** When p->explain==1, first the main program is listed, then each of
** the trigger subprograms are listed one by one.
@@ -74023,6 +77512,8 @@ SQLITE_PRIVATE int sqlite3VdbeList(
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
+ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
+ Op *pOp = 0;
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
@@ -74035,7 +77526,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
releaseMemArray(pMem, 8);
p->pResultSet = 0;
- if( p->rc==SQLITE_NOMEM_BKPT ){
+ if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
sqlite3OomFault(db);
@@ -74050,7 +77541,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
- if( p->explain==1 ){
+ if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
** to trigger subprograms. The VDBE is guaranteed to have at least 9
@@ -74068,19 +77559,13 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}
}
- do{
+ while(1){ /* Loop exits via break */
i = p->pc++;
- }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
- if( i>=nRow ){
- p->rc = SQLITE_OK;
- rc = SQLITE_DONE;
- }else if( db->u1.isInterrupted ){
- p->rc = SQLITE_INTERRUPT;
- rc = SQLITE_ERROR;
- sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
- }else{
- const char *zP4;
- Op *pOp;
+ if( i>=nRow ){
+ p->rc = SQLITE_OK;
+ rc = SQLITE_DONE;
+ break;
+ }
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
** main program. */
@@ -74095,94 +77580,113 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}
pOp = &apSub[j]->aOp[i];
}
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->u.i = i; /* Program counter */
- pMem++;
-
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem++;
- /* When an OP_Program opcode is encounter (the only opcode that has
- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
- ** has not already been seen.
- */
- if( pOp->p4type==P4_SUBPROGRAM ){
- int nByte = (nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<nSub; j++){
- if( apSub[j]==pOp->p4.pProgram ) break;
- }
- if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){
- apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = pOp->p4.pProgram;
- pSub->flags |= MEM_Blob;
- pSub->n = nSub*sizeof(SubProgram*);
+ /* When an OP_Program opcode is encounter (the only opcode that has
+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
+ ** has not already been seen.
+ */
+ if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
+ int nByte = (nSub+1)*sizeof(SubProgram*);
+ int j;
+ for(j=0; j<nSub; j++){
+ if( apSub[j]==pOp->p4.pProgram ) break;
+ }
+ if( j==nSub ){
+ p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
+ if( p->rc!=SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ break;
}
+ apSub = (SubProgram **)pSub->z;
+ apSub[nSub++] = pOp->p4.pProgram;
+ pSub->flags |= MEM_Blob;
+ pSub->n = nSub*sizeof(SubProgram*);
+ nRow += pOp->p4.pProgram->nOp;
}
}
+ if( p->explain<2 ) break;
+ if( pOp->opcode==OP_Explain ) break;
+ if( pOp->opcode==OP_Init && p->pc>1 ) break;
+ }
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p1; /* P1 */
- pMem++;
+ if( rc==SQLITE_OK ){
+ if( db->u1.isInterrupted ){
+ p->rc = SQLITE_INTERRUPT;
+ rc = SQLITE_ERROR;
+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
+ }else{
+ const char *zP4;
+ if( p->explain==1 ){
+ pMem->flags = MEM_Int;
+ pMem->u.i = i; /* Program counter */
+ pMem++;
+
+ pMem->flags = MEM_Static|MEM_Str|MEM_Term;
+ pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+ }
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p2; /* P2 */
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p1; /* P1 */
+ pMem++;
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p3; /* P3 */
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p2; /* P2 */
+ pMem++;
- if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
- if( zP4!=pMem->z ){
- pMem->n = 0;
- sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
- }else{
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- }
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p3; /* P3 */
+ pMem++;
- if( p->explain==1 ){
- if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Str|MEM_Term;
- pMem->n = 2;
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->enc = SQLITE_UTF8;
+ zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
+ if( zP4!=pMem->z ){
+ pMem->n = 0;
+ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
+ }else{
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ }
pMem++;
-
+
+ if( p->explain==1 ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = 2;
+ sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- pMem->n = displayComment(pOp, zP4, pMem->z, 500);
- pMem->enc = SQLITE_UTF8;
+ if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->enc = SQLITE_UTF8;
#else
- pMem->flags = MEM_Null; /* Comment */
+ pMem->flags = MEM_Null; /* Comment */
#endif
- }
+ }
- p->nResColumn = 8 - 4*(p->explain-1);
- p->pResultSet = &p->aMem[1];
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
+ p->nResColumn = 8 - 4*(p->explain-1);
+ p->pResultSet = &p->aMem[1];
+ p->rc = SQLITE_OK;
+ rc = SQLITE_ROW;
+ }
}
return rc;
}
@@ -74652,6 +78156,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
pPager = sqlite3BtreePager(pBt);
if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
&& aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+ && sqlite3PagerIsMemdb(pPager)==0
){
assert( i!=1 );
nTrans++;
@@ -75265,7 +78770,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
*/
sqlite3VdbeHalt(p);
- /* If the VDBE has be run even partially, then transfer the error code
+ /* If the VDBE has been run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
** if the VDBE has just been set to run but has not actually executed any
** instructions yet, leave the main database error information unchanged.
@@ -75295,6 +78800,9 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
p->pResultSet = 0;
+#ifdef SQLITE_DEBUG
+ p->nWrite = 0;
+#endif
/* Save profiling information from this VDBE run.
*/
@@ -75427,7 +78935,7 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
sqlite3 *db;
- if( NEVER(p==0) ) return;
+ assert( p!=0 );
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3VdbeClearObject(db, p);
@@ -75823,7 +79331,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
- case 10: /* Reserved for future use */
+ case 10: { /* Internal use only: NULL with virtual table
+ ** UPDATE no-change flag set */
+ pMem->flags = MEM_Null|MEM_Zero;
+ pMem->n = 0;
+ pMem->u.nZero = 0;
+ break;
+ }
case 11: /* Reserved for future use */
case 0: { /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
@@ -76168,7 +79682,7 @@ static int isAllZero(const char *z, int n){
** is less than, equal to, or greater than the second, respectively.
** If one blob is a prefix of the other, then the shorter is the lessor.
*/
-static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
int c;
int n1 = pB1->n;
int n2 = pB2->n;
@@ -76211,13 +79725,10 @@ static int sqlite3IntFloatCompare(i64 i, double r){
i64 y;
double s;
if( r<-9223372036854775808.0 ) return +1;
- if( r>9223372036854775807.0 ) return -1;
+ if( r>=9223372036854775808.0 ) return -1;
y = (i64)r;
if( i<y ) return -1;
- if( i>y ){
- if( y==SMALLEST_INT64 && r>0.0 ) return -1;
- return +1;
- }
+ if( i>y ) return +1;
s = (double)i;
if( s<r ) return -1;
if( s>r ) return +1;
@@ -76241,7 +79752,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
f1 = pMem1->flags;
f2 = pMem2->flags;
combined_flags = f1|f2;
- assert( (combined_flags & MEM_RowSet)==0 );
+ assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) );
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
@@ -76386,7 +79897,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
u32 idx1; /* Offset of first type in header */
int rc = 0; /* Return value */
Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */
- KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
+ KeyInfo *pKeyInfo;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
Mem mem1;
@@ -76481,7 +79992,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
if( (d1+mem1.n) > (unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
- }else if( pKeyInfo->aColl[i] ){
+ }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
@@ -76532,7 +80043,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}
if( rc!=0 ){
- if( pKeyInfo->aSortOrder[i] ){
+ if( pPKey2->pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
@@ -76541,10 +80052,11 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}
i++;
+ if( i==pPKey2->nField ) break;
pRhs++;
d1 += sqlite3VdbeSerialTypeLen(serial_type);
idx1 += sqlite3VarintLen(serial_type);
- }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
+ }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
@@ -76556,7 +80068,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
** value. */
assert( CORRUPT_DB
|| vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc)
- || pKeyInfo->db->mallocFailed
+ || pPKey2->pKeyInfo->db->mallocFailed
);
pPKey2->eqSeen = 1;
return pPKey2->default_rc;
@@ -76807,7 +80319,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
(void)getVarint32((u8*)m.z, szHdr);
testcase( szHdr==3 );
testcase( szHdr==m.n );
- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
+ testcase( szHdr>0x7fffffff );
+ assert( m.n>=0 );
+ if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
goto idx_rowid_corruption;
}
@@ -76882,7 +80396,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
if( rc ){
return rc;
}
- *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
+ *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
sqlite3VdbeMemRelease(&m);
return SQLITE_OK;
}
@@ -76914,11 +80428,19 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){
** programs obsolete. Removing user-defined functions or collating
** sequences, or changing an authorization function are the types of
** things that make prepared statements obsolete.
+**
+** If iCode is 1, then expiration is advisory. The statement should
+** be reprepared before being restarted, but if it is already running
+** it is allowed to run to completion.
+**
+** Internally, this function just sets the Vdbe.expired flag on all
+** prepared statements. The flag is set to 1 for an immediate expiration
+** and set to 2 for an advisory expiration.
*/
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){
Vdbe *p;
for(p = db->pVdbe; p; p=p->pNext){
- p->expired = 1;
+ p->expired = iCode+1;
}
}
@@ -77376,6 +80898,11 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
return aType[pVal->flags&MEM_AffMask];
}
+/* Return true if a parameter to xUpdate represents an unchanged column */
+SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
+ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
+}
+
/* Make a copy of an sqlite3_value object
*/
SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
@@ -77476,14 +81003,12 @@ SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
- pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
- pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
@@ -77597,8 +81122,7 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
return SQLITE_OK;
}
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
- pCtx->isError = errCode;
- pCtx->fErrorOrAux = 1;
+ pCtx->isError = errCode ? errCode : -1;
#ifdef SQLITE_DEBUG
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
#endif
@@ -77612,7 +81136,6 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
- pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
@@ -77622,7 +81145,6 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM_BKPT;
- pCtx->fErrorOrAux = 1;
sqlite3OomFault(pCtx->pOut->db);
}
@@ -77863,6 +81385,25 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
}
/*
+** If this routine is invoked from within an xColumn method of a virtual
+** table, then it returns true if and only if the the call is during an
+** UPDATE operation and the value of the column will not be modified
+** by the UPDATE.
+**
+** If this routine is called from any context other than within the
+** xColumn method of a virtual table, then the return value is meaningless
+** and arbitrary.
+**
+** Virtual table implements might use this routine to optimize their
+** performance by substituting a NULL result, or some other light-weight
+** value, as a signal to the xUpdate routine that the column is unchanged.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
+ assert( p );
+ return sqlite3_value_nochange(p->pOut);
+}
+
+/*
** Return the current time for a statement. If the current time
** is requested more than once within the same run of a single prepared
** statement, the exact same time is returned for each invocation regardless
@@ -77886,28 +81427,6 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
}
/*
-** The following is the implementation of an SQL function that always
-** fails with an error message stating that the function is used in the
-** wrong context. The sqlite3_overload_function() API might construct
-** SQL function that use this routine so that the functions will exist
-** for name resolution but are actually overloaded by the xFindFunction
-** method of virtual tables.
-*/
-SQLITE_PRIVATE void sqlite3InvalidFunction(
- sqlite3_context *context, /* The function calling context */
- int NotUsed, /* Number of arguments to the function */
- sqlite3_value **NotUsed2 /* Value of each argument */
-){
- const char *zName = context->pFunc->zName;
- char *zErr;
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- zErr = sqlite3_mprintf(
- "unable to use function %s in the requested context", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
-}
-
-/*
** Create a new aggregate context for p and return a pointer to
** its pMem->z element.
*/
@@ -78010,10 +81529,7 @@ SQLITE_API void sqlite3_set_auxdata(
pAuxData->iAuxArg = iArg;
pAuxData->pNextAux = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
- if( pCtx->fErrorOrAux==0 ){
- pCtx->isError = 0;
- pCtx->fErrorOrAux = 1;
- }
+ if( pCtx->isError==0 ) pCtx->isError = -1;
}else if( pAuxData->xDeleteAux ){
pAuxData->xDeleteAux(pAuxData->pAux);
}
@@ -78093,7 +81609,7 @@ static const Mem *columnNullValue(void){
/* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
/* .pScopyFrom = */ (Mem*)0,
- /* .pFiller = */ (void*)0,
+ /* .mScopyFlags= */ 0,
#endif
};
return &nullMem;
@@ -78775,7 +82291,9 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
size_t v;
#ifdef SQLITE_ENABLE_API_ARMOR
- if( !pStmt ){
+ if( !pStmt
+ || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
+ ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
@@ -79181,17 +82699,17 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
- sqlite3StrAccumAppend(&out, "-- ", 3);
+ sqlite3_str_append(&out, "-- ", 3);
assert( (zRawSql - zStart) > 0 );
- sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
+ sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
}
}else if( p->nVar==0 ){
- sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
+ sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
}else{
while( zRawSql[0] ){
n = findNextHostParameter(zRawSql, &nToken);
assert( n>0 );
- sqlite3StrAccumAppend(&out, zRawSql, n);
+ sqlite3_str_append(&out, zRawSql, n);
zRawSql += n;
assert( zRawSql[0] || nToken==0 );
if( nToken==0 ) break;
@@ -79217,11 +82735,11 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
assert( idx>0 && idx<=p->nVar );
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
- sqlite3StrAccumAppend(&out, "NULL", 4);
+ sqlite3_str_append(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
+ sqlite3_str_appendf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
+ sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
}else if( pVar->flags & MEM_Str ){
int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
@@ -79231,7 +82749,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
utf8.db = db;
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
- out.accError = STRACCUM_NOMEM;
+ out.accError = SQLITE_NOMEM;
out.nAlloc = 0;
}
pVar = &utf8;
@@ -79244,38 +82762,38 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
}
#endif
- sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
+ sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut<pVar->n ){
- sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
}
#endif
#ifndef SQLITE_OMIT_UTF16
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
#endif
}else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+ sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
}else{
int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
- sqlite3StrAccumAppend(&out, "x'", 2);
+ sqlite3_str_append(&out, "x'", 2);
nOut = pVar->n;
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
#endif
for(i=0; i<nOut; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
}
- sqlite3StrAccumAppend(&out, "'", 1);
+ sqlite3_str_append(&out, "'", 1);
#ifdef SQLITE_TRACE_SIZE_LIMIT
if( nOut<pVar->n ){
- sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
}
#endif
}
}
}
- if( out.accError ) sqlite3StrAccumReset(&out);
+ if( out.accError ) sqlite3_str_reset(&out);
return sqlite3StrAccumFinish(&out);
}
@@ -79407,32 +82925,56 @@ SQLITE_API int sqlite3_found_count = 0;
** feature is used for test suite validation only and does not appear an
** production builds.
**
-** M is an integer, 2 or 3, that indices how many different ways the
-** branch can go. It is usually 2. "I" is the direction the branch
-** goes. 0 means falls through. 1 means branch is taken. 2 means the
-** second alternative branch is taken.
+** M is an integer between 2 and 4. 2 indicates a ordinary two-way
+** branch (I=0 means fall through and I=1 means taken). 3 indicates
+** a 3-way branch where the third way is when one of the operands is
+** NULL. 4 indicates the OP_Jump instruction which has three destinations
+** depending on whether the first operand is less than, equal to, or greater
+** than the second.
**
** iSrcLine is the source code line (from the __LINE__ macro) that
-** generated the VDBE instruction. This instrumentation assumes that all
-** source code is in a single file (the amalgamation). Special values 1
-** and 2 for the iSrcLine parameter mean that this particular branch is
-** always taken or never taken, respectively.
+** generated the VDBE instruction combined with flag bits. The source
+** code line number is in the lower 24 bits of iSrcLine and the upper
+** 8 bytes are flags. The lower three bits of the flags indicate
+** values for I that should never occur. For example, if the branch is
+** always taken, the flags should be 0x05 since the fall-through and
+** alternate branch are never taken. If a branch is never taken then
+** flags should be 0x06 since only the fall-through approach is allowed.
+**
+** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
+** interested in equal or not-equal. In other words, I==0 and I==2
+** should be treated the same.
+**
+** Since only a line number is retained, not the filename, this macro
+** only works for amalgamation builds. But that is ok, since these macros
+** should be no-ops except for special builds used to measure test coverage.
*/
#if !defined(SQLITE_VDBE_COVERAGE)
# define VdbeBranchTaken(I,M)
#else
# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
- static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
- if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
- M = iSrcLine;
- /* Assert the truth of VdbeCoverageAlwaysTaken() and
- ** VdbeCoverageNeverTaken() */
- assert( (M & I)==I );
- }else{
- if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
- sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
- iSrcLine,I,M);
- }
+ static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){
+ u8 mNever;
+ assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */
+ assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */
+ assert( I<M ); /* I can only be 2 if M is 3 or 4 */
+ /* Transform I from a integer [0,1,2] into a bitmask of [1,2,4] */
+ I = 1<<I;
+ /* The upper 8 bits of iSrcLine are flags. The lower three bits of
+ ** the flags indicate directions that the branch can never go. If
+ ** a branch really does go in one of those directions, assert right
+ ** away. */
+ mNever = iSrcLine >> 24;
+ assert( (I & mNever)==0 );
+ if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
+ I |= mNever;
+ if( M==2 ) I |= 0x04;
+ if( M==4 ){
+ I |= 0x08;
+ if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
+ }
+ sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
+ iSrcLine&0xffffff, I, M);
}
#endif
@@ -79549,6 +83091,11 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
pRec->flags |= MEM_Real;
if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
}
+ /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the
+ ** string representation after computing a numeric equivalent, because the
+ ** string representation might not be the canonical representation for the
+ ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */
+ pRec->flags &= ~MEM_Str;
}
/*
@@ -79749,7 +83296,7 @@ static void memTracePrint(Mem *p){
if( p->flags & MEM_Undefined ){
printf(" undefined");
}else if( p->flags & MEM_Null ){
- printf(" NULL");
+ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
#ifdef _WIN32
printf(" si:%I64d", p->u.i);
@@ -79764,7 +83311,7 @@ static void memTracePrint(Mem *p){
}else if( p->flags & MEM_Real ){
printf(" r:%g", p->u.r);
#endif
- }else if( p->flags & MEM_RowSet ){
+ }else if( sqlite3VdbeMemIsRowSet(p) ){
printf(" (rowset)");
}else{
char zBuf[200];
@@ -80023,7 +83570,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
- start = sqlite3Hwtime();
+ start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
#endif
nVmStep++;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -80290,6 +83837,9 @@ case OP_Yield: { /* in1, jump */
*/
case OP_HaltIfNull: { /* in3 */
pIn3 = &aMem[pOp->p3];
+#ifdef SQLITE_DEBUG
+ if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
+#endif
if( (pIn3->flags & MEM_Null)==0 ) break;
/* Fall through into OP_Halt */
}
@@ -80329,6 +83879,9 @@ case OP_Halt: {
int pcx;
pcx = (int)(pOp - aOp);
+#ifdef SQLITE_DEBUG
+ if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
+#endif
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
pFrame = p->pFrame;
@@ -80512,6 +84065,9 @@ case OP_Null: { /* out2 */
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
pOut->n = 0;
+#ifdef SQLITE_DEBUG
+ pOut->uTemp = 0;
+#endif
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
@@ -80633,6 +84189,7 @@ case OP_Copy: {
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
while( 1 ){
+ memAboutToChange(p, pOut);
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
@@ -80665,7 +84222,8 @@ case OP_SCopy: { /* out2 */
assert( pOut!=pIn1 );
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
+ pOut->pScopyFrom = pIn1;
+ pOut->mScopyFlags = pIn1->flags;
#endif
break;
}
@@ -81299,7 +84857,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
- testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
+ assert( flags3==pIn3->flags );
+ /* testcase( flags3!=pIn3->flags );
+ ** this used to be possible with pIn1==pIn3, but not since
+ ** the column cache was removed. The following assignment
+ ** is essentially a no-op. But, it provides defense-in-depth
+ ** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
@@ -81513,11 +85076,11 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
+ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
}else if( iCompare==0 ){
- VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
+ VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
}else{
- VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
+ VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1];
}
break;
}
@@ -81547,18 +85110,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Null ){
- v1 = 2;
- }else{
- v1 = sqlite3VdbeIntValue(pIn1)!=0;
- }
- pIn2 = &aMem[pOp->p2];
- if( pIn2->flags & MEM_Null ){
- v2 = 2;
- }else{
- v2 = sqlite3VdbeIntValue(pIn2)!=0;
- }
+ v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2);
+ v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2);
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
v1 = and_logic[v1*3+v2];
@@ -81576,6 +85129,35 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
break;
}
+/* Opcode: IsTrue P1 P2 P3 P4 *
+** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4
+**
+** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and
+** IS NOT FALSE operators.
+**
+** Interpret the value in register P1 as a boolean value. Store that
+** boolean (a 0 or 1) in register P2. Or if the value in register P1 is
+** NULL, then the P3 is stored in register P2. Invert the answer if P4
+** is 1.
+**
+** The logic is summarized like this:
+**
+** <ul>
+** <li> If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE
+** <li> If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE
+** <li> If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE
+** <li> If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE
+** </ul>
+*/
+case OP_IsTrue: { /* in1, out2 */
+ assert( pOp->p4type==P4_INT32 );
+ assert( pOp->p4.i==0 || pOp->p4.i==1 );
+ assert( pOp->p3==0 || pOp->p3==1 );
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p2],
+ sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i);
+ break;
+}
+
/* Opcode: Not P1 P2 * * *
** Synopsis: r[P2]= !r[P1]
**
@@ -81586,16 +85168,16 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
case OP_Not: { /* same as TK_NOT, in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
- sqlite3VdbeMemSetNull(pOut);
if( (pIn1->flags & MEM_Null)==0 ){
- pOut->flags = MEM_Int;
- pOut->u.i = !sqlite3VdbeIntValue(pIn1);
+ sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0));
+ }else{
+ sqlite3VdbeMemSetNull(pOut);
}
break;
}
/* Opcode: BitNot P1 P2 * * *
-** Synopsis: r[P1]= ~r[P1]
+** Synopsis: r[P2]= ~r[P1]
**
** Interpret the content of register P1 as an integer. Store the
** ones-complement of the P1 value into register P2. If P1 holds
@@ -81656,30 +85238,25 @@ case OP_Once: { /* jump */
** is considered true if it is numeric and non-zero. If the value
** in P1 is NULL then take the jump if and only if P3 is non-zero.
*/
+case OP_If: { /* jump, in1 */
+ int c;
+ c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3);
+ VdbeBranchTaken(c!=0, 2);
+ if( c ) goto jump_to_p2;
+ break;
+}
+
/* Opcode: IfNot P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is False. The value
** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if and only if P3 is non-zero.
*/
-case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
int c;
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Null ){
- c = pOp->p3;
- }else{
-#ifdef SQLITE_OMIT_FLOATING_POINT
- c = sqlite3VdbeIntValue(pIn1)!=0;
-#else
- c = sqlite3VdbeRealValue(pIn1)!=0.0;
-#endif
- if( pOp->opcode==OP_IfNot ) c = !c;
- }
+ c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3);
VdbeBranchTaken(c!=0, 2);
- if( c ){
- goto jump_to_p2;
- }
+ if( c ) goto jump_to_p2;
break;
}
@@ -81729,6 +85306,36 @@ case OP_IfNullRow: { /* jump */
break;
}
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/* Opcode: Offset P1 P2 P3 * *
+** Synopsis: r[P3] = sqlite_offset(P1)
+**
+** Store in register r[P3] the byte offset into the database file that is the
+** start of the payload for the record at which that cursor P1 is currently
+** pointing.
+**
+** P2 is the column number for the argument to the sqlite_offset() function.
+** This opcode does not use P2 itself, but the P2 value is used by the
+** code generator. The P1, P2, and P3 operands to this opcode are the
+** same as for OP_Column.
+**
+** This opcode is only available if SQLite is compiled with the
+** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
+*/
+case OP_Offset: { /* out3 */
+ VdbeCursor *pC; /* The VDBE cursor */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ pOut = &p->aMem[pOp->p3];
+ if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
+ sqlite3VdbeMemSetNull(pOut);
+ }else{
+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
+ }
+ break;
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX
**
@@ -82142,9 +85749,18 @@ case OP_MakeRecord: {
pRec = pLast;
do{
assert( memIsValid(pRec) );
- pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
+ serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
if( pRec->flags & MEM_Zero ){
- if( nData ){
+ if( serial_type==0 ){
+ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
+ ** table methods that never invoke sqlite3_result_xxxxx() while
+ ** computing an unchanging column value in an UPDATE statement.
+ ** Give such values a special internal-use-only serial-type of 10
+ ** so that they can be passed through to xUpdate and have
+ ** a true sqlite3_value_nochange(). */
+ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
+ serial_type = 10;
+ }else if( nData ){
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
}else{
nZero += pRec->u.nZero;
@@ -82155,6 +85771,7 @@ case OP_MakeRecord: {
testcase( serial_type==127 );
testcase( serial_type==128 );
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
+ pRec->uTemp = serial_type;
if( pRec==pData0 ) break;
pRec--;
}while(1);
@@ -82375,7 +85992,7 @@ case OP_Savepoint: {
}
}
if( isSchemaChange ){
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
sqlite3ResetAllSchemasOfConnection(db);
db->mDbFlags |= DBFLAG_SchemaChange;
}
@@ -82517,8 +86134,7 @@ case OP_AutoCommit: {
*/
case OP_Transaction: {
Btree *pBt;
- int iMeta;
- int iGen;
+ int iMeta = 0;
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
@@ -82531,7 +86147,7 @@ case OP_Transaction: {
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
- rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
testcase( rc==SQLITE_BUSY_SNAPSHOT );
testcase( rc==SQLITE_BUSY_RECOVERY );
if( rc!=SQLITE_OK ){
@@ -82564,19 +86180,17 @@ case OP_Transaction: {
p->nStmtDefCons = db->nDeferredCons;
p->nStmtDefImmCons = db->nDeferredImmCons;
}
-
- /* Gather the schema version number for checking:
+ }
+ assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
+ if( pOp->p5
+ && (iMeta!=pOp->p3
+ || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
+ ){
+ /*
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
** version is checked to ensure that the schema has not changed since the
** SQL statement was prepared.
*/
- sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
- iGen = db->aDb[pOp->p1].pSchema->iGeneration;
- }else{
- iGen = iMeta = 0;
- }
- assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
- if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
@@ -82645,6 +86259,8 @@ case OP_ReadCookie: { /* out2 */
*/
case OP_SetCookie: {
Db *pDb;
+
+ sqlite3VdbeIncrWriteCounter(p, 0);
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
@@ -82665,7 +86281,7 @@ case OP_SetCookie: {
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
** schema is changed. Ticket #1644 */
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
p->expired = 0;
}
if( rc ) goto abort_due_to_error;
@@ -82683,59 +86299,78 @@ case OP_SetCookie: {
** values need not be contiguous but all P1 values should be small integers.
** It is an error for P1 to be negative.
**
-** If P5!=0 then use the content of register P2 as the root page, not
-** the value of P2 itself.
-**
-** There will be a read lock on the database whenever there is an
-** open cursor. If the database was unlocked prior to this instruction
-** then a read lock is acquired as part of this instruction. A read
-** lock allows other processes to read the database but prohibits
-** any other process from modifying the database. The read lock is
-** released when all cursors are closed. If this instruction attempts
-** to get a read lock but fails, the script terminates with an
-** SQLITE_BUSY error code.
+** Allowed P5 bits:
+** <ul>
+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
+** of OP_SeekLE/OP_IdxGT)
+** </ul>
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table.
+** object, then table being opened must be an [index b-tree] where the
+** KeyInfo object defines the content and collating
+** sequence of that index b-tree. Otherwise, if P4 is an integer
+** value, then the table being opened must be a [table b-tree] with a
+** number of columns no less than the value of P4.
**
** See also: OpenWrite, ReopenIdx
*/
/* Opcode: ReopenIdx P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
-** The ReopenIdx opcode works exactly like ReadOpen except that it first
-** checks to see if the cursor on P1 is already open with a root page
-** number of P2 and if it is this opcode becomes a no-op. In other words,
+** The ReopenIdx opcode works like OP_OpenRead except that it first
+** checks to see if the cursor on P1 is already open on the same
+** b-tree and if it is this opcode becomes a no-op. In other words,
** if the cursor is already open, do not reopen it.
**
-** The ReopenIdx opcode may only be used with P5==0 and with P4 being
-** a P4_KEYINFO object. Furthermore, the P3 value must be the same as
-** every other ReopenIdx or OpenRead for the same cursor number.
+** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ
+** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must
+** be the same as every other ReopenIdx or OpenRead for the same cursor
+** number.
+**
+** Allowed P5 bits:
+** <ul>
+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
+** of OP_SeekLE/OP_IdxGT)
+** </ul>
**
-** See the OpenRead opcode documentation for additional information.
+** See also: OP_OpenRead, OP_OpenWrite
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
** Open a read/write cursor named P1 on the table or index whose root
-** page is P2. Or if P5!=0 use the content of register P2 to find the
-** root page.
+** page is P2 (or whose root page is held in register P2 if the
+** OPFLAG_P2ISREG bit is set in P5 - see below).
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table, or to the
-** largest index of any column of the table that is actually used.
+** object, then table being opened must be an [index b-tree] where the
+** KeyInfo object defines the content and collating
+** sequence of that index b-tree. Otherwise, if P4 is an integer
+** value, then the table being opened must be a [table b-tree] with a
+** number of columns no less than the value of P4.
**
-** This instruction works just like OpenRead except that it opens the cursor
-** in read/write mode. For a given table, there can be one or more read-only
-** cursors or a single read/write cursor but not both.
+** Allowed P5 bits:
+** <ul>
+** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
+** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
+** of OP_SeekLE/OP_IdxGT)
+** <li> <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
+** and subsequently delete entries in an index btree. This is a
+** hint to the storage engine that the storage engine is allowed to
+** ignore. The hint is not used by the official SQLite b*tree storage
+** engine, but is used by COMDB2.
+** <li> <b>0x10 OPFLAG_P2ISREG</b>: Use the content of register P2
+** as the root page, not the value of P2 itself.
+** </ul>
+**
+** This instruction works like OpenRead except that it opens the cursor
+** in read/write mode.
**
-** See also OpenRead.
+** See also: OP_OpenRead, OP_ReopenIdx
*/
case OP_ReopenIdx: {
int nField;
@@ -82764,7 +86399,7 @@ case OP_OpenWrite:
assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
|| p->readOnly==0 );
- if( p->expired ){
+ if( p->expired==1 ){
rc = SQLITE_ABORT_ROLLBACK;
goto abort_due_to_error;
}
@@ -82791,6 +86426,7 @@ case OP_OpenWrite:
if( pOp->p5 & OPFLAG_P2ISREG ){
assert( p2>0 );
assert( p2<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->opcode==OP_OpenWrite );
pIn2 = &aMem[p2];
assert( memIsValid(pIn2) );
assert( (pIn2->flags & MEM_Int)!=0 );
@@ -82918,7 +86554,7 @@ case OP_OpenEphemeral: {
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1);
+ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -83145,10 +86781,10 @@ case OP_ColumnsUsed: {
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
-case OP_SeekLT: /* jump, in3 */
-case OP_SeekLE: /* jump, in3 */
-case OP_SeekGE: /* jump, in3 */
-case OP_SeekGT: { /* jump, in3 */
+case OP_SeekLT: /* jump, in3, group */
+case OP_SeekLE: /* jump, in3, group */
+case OP_SeekGE: /* jump, in3, group */
+case OP_SeekGT: { /* jump, in3, group */
int res; /* Comparison result */
int oc; /* Opcode */
VdbeCursor *pC; /* The cursor to seek */
@@ -83326,6 +86962,25 @@ seek_not_found:
break;
}
+/* Opcode: SeekHit P1 P2 * * *
+** Synopsis: seekHit=P2
+**
+** Set the seekHit flag on cursor P1 to the value in P2.
+** The seekHit flag is used by the IfNoHope opcode.
+**
+** P1 must be a valid b-tree cursor. P2 must be a boolean value,
+** either 0 or 1.
+*/
+case OP_SeekHit: {
+ VdbeCursor *pC;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pOp->p2==0 || pOp->p2==1 );
+ pC->seekHit = pOp->p2 & 1;
+ break;
+}
+
/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
@@ -83360,7 +87015,34 @@ seek_not_found:
** advanced in either direction. In other words, the Next and Prev
** opcodes do not work after this operation.
**
-** See also: Found, NotExists, NoConflict
+** See also: Found, NotExists, NoConflict, IfNoHope
+*/
+/* Opcode: IfNoHope P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
+**
+** Register P3 is the first of P4 registers that form an unpacked
+** record.
+**
+** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then
+** this opcode is a no-op. But if the seekHit flag of P1 is clear, then
+** check to see if there is any entry in P1 that matches the
+** prefix identified by P3 and P4. If no entry matches the prefix,
+** jump to P2. Otherwise fall through.
+**
+** This opcode behaves like OP_NotFound if the seekHit
+** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
+**
+** This opcode is used in IN clause processing for a multi-column key.
+** If an IN clause is attached to an element of the key other than the
+** left-most element, and if there are no matches on the most recent
+** seek over the whole key, then it might be that one of the key element
+** to the left is prohibiting a match, and hence there is "no hope" of
+** any match regardless of how many IN clause elements are checked.
+** In such a case, we abandon the IN clause search early, using this
+** opcode. The opcode name comes from the fact that the
+** jump is taken if there is "no hope" of achieving a match.
+**
+** See also: NotFound, SeekHit
*/
/* Opcode: NoConflict P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
@@ -83385,6 +87067,14 @@ seek_not_found:
**
** See also: NotFound, Found, NotExists
*/
+case OP_IfNoHope: { /* jump, in3 */
+ VdbeCursor *pC;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ if( pC->seekHit ) break;
+ /* Fall through into OP_NotFound */
+}
case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
@@ -83522,18 +87212,26 @@ case OP_SeekRowid: { /* jump, in3 */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & MEM_Int)==0 ){
+ /* Make sure pIn3->u.i contains a valid integer representation of
+ ** the key value, but do not change the datatype of the register, as
+ ** other parts of the perpared statement might be depending on the
+ ** current datatype. */
+ u16 origFlags = pIn3->flags;
+ int isNotInt;
applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
- if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
+ isNotInt = (pIn3->flags & MEM_Int)==0;
+ pIn3->flags = origFlags;
+ if( isNotInt ) goto jump_to_p2;
}
/* Fall through into OP_NotExists */
case OP_NotExists: /* jump, in3 */
pIn3 = &aMem[pOp->p3];
- assert( pIn3->flags & MEM_Int );
+ assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
- pC->seekOp = 0;
+ pC->seekOp = OP_SeekRowid;
#endif
assert( pC->isTable );
assert( pC->eCurType==CURTYPE_BTREE );
@@ -83608,6 +87306,7 @@ case OP_NewRowid: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
+ assert( pC->isTable );
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0 );
{
@@ -83764,10 +87463,8 @@ case OP_InsertInt: {
int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
const char *zDb; /* database name - used by the update hook */
Table *pTab; /* Table structure - used by update and pre-update hooks */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
BtreePayload x; /* Payload to be inserted */
- op = 0;
pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( memIsValid(pData) );
@@ -83778,6 +87475,7 @@ case OP_InsertInt: {
assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
REGISTER_TRACE(pOp->p2, pData);
+ sqlite3VdbeIncrWriteCounter(p, pC);
if( pOp->opcode==OP_Insert ){
pKey = &aMem[pOp->p3];
@@ -83795,19 +87493,21 @@ case OP_InsertInt: {
zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
- op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
}else{
- pTab = 0; /* Not needed. Silence a compiler warning. */
+ pTab = 0;
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, x.nKey, pOp->p2);
+ if( pTab ){
+ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
+ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
+ }
+ if( db->xUpdateCallback==0 || pTab->aCol==0 ){
+ /* Prevent post-update hook from running in cases when it should not */
+ pTab = 0;
+ }
}
if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif
@@ -83832,8 +87532,12 @@ case OP_InsertInt: {
/* Invoke the update-hook if required. */
if( rc ) goto abort_due_to_error;
- if( db->xUpdateCallback && op ){
- db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
+ if( pTab ){
+ assert( db->xUpdateCallback!=0 );
+ assert( pTab->aCol!=0 );
+ db->xUpdateCallback(db->pUpdateArg,
+ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
+ zDb, pTab->zName, x.nKey);
}
break;
}
@@ -83886,6 +87590,7 @@ case OP_Delete: {
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0 );
assert( pC->deferredMoveto==0 );
+ sqlite3VdbeIncrWriteCounter(p, pC);
#ifdef SQLITE_DEBUG
if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
@@ -84054,10 +87759,10 @@ case OP_SorterData: {
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
**
-** If P3!=0 then this opcode is allowed to make an ephermeral pointer
+** If P3!=0 then this opcode is allowed to make an ephemeral pointer
** into the database page. That means that the content of the output
** register will be invalidated as soon as the cursor moves - including
-** moves caused by other cursors that "save" the the current cursors
+** moves caused by other cursors that "save" the current cursors
** position in order that they can write to the same table. If P3==0
** then a copy of the data is made into memory. P3!=0 is faster, but
** P3==0 is safer.
@@ -84180,6 +87885,9 @@ case OP_NullRow: {
assert( pC->uc.pCursor!=0 );
sqlite3BtreeClearCursor(pC->uc.pCursor);
}
+#ifdef SQLITE_DEBUG
+ if( pC->seekOp==0 ) pC->seekOp = OP_NullRow;
+#endif
break;
}
@@ -84298,7 +88006,7 @@ case OP_Sort: { /* jump */
p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* Fall through into OP_Rewind */
}
-/* Opcode: Rewind P1 P2 * * *
+/* Opcode: Rewind P1 P2 * * P5
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
@@ -84306,6 +88014,10 @@ case OP_Sort: { /* jump */
** If the table or index is not empty, fall through to the following
** instruction.
**
+** If P5 is non-zero and the table is not empty, then the "skip-next"
+** flag is set on the cursor so that the next OP_Next instruction
+** executed on it is a no-op.
+**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
@@ -84330,6 +88042,9 @@ case OP_Rewind: { /* jump */
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
+#endif
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
@@ -84366,12 +88081,7 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
-** See also: Prev, NextIfOpen
-*/
-/* Opcode: NextIfOpen P1 P2 P3 P4 P5
-**
-** This opcode works just like Next except that if cursor P1 is not
-** open it behaves a no-op.
+** See also: Prev
*/
/* Opcode: Prev P1 P2 P3 P4 P5
**
@@ -84399,11 +88109,6 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
-/* Opcode: PrevIfOpen P1 P2 P3 P4 P5
-**
-** This opcode works just like Prev except that if cursor P1 is not
-** open it behaves a no-op.
-*/
/* Opcode: SorterNext P1 P2 * * P5
**
** This opcode works just like OP_Next except that P1 must be a
@@ -84418,10 +88123,6 @@ case OP_SorterNext: { /* jump */
assert( isSorter(pC) );
rc = sqlite3VdbeSorterNext(db, pC);
goto next_tail;
-case OP_PrevIfOpen: /* jump */
-case OP_NextIfOpen: /* jump */
- if( p->apCsr[pOp->p1]==0 ) break;
- /* Fall through */
case OP_Prev: /* jump */
case OP_Next: /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -84432,17 +88133,17 @@ case OP_Next: /* jump */
assert( pC->eCurType==CURTYPE_BTREE );
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
- assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
- assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
- /* The Next opcode is only used after SeekGT, SeekGE, and Rewind.
+ /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
- assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen
+ assert( pOp->opcode!=OP_Next
|| pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
- || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found);
- assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen
+ || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
+ || pC->seekOp==OP_NullRow);
+ assert( pOp->opcode!=OP_Prev
|| pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
- || pC->seekOp==OP_Last );
+ || pC->seekOp==OP_Last
+ || pC->seekOp==OP_NullRow);
rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:
@@ -84504,6 +88205,7 @@ case OP_IdxInsert: { /* in2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
+ sqlite3VdbeIncrWriteCounter(p, pC);
assert( pC!=0 );
assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
@@ -84550,6 +88252,7 @@ case OP_IdxDelete: {
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
+ sqlite3VdbeIncrWriteCounter(p, pC);
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
assert( pOp->p5==0 );
@@ -84723,7 +88426,13 @@ case OP_IdxGE: { /* jump */
}
r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
+ {
+ int i;
+ for(i=0; i<r.nField; i++){
+ assert( memIsValid(&r.aMem[i]) );
+ REGISTER_TRACE(pOp->p3+i, &aMem[pOp->p3+i]);
+ }
+ }
#endif
res = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
@@ -84772,6 +88481,7 @@ case OP_Destroy: { /* out2 */
int iMoved;
int iDb;
+ sqlite3VdbeIncrWriteCounter(p, 0);
assert( p->readOnly==0 );
assert( pOp->p1>1 );
pOut = out2Prerelease(p, pOp);
@@ -84821,6 +88531,7 @@ case OP_Destroy: { /* out2 */
case OP_Clear: {
u64 nChange;
+ sqlite3VdbeIncrWriteCounter(p, 0);
nChange = 0;
assert( p->readOnly==0 );
assert( DbMaskTest(p->btreeMask, pOp->p2) );
@@ -84870,13 +88581,14 @@ case OP_ResetSorter: {
** Allocate a new b-tree in the main database file if P1==0 or in the
** TEMP database file if P1==1 or in an attached database if
** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
-** it must be 2 (BTREE_BLOBKEY) for a index or WITHOUT ROWID table.
+** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table.
** The root page number of the new b-tree is stored in register P2.
*/
case OP_CreateBtree: { /* out2 */
int pgno;
Db *pDb;
+ sqlite3VdbeIncrWriteCounter(p, 0);
pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
@@ -84896,6 +88608,7 @@ case OP_CreateBtree: { /* out2 */
** Run the SQL statement or statements specified in the P4 string.
*/
case OP_SqlExec: {
+ sqlite3VdbeIncrWriteCounter(p, 0);
db->nSqlExec++;
rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
db->nSqlExec--;
@@ -84906,7 +88619,8 @@ case OP_SqlExec: {
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
-** that match the WHERE clause P4.
+** that match the WHERE clause P4. If P4 is a NULL pointer, then the
+** entire schema for P1 is reparsed.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine. It is thus a re-entrant opcode.
@@ -84930,11 +88644,22 @@ case OP_ParseSchema: {
iDb = pOp->p1;
assert( iDb>=0 && iDb<db->nDb );
assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
- /* Used to be a conditional */ {
+
+#ifndef SQLITE_OMIT_ALTERTABLE
+ if( pOp->p4.z==0 ){
+ sqlite3SchemaClear(db->aDb[iDb].pSchema);
+ db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
+ rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
+ db->mDbFlags |= DBFLAG_SchemaChange;
+ p->expired = 0;
+ }else
+#endif
+ {
zMaster = MASTER_NAME;
initData.db = db;
initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
+ initData.mInitFlags = 0;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
@@ -84985,6 +88710,7 @@ case OP_LoadAnalysis: {
** schema consistent with what is on disk.
*/
case OP_DropTable: {
+ sqlite3VdbeIncrWriteCounter(p, 0);
sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
break;
}
@@ -84998,6 +88724,7 @@ case OP_DropTable: {
** schema consistent with what is on disk.
*/
case OP_DropIndex: {
+ sqlite3VdbeIncrWriteCounter(p, 0);
sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
break;
}
@@ -85011,6 +88738,7 @@ case OP_DropIndex: {
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {
+ sqlite3VdbeIncrWriteCounter(p, 0);
sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
break;
}
@@ -85084,11 +88812,11 @@ case OP_RowSetAdd: { /* in1, in2 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
assert( (pIn2->flags & MEM_Int)!=0 );
- if( (pIn1->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIn1);
- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
+ if( (pIn1->flags & MEM_Blob)==0 ){
+ if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
}
- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
+ assert( sqlite3VdbeMemIsRowSet(pIn1) );
+ sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i);
break;
}
@@ -85104,8 +88832,9 @@ case OP_RowSetRead: { /* jump, in1, out3 */
i64 val;
pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
+ assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) );
+ if( (pIn1->flags & MEM_Blob)==0
+ || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
@@ -85154,20 +88883,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */
/* If there is anything other than a rowset object in memory cell P1,
** delete it now and initialize P1 with an empty rowset
*/
- if( (pIn1->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIn1);
- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
+ if( (pIn1->flags & MEM_Blob)==0 ){
+ if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
}
-
+ assert( sqlite3VdbeMemIsRowSet(pIn1) );
assert( pOp->p4type==P4_INT32 );
assert( iSet==-1 || iSet>=0 );
if( iSet ){
- exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
+ exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i);
VdbeBranchTaken(exists!=0,2);
if( exists ) goto jump_to_p2;
}
if( iSet>=0 ){
- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
+ sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i);
}
break;
}
@@ -85231,7 +88959,7 @@ case OP_Program: { /* jump */
** of the current program, and the memory required at runtime to execute
** the trigger program. If this trigger has been fired before, then pRt
** is already allocated. Otherwise, it must be initialized. */
- if( (pRt->flags&MEM_Frame)==0 ){
+ if( (pRt->flags&MEM_Blob)==0 ){
/* SubProgram.nMem is set to the number of memory cells used by the
** program stored in SubProgram.aOp. As well as these, one memory
** cell is required for each cursor used by the program. Set local
@@ -85249,8 +88977,10 @@ case OP_Program: { /* jump */
goto no_mem;
}
sqlite3VdbeMemRelease(pRt);
- pRt->flags = MEM_Frame;
- pRt->u.pFrame = pFrame;
+ pRt->flags = MEM_Blob|MEM_Dyn;
+ pRt->z = (char*)pFrame;
+ pRt->n = nByte;
+ pRt->xDel = sqlite3VdbeFrameMemDel;
pFrame->v = p;
pFrame->nChildMem = nMem;
@@ -85266,6 +88996,9 @@ case OP_Program: { /* jump */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
pFrame->anExec = p->anExec;
#endif
+#ifdef SQLITE_DEBUG
+ pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
+#endif
pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
@@ -85273,7 +89006,8 @@ case OP_Program: { /* jump */
pMem->db = db;
}
}else{
- pFrame = pRt->u.pFrame;
+ pFrame = (VdbeFrame*)pRt->z;
+ assert( pRt->xDel==sqlite3VdbeFrameMemDel );
assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem
|| (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
assert( pProgram->nCsr==pFrame->nChildCsr );
@@ -85502,24 +89236,35 @@ case OP_DecrJumpZero: { /* jump, in1 */
}
-/* Opcode: AggStep0 * P2 P3 P4 P5
+/* Opcode: AggStep * P2 P3 P4 P5
** Synopsis: accum=r[P3] step(r[P2@P5])
**
-** Execute the step function for an aggregate. The
-** function has P5 arguments. P4 is a pointer to the FuncDef
-** structure that specifies the function. Register P3 is the
+** Execute the xStep function for an aggregate.
+** The function has P5 arguments. P4 is a pointer to the
+** FuncDef structure that specifies the function. Register P3 is the
** accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
*/
-/* Opcode: AggStep * P2 P3 P4 P5
+/* Opcode: AggInverse * P2 P3 P4 P5
+** Synopsis: accum=r[P3] inverse(r[P2@P5])
+**
+** Execute the xInverse function for an aggregate.
+** The function has P5 arguments. P4 is a pointer to the
+** FuncDef structure that specifies the function. Register P3 is the
+** accumulator.
+**
+** The P5 arguments are taken from register P2 and its
+** successors.
+*/
+/* Opcode: AggStep1 P1 P2 P3 P4 P5
** Synopsis: accum=r[P3] step(r[P2@P5])
**
-** Execute the step function for an aggregate. The
-** function has P5 arguments. P4 is a pointer to an sqlite3_context
-** object that is used to run the function. Register P3 is
-** as the accumulator.
+** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
+** aggregate. The function has P5 arguments. P4 is a pointer to the
+** FuncDef structure that specifies the function. Register P3 is the
+** accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
@@ -85530,7 +89275,8 @@ case OP_DecrJumpZero: { /* jump, in1 */
** sqlite3_context only happens once, instead of on each call to the
** step function.
*/
-case OP_AggStep0: {
+case OP_AggInverse:
+case OP_AggStep: {
int n;
sqlite3_context *pCtx;
@@ -85539,28 +89285,47 @@ case OP_AggStep0: {
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*));
+ pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
+ (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
if( pCtx==0 ) goto no_mem;
pCtx->pMem = 0;
+ pCtx->pOut = (Mem*)&(pCtx->argv[n]);
+ sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
+ pCtx->skipFlag = 0;
+ pCtx->isError = 0;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
- pOp->opcode = OP_AggStep;
+
+ /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
+ assert( pOp->p1==(pOp->opcode==OP_AggInverse) );
+
+ pOp->opcode = OP_AggStep1;
/* Fall through into OP_AggStep */
}
-case OP_AggStep: {
+case OP_AggStep1: {
int i;
sqlite3_context *pCtx;
Mem *pMem;
- Mem t;
assert( pOp->p4type==P4_FUNCCTX );
pCtx = pOp->p4.pCtx;
pMem = &aMem[pOp->p3];
+#ifdef SQLITE_DEBUG
+ if( pOp->p1 ){
+ /* This is an OP_AggInverse call. Verify that xStep has always
+ ** been called at least once prior to any xInverse call. */
+ assert( pMem->uTemp==0x1122e0e3 );
+ }else{
+ /* This is an OP_AggStep call. Mark it as such. */
+ pMem->uTemp = 0x1122e0e3;
+ }
+#endif
+
/* If this function is inside of a trigger, the register array in aMem[]
** might change from one evaluation to the next. The next block of code
** checks to see if the register array has changed, and if so it
@@ -85578,48 +89343,80 @@ case OP_AggStep: {
#endif
pMem->n++;
- sqlite3VdbeMemInit(&t, db, MEM_Null);
- pCtx->pOut = &t;
- pCtx->fErrorOrAux = 0;
- pCtx->skipFlag = 0;
+ assert( pCtx->pOut->flags==MEM_Null );
+ assert( pCtx->isError==0 );
+ assert( pCtx->skipFlag==0 );
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pOp->p1 ){
+ (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
+ }else
+#endif
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
- if( pCtx->fErrorOrAux ){
- if( pCtx->isError ){
- sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
+
+ if( pCtx->isError ){
+ if( pCtx->isError>0 ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
rc = pCtx->isError;
}
- sqlite3VdbeMemRelease(&t);
+ if( pCtx->skipFlag ){
+ assert( pOp[-1].opcode==OP_CollSeq );
+ i = pOp[-1].p1;
+ if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
+ pCtx->skipFlag = 0;
+ }
+ sqlite3VdbeMemRelease(pCtx->pOut);
+ pCtx->pOut->flags = MEM_Null;
+ pCtx->isError = 0;
if( rc ) goto abort_due_to_error;
- }else{
- assert( t.flags==MEM_Null );
- }
- if( pCtx->skipFlag ){
- assert( pOp[-1].opcode==OP_CollSeq );
- i = pOp[-1].p1;
- if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
+ assert( pCtx->pOut->flags==MEM_Null );
+ assert( pCtx->skipFlag==0 );
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
** Synopsis: accum=r[P1] N=P2
**
-** Execute the finalizer function for an aggregate. P1 is
-** the memory location that is the accumulator for the aggregate.
+** P1 is the memory location that is the accumulator for an aggregate
+** or window function. Execute the finalizer function
+** for an aggregate and store the result in P1.
+**
+** P2 is the number of arguments that the step function takes and
+** P4 is a pointer to the FuncDef for this function. The P2
+** argument is not used by this opcode. It is only there to disambiguate
+** functions that can take varying numbers of arguments. The
+** P4 argument is only needed for the case where
+** the step function was not previously called.
+*/
+/* Opcode: AggValue * P2 P3 P4 *
+** Synopsis: r[P3]=value N=P2
+**
+** Invoke the xValue() function and store the result in register P3.
**
** P2 is the number of arguments that the step function takes and
** P4 is a pointer to the FuncDef for this function. The P2
** argument is not used by this opcode. It is only there to disambiguate
** functions that can take varying numbers of arguments. The
-** P4 argument is only needed for the degenerate case where
+** P4 argument is only needed for the case where
** the step function was not previously called.
*/
+case OP_AggValue:
case OP_AggFinal: {
Mem *pMem;
assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+ assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
pMem = &aMem[pOp->p1];
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pOp->p3 ){
+ rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
+ pMem = &aMem[pOp->p3];
+ }else
+#endif
+ {
+ rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+ }
+
if( rc ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
goto abort_due_to_error;
@@ -85814,7 +89611,7 @@ case OP_IncrVacuum: { /* jump */
}
#endif
-/* Opcode: Expire P1 * * * *
+/* Opcode: Expire P1 P2 * * *
**
** Cause precompiled statements to expire. When an expired statement
** is executed using sqlite3_step() it will either automatically
@@ -85823,12 +89620,19 @@ case OP_IncrVacuum: { /* jump */
**
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is expired.
+**
+** If P2 is 0, then SQL statements are expired immediately. If P2 is 1,
+** then running SQL statements are allowed to continue to run to completion.
+** The P2==1 case occurs when a CREATE INDEX or similar schema change happens
+** that might help the statement run faster but which does not affect the
+** correctness of operation.
*/
case OP_Expire: {
+ assert( pOp->p2==0 || pOp->p2==1 );
if( !pOp->p1 ){
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, pOp->p2);
}else{
- p->expired = 1;
+ p->expired = pOp->p2+1;
}
break;
}
@@ -86042,12 +89846,19 @@ case OP_VFilter: { /* jump */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 P3 * *
+/* Opcode: VColumn P1 P2 P3 * P5
** Synopsis: r[P3]=vcolumn(P2)
**
-** Store the value of the P2-th column of
-** the row of the virtual-table that the
-** P1 cursor is pointing to into register P3.
+** Store in register P3 the value of the P2-th column of
+** the current row of the virtual-table of cursor P1.
+**
+** If the VColumn opcode is being used to fetch the value of
+** an unchanging column during an UPDATE operation, then the P5
+** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
+** function to return true inside the xColumn method of the virtual
+** table implementation. The P5 column might also contain other
+** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
+** unused by OP_VColumn.
*/
case OP_VColumn: {
sqlite3_vtab *pVtab;
@@ -86069,10 +89880,18 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
- MemSetTypeFlag(pDest, MEM_Null);
+ testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
+ if( pOp->p5 & OPFLAG_NOCHNG ){
+ sqlite3VdbeMemSetNull(pDest);
+ pDest->flags = MEM_Null|MEM_Zero;
+ pDest->u.nZero = 0;
+ }else{
+ MemSetTypeFlag(pDest, MEM_Null);
+ }
rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
sqlite3VtabImportErrmsg(p, pVtab);
- if( sContext.isError ){
+ if( sContext.isError>0 ){
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest));
rc = sContext.isError;
}
sqlite3VdbeChangeEncoding(pDest, encoding);
@@ -86139,7 +89958,10 @@ case OP_VNext: { /* jump */
case OP_VRename: {
sqlite3_vtab *pVtab;
Mem *pName;
-
+ int isLegacy;
+
+ isLegacy = (db->flags & SQLITE_LegacyAlter);
+ db->flags |= SQLITE_LegacyAlter;
pVtab = pOp->p4.pVtab->pVtab;
pName = &aMem[pOp->p1];
assert( pVtab->pModule->xRename );
@@ -86153,6 +89975,7 @@ case OP_VRename: {
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc ) goto abort_due_to_error;
rc = pVtab->pModule->xRename(pVtab, pName->z);
+ if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter;
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
if( rc ) goto abort_due_to_error;
@@ -86201,6 +90024,8 @@ case OP_VUpdate: {
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
);
assert( p->readOnly==0 );
+ if( db->mallocFailed ) goto no_mem;
+ sqlite3VdbeIncrWriteCounter(p, 0);
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
@@ -86321,8 +90146,8 @@ case OP_MaxPgcnt: { /* out2 */
**
** See also: Function0, AggStep, AggFinal
*/
-case OP_PureFunc0:
-case OP_Function0: {
+case OP_PureFunc0: /* group */
+case OP_Function0: { /* group */
int n;
sqlite3_context *pCtx;
@@ -86337,6 +90162,7 @@ case OP_Function0: {
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
+ pCtx->isError = 0;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
@@ -86345,8 +90171,8 @@ case OP_Function0: {
pOp->opcode += 2;
/* Fall through into OP_Function */
}
-case OP_PureFunc:
-case OP_Function: {
+case OP_PureFunc: /* group */
+case OP_Function: { /* group */
int i;
sqlite3_context *pCtx;
@@ -86371,16 +90197,17 @@ case OP_Function: {
}
#endif
MemSetTypeFlag(pOut, MEM_Null);
- pCtx->fErrorOrAux = 0;
+ assert( pCtx->isError==0 );
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
- if( pCtx->fErrorOrAux ){
- if( pCtx->isError ){
+ if( pCtx->isError ){
+ if( pCtx->isError>0 ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
+ pCtx->isError = 0;
if( rc ) goto abort_due_to_error;
}
@@ -86395,7 +90222,13 @@ case OP_Function: {
break;
}
-
+/* Opcode: Trace P1 P2 * P4 *
+**
+** Write P4 on the statement trace output if statement tracing is
+** enabled.
+**
+** Operand P1 must be 0x7fffffff and P2 must positive.
+*/
/* Opcode: Init P1 P2 P3 P4 *
** Synopsis: Start at P2
**
@@ -86414,9 +90247,12 @@ case OP_Function: {
** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
** error is encountered.
*/
+case OP_Trace:
case OP_Init: { /* jump */
- char *zTrace;
int i;
+#ifndef SQLITE_OMIT_TRACE
+ char *zTrace;
+#endif
/* If the P4 argument is not NULL, then it must be an SQL comment string.
** The "--" string is broken up to prevent false-positives with srcck1.c.
@@ -86428,7 +90264,9 @@ case OP_Init: { /* jump */
** sqlite3_expanded_sql(P) otherwise.
*/
assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
- assert( pOp==p->aOp ); /* Always instruction 0 */
+
+ /* OP_Init is always instruction 0 */
+ assert( pOp==p->aOp || pOp->opcode==OP_Trace );
#ifndef SQLITE_OMIT_TRACE
if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
@@ -86471,6 +90309,7 @@ case OP_Init: { /* jump */
#endif /* SQLITE_OMIT_TRACE */
assert( pOp->p2>0 );
if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
+ if( pOp->opcode==OP_Trace ) break;
for(i=1; i<p->nOp; i++){
if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
}
@@ -86504,6 +90343,22 @@ case OP_CursorHint: {
}
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+#ifdef SQLITE_DEBUG
+/* Opcode: Abortable * * * * *
+**
+** Verify that an Abort can happen. Assert if an Abort at this point
+** might cause database corruption. This opcode only appears in debugging
+** builds.
+**
+** An Abort is safe if either there have been no writes, or if there is
+** an active statement journal.
+*/
+case OP_Abortable: {
+ sqlite3VdbeAssertAbortable(p);
+ break;
+}
+#endif
+
/* Opcode: Noop * * * * *
**
** Do nothing. This instruction is often useful as a jump
@@ -86515,8 +90370,9 @@ case OP_CursorHint: {
** This opcode records information from the optimizer. It is the
** the same as a no-op. This opcodesnever appears in a real VM program.
*/
-default: { /* This is really OP_Noop and OP_Explain */
+default: { /* This is really OP_Noop, OP_Explain */
assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
+
break;
}
@@ -86530,7 +90386,7 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
- u64 endTime = sqlite3Hwtime();
+ u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
if( endTime>start ) pOrigOp->cycles += endTime - start;
pOrigOp->cnt++;
}
@@ -89241,7 +93097,11 @@ static int vdbeMergeEngineInit(
){
int rc = SQLITE_OK; /* Return code */
int i; /* For looping over PmaReader objects */
- int nTree = pMerger->nTree;
+ int nTree; /* Number of subtrees to merge */
+
+ /* Failure to allocate the merge would have been detected prior to
+ ** invoking this routine */
+ assert( pMerger!=0 );
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
@@ -89250,6 +93110,7 @@ static int vdbeMergeEngineInit(
assert( pMerger->pTask==0 );
pMerger->pTask = pTask;
+ nTree = pMerger->nTree;
for(i=0; i<nTree; i++){
if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
/* PmaReaders should be normally initialized in order, as if they are
@@ -90378,6 +94239,14 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
}else if( pExpr->x.pList ){
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
+ Window *pWin = pExpr->pWin;
+ if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
+ if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
+ if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+ }
+#endif
}
break;
}
@@ -90415,7 +94284,6 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
return WRC_Continue;
}
@@ -90432,16 +94300,15 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
struct SrcList_item *pItem;
pSrc = p->pSrc;
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- if( pItem->fg.isTabFunc
- && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
- ){
- return WRC_Abort;
- }
+ assert( pSrc!=0 );
+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+ return WRC_Abort;
+ }
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
}
}
return WRC_Continue;
@@ -90563,29 +94430,31 @@ static void resolveAlias(
assert( pOrig!=0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
- if( pDup==0 ) return;
- if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
- if( pExpr->op==TK_COLLATE ){
- pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
- }
- ExprSetProperty(pDup, EP_Alias);
+ if( pDup!=0 ){
+ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
+ if( pExpr->op==TK_COLLATE ){
+ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
+ }
+ ExprSetProperty(pDup, EP_Alias);
- /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
- ** prevents ExprDelete() from deleting the Expr structure itself,
- ** allowing it to be repopulated by the memcpy() on the following line.
- ** The pExpr->u.zToken might point into memory that will be freed by the
- ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
- ** make a copy of the token before doing the sqlite3DbFree().
- */
- ExprSetProperty(pExpr, EP_Static);
- sqlite3ExprDelete(db, pExpr);
- memcpy(pExpr, pDup, sizeof(*pExpr));
- if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
- assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
- pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
- pExpr->flags |= EP_MemToken;
+ /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
+ ** prevents ExprDelete() from deleting the Expr structure itself,
+ ** allowing it to be repopulated by the memcpy() on the following line.
+ ** The pExpr->u.zToken might point into memory that will be freed by the
+ ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
+ ** make a copy of the token before doing the sqlite3DbFree().
+ */
+ ExprSetProperty(pExpr, EP_Static);
+ sqlite3ExprDelete(db, pExpr);
+ memcpy(pExpr, pDup, sizeof(*pExpr));
+ if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
+ assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
+ pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
+ pExpr->flags |= EP_MemToken;
+ }
+ sqlite3DbFree(db, pDup);
}
- sqlite3DbFree(db, pDup);
+ ExprSetProperty(pExpr, EP_Alias);
}
@@ -90679,7 +94548,7 @@ static int lookupName(
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
- int isTrigger = 0; /* True if resolved to a trigger column */
+ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */
Table *pTab = 0; /* Table hold the row */
Column *pCol; /* A column of pTab */
@@ -90750,6 +94619,9 @@ static int lookupName(
if( sqlite3StrICmp(zTabName, zTab)!=0 ){
continue;
}
+ if( IN_RENAME_OBJECT && pItem->zAlias ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+ }
}
if( 0==(cntTab++) ){
pMatch = pItem;
@@ -90784,22 +94656,35 @@ static int lookupName(
}
} /* if( pSrcList ) */
-#ifndef SQLITE_OMIT_TRIGGER
+#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
/* If we have not already resolved the name, then maybe
- ** it is a new.* or old.* trigger argument reference
+ ** it is a new.* or old.* trigger argument reference. Or
+ ** maybe it is an excluded.* from an upsert.
*/
- if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
- int op = pParse->eTriggerOp;
- assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
- if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
- pExpr->iTable = 1;
- pTab = pParse->pTriggerTab;
- }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
- pExpr->iTable = 0;
- pTab = pParse->pTriggerTab;
- }else{
- pTab = 0;
+ if( zDb==0 && zTab!=0 && cntTab==0 ){
+ pTab = 0;
+#ifndef SQLITE_OMIT_TRIGGER
+ if( pParse->pTriggerTab!=0 ){
+ int op = pParse->eTriggerOp;
+ assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
+ if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
+ pExpr->iTable = 1;
+ pTab = pParse->pTriggerTab;
+ }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
+ pExpr->iTable = 0;
+ pTab = pParse->pTriggerTab;
+ }
+ }
+#endif /* SQLITE_OMIT_TRIGGER */
+#ifndef SQLITE_OMIT_UPSERT
+ if( (pNC->ncFlags & NC_UUpsert)!=0 ){
+ Upsert *pUpsert = pNC->uNC.pUpsert;
+ if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
+ pTab = pUpsert->pUpsertSrc->a[0].pTab;
+ pExpr->iTable = 2;
+ }
}
+#endif /* SQLITE_OMIT_UPSERT */
if( pTab ){
int iCol;
@@ -90819,24 +94704,42 @@ static int lookupName(
}
if( iCol<pTab->nCol ){
cnt++;
- if( iCol<0 ){
- pExpr->affinity = SQLITE_AFF_INTEGER;
- }else if( pExpr->iTable==0 ){
- testcase( iCol==31 );
- testcase( iCol==32 );
- pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
- }else{
- testcase( iCol==31 );
- testcase( iCol==32 );
- pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
+#ifndef SQLITE_OMIT_UPSERT
+ if( pExpr->iTable==2 ){
+ testcase( iCol==(-1) );
+ if( IN_RENAME_OBJECT ){
+ pExpr->iColumn = iCol;
+ pExpr->pTab = pTab;
+ eNewExprOp = TK_COLUMN;
+ }else{
+ pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
+ eNewExprOp = TK_REGISTER;
+ ExprSetProperty(pExpr, EP_Alias);
+ }
+ }else
+#endif /* SQLITE_OMIT_UPSERT */
+ {
+#ifndef SQLITE_OMIT_TRIGGER
+ if( iCol<0 ){
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }else if( pExpr->iTable==0 ){
+ testcase( iCol==31 );
+ testcase( iCol==32 );
+ pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
+ }else{
+ testcase( iCol==31 );
+ testcase( iCol==32 );
+ pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
+ }
+ pExpr->pTab = pTab;
+ pExpr->iColumn = (i16)iCol;
+ eNewExprOp = TK_TRIGGER;
+#endif /* SQLITE_OMIT_TRIGGER */
}
- pExpr->iColumn = (i16)iCol;
- pExpr->pTab = pTab;
- isTrigger = 1;
}
}
}
-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
+#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */
/*
** Perhaps the name is a reference to the ROWID
@@ -90871,10 +94774,12 @@ static int lookupName(
** is supported for backwards compatibility only. Hence, we issue a warning
** on sqlite3_log() whenever the capability is used.
*/
- if( (pEList = pNC->pEList)!=0
- && zTab==0
+ if( (pNC->ncFlags & NC_UEList)!=0
&& cnt==0
+ && zTab==0
){
+ pEList = pNC->uNC.pEList;
+ assert( pEList!=0 );
for(j=0; j<pEList->nExpr; j++){
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
@@ -90895,6 +94800,9 @@ static int lookupName(
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
+ }
goto lookupname_end;
}
}
@@ -90919,10 +94827,16 @@ static int lookupName(
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
- if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- pExpr->op = TK_STRING;
- pExpr->pTab = 0;
- return WRC_Prune;
+ if( cnt==0 && zTab==0 ){
+ assert( pExpr->op==TK_ID );
+ if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+ pExpr->op = TK_STRING;
+ pExpr->pTab = 0;
+ return WRC_Prune;
+ }
+ if( sqlite3ExprIdToTrueFalse(pExpr) ){
+ return WRC_Prune;
+ }
}
/*
@@ -90965,7 +94879,7 @@ static int lookupName(
pExpr->pLeft = 0;
sqlite3ExprDelete(db, pExpr->pRight);
pExpr->pRight = 0;
- pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
+ pExpr->op = eNewExprOp;
ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
if( cnt==1 ){
@@ -91084,7 +94998,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
SrcList *pSrcList = pNC->pSrcList;
struct SrcList_item *pItem;
assert( pSrcList && pSrcList->nSrc==1 );
- pItem = pSrcList->a;
+ pItem = pSrcList->a;
+ assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
pExpr->op = TK_COLUMN;
pExpr->pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
@@ -91115,17 +95030,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
zTable = 0;
zColumn = pExpr->u.zToken;
}else{
+ Expr *pLeft = pExpr->pLeft;
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
- zTable = pExpr->pLeft->u.zToken;
- zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->u.zToken;
- zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
+ zDb = pLeft->u.zToken;
+ pLeft = pRight->pLeft;
+ pRight = pRight->pRight;
+ }
+ zTable = pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
+ }
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
}
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
@@ -91208,40 +95130,95 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
NC_IdxExpr|NC_PartIdx);
}
}
- if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
- pNC->nErr++;
- is_agg = 0;
- }else if( no_such_func && pParse->db->init.busy==0
+
+ if( 0==IN_RENAME_OBJECT ){
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
+ || (pDef->xValue==0 && pDef->xInverse==0)
+ || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
+ );
+ if( pDef && pDef->xValue==0 && pExpr->pWin ){
+ sqlite3ErrorMsg(pParse,
+ "%.*s() may not be used as a window function", nId, zId
+ );
+ pNC->nErr++;
+ }else if(
+ (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
+ || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
+ || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
+ ){
+ const char *zType;
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
+ zType = "window";
+ }else{
+ zType = "aggregate";
+ }
+ sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
+ pNC->nErr++;
+ is_agg = 0;
+ }
+#else
+ if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
+ sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
+ pNC->nErr++;
+ is_agg = 0;
+ }
+#endif
+ else if( no_such_func && pParse->db->init.busy==0
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
- && pParse->explain==0
+ && pParse->explain==0
#endif
- ){
- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
- pNC->nErr++;
- }else if( wrong_num_args ){
- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
- nId, zId);
- pNC->nErr++;
- }
- if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
+ ){
+ sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
+ pNC->nErr++;
+ }else if( wrong_num_args ){
+ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
+ nId, zId);
+ pNC->nErr++;
+ }
+ if( is_agg ){
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
+#else
+ pNC->ncFlags &= ~NC_AllowAgg;
+#endif
+ }
+ }
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
- NameContext *pNC2 = pNC;
- pExpr->op = TK_AGG_FUNCTION;
- pExpr->op2 = 0;
- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
- pExpr->op2++;
- pNC2 = pNC2->pNext;
- }
- assert( pDef!=0 );
- if( pNC2 ){
- assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
- testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
- pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pExpr->pWin ){
+ Select *pSel = pNC->pWinSelect;
+ sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
+ sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
+ sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
+ if( 0==pSel->pWin
+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
+ ){
+ pExpr->pWin->pNextWin = pSel->pWin;
+ pSel->pWin = pExpr->pWin;
+ }
+ pNC->ncFlags |= NC_AllowWin;
+ }else
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+ {
+ NameContext *pNC2 = pNC;
+ pExpr->op = TK_AGG_FUNCTION;
+ pExpr->op2 = 0;
+ while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
+ pExpr->op2++;
+ pNC2 = pNC2->pNext;
+ }
+ assert( pDef!=0 );
+ if( pNC2 ){
+ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
+ testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
+ pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+ }
+ pNC->ncFlags |= NC_AllowAgg;
}
- pNC->ncFlags |= NC_AllowAgg;
}
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
@@ -91270,15 +95247,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
+ case TK_IS:
+ case TK_ISNOT: {
+ Expr *pRight;
+ assert( !ExprHasProperty(pExpr, EP_Reduced) );
+ /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
+ ** and "x IS NOT FALSE". */
+ if( (pRight = pExpr->pRight)->op==TK_ID ){
+ int rc = resolveExprStep(pWalker, pRight);
+ if( rc==WRC_Abort ) return WRC_Abort;
+ if( pRight->op==TK_TRUEFALSE ){
+ pExpr->op2 = pExpr->op;
+ pExpr->op = TK_TRUTH;
+ return WRC_Continue;
+ }
+ }
+ /* Fall thru */
+ }
case TK_BETWEEN:
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
- case TK_GE:
- case TK_IS:
- case TK_ISNOT: {
+ case TK_GE: {
int nLeft, nRight;
if( pParse->db->mallocFailed ) break;
assert( pExpr->pLeft!=0 );
@@ -91381,8 +95373,8 @@ static int resolveOrderByTermToExprList(
memset(&nc, 0, sizeof(nc));
nc.pParse = pParse;
nc.pSrcList = pSelect->pSrc;
- nc.pEList = pEList;
- nc.ncFlags = NC_AllowAgg;
+ nc.uNC.pEList = pEList;
+ nc.ncFlags = NC_AllowAgg|NC_UEList;
nc.nErr = 0;
db = pParse->db;
savedSuppErr = db->suppressErr;
@@ -91627,6 +95619,19 @@ static int resolveOrderGroupBy(
}
for(j=0; j<pSelect->pEList->nExpr; j++){
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pE->pWin ){
+ /* Since this window function is being changed into a reference
+ ** to the same window function the result set, remove the instance
+ ** of this window function from the Select.pWin list. */
+ Window **pp;
+ for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
+ if( *pp==pE->pWin ){
+ *pp = (*pp)->pNextWin;
+ }
+ }
+ }
+#endif
pItem->u.x.iOrderByCol = j+1;
}
}
@@ -91683,8 +95688,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
- if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
- sqlite3ResolveExprNames(&sNC, p->pOffset) ){
+ sNC.pWinSelect = p;
+ if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
return WRC_Abort;
}
@@ -91732,12 +95737,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
*/
- sNC.ncFlags = NC_AllowAgg;
+ sNC.ncFlags = NC_AllowAgg|NC_AllowWin;
sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
+ sNC.ncFlags &= ~NC_AllowWin;
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
@@ -91766,7 +95772,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** Minor point: If this is the case, then the expression will be
** re-evaluated for each reference to it.
*/
- sNC.pEList = p->pEList;
+ assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 );
+ sNC.uNC.pEList = p->pEList;
+ sNC.ncFlags |= NC_UEList;
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
@@ -91784,7 +95792,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** outer queries
*/
sNC.pNext = 0;
- sNC.ncFlags |= NC_AllowAgg;
+ sNC.ncFlags |= NC_AllowAgg|NC_AllowWin;
/* If this is a converted compound query, move the ORDER BY clause from
** the sub-query back to the parent query. At this point each term
@@ -91815,6 +95823,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
if( db->mallocFailed ){
return WRC_Abort;
}
+ sNC.ncFlags &= ~NC_AllowWin;
/* Resolve the GROUP BY clause. At the same time, make sure
** the GROUP BY clause does not contain aggregate functions.
@@ -91999,7 +96008,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelfReference(
Table *pTab, /* The table being referenced */
int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
Expr *pExpr, /* Expression to resolve. May be NULL. */
- ExprList *pList /* Expression list to resolve. May be NUL. */
+ ExprList *pList /* Expression list to resolve. May be NULL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
@@ -92163,14 +96172,6 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
while( p ){
int op = p->op;
if( p->flags & EP_Generic ) break;
- if( op==TK_CAST || op==TK_UPLUS ){
- p = p->pLeft;
- continue;
- }
- if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
- pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
- break;
- }
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
&& p->pTab!=0
@@ -92184,6 +96185,14 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
}
break;
}
+ if( op==TK_CAST || op==TK_UPLUS ){
+ p = p->pLeft;
+ continue;
+ }
+ if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
+ break;
+ }
if( p->flags & EP_Collate ){
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
@@ -92603,7 +96612,6 @@ static void codeVectorCompare(
Expr *pL, *pR;
int r1, r2;
assert( i>=0 && i<nLeft );
- if( i>0 ) sqlite3ExprCachePush(pParse);
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
@@ -92615,7 +96623,6 @@ static void codeVectorCompare(
testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
sqlite3ReleaseTempReg(pParse, regFree1);
sqlite3ReleaseTempReg(pParse, regFree2);
- if( i>0 ) sqlite3ExprCachePop(pParse);
if( i==nLeft-1 ){
break;
}
@@ -92680,16 +96687,15 @@ static void heightOfExprList(ExprList *p, int *pnHeight){
}
}
}
-static void heightOfSelect(Select *p, int *pnHeight){
- if( p ){
+static void heightOfSelect(Select *pSelect, int *pnHeight){
+ Select *p;
+ for(p=pSelect; p; p=p->pPrior){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
- heightOfExpr(p->pOffset, pnHeight);
heightOfExprList(p->pEList, pnHeight);
heightOfExprList(p->pGroupBy, pnHeight);
heightOfExprList(p->pOrderBy, pnHeight);
- heightOfSelect(p->pPrior, pnHeight);
}
}
@@ -92964,7 +96970,12 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
** Construct a new expression node for a function with multiple
** arguments.
*/
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
+SQLITE_PRIVATE Expr *sqlite3ExprFunction(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* Argument list */
+ Token *pToken, /* Name of the function */
+ int eDistinct /* SF_Distinct or SF_ALL or 0 */
+){
Expr *pNew;
sqlite3 *db = pParse->db;
assert( pToken );
@@ -92973,9 +96984,14 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
return 0;
}
+ if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
+ }
pNew->x.pList = pList;
+ ExprSetProperty(pNew, EP_HasFunc);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
sqlite3ExprSetHeightAndFlags(pParse, pNew);
+ if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
return pNew;
}
@@ -93085,6 +97101,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
+ if( !ExprHasProperty(p, EP_Reduced) ){
+ sqlite3WindowDelete(db, p->pWin);
+ }
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
@@ -93133,7 +97152,7 @@ static int exprStructSize(Expr *p){
** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
** (unreduced) Expr objects as they or originally constructed by the parser.
** During expression analysis, extra information is computed and moved into
-** later parts of teh Expr object and that extra information might get chopped
+** later parts of the Expr object and that extra information might get chopped
** off if the expression is reduced. Note also that it does not work to
** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal
** to reduce a pristine expression tree from the parser. The implementation
@@ -93145,7 +97164,11 @@ 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 || p->op==TK_SELECT_COLUMN ){
+ if( 0==flags || p->op==TK_SELECT_COLUMN
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ || p->pWin
+#endif
+ ){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -93273,18 +97296,22 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
+ zAlloc += dupedExprNodeSize(p, dupFlags);
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
- zAlloc += dupedExprNodeSize(p, dupFlags);
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
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{
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
+ pNew->pWin = 0;
+ }else{
+ pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
+ }
+#endif /* SQLITE_OMIT_WINDOWFUNC */
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
@@ -93296,6 +97323,9 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
+ if( pzBuffer ){
+ *pzBuffer = zAlloc;
+ }
}
return pNew;
}
@@ -93385,6 +97415,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
pItem->bSpanIsTab = pOldItem->bSpanIsTab;
+ pItem->bSorterRef = pOldItem->bSorterRef;
pItem->u = pOldItem->u;
}
return pNew;
@@ -93483,7 +97514,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
pNew->pNext = pNext;
pNew->pPrior = 0;
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
- pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
@@ -93491,7 +97521,11 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith);
- sqlite3SelectSetName(pNew, p->zSelName);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ pNew->pWin = 0;
+ pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
+#endif
+ pNew->selId = p->selId;
*pp = pNew;
pp = &pNew->pPrior;
pNext = pNew;
@@ -93663,6 +97697,9 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
assert( pItem->zName==0 );
pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote ) sqlite3Dequote(pItem->zName);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
+ }
}
}
@@ -93677,17 +97714,16 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
SQLITE_PRIVATE void sqlite3ExprListSetSpan(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
- ExprSpan *pSpan /* The span to be added */
+ const char *zStart, /* Start of the span */
+ const char *zEnd /* End of the span */
){
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
+ pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
}
}
@@ -93757,6 +97793,34 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
}
/*
+** If the input expression is an ID with the name "true" or "false"
+** then convert it into an TK_TRUEFALSE term. Return non-zero if
+** the conversion happened, and zero if the expression is unaltered.
+*/
+SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
+ assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
+ if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
+ || sqlite3StrICmp(pExpr->u.zToken, "false")==0
+ ){
+ pExpr->op = TK_TRUEFALSE;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE
+** and 0 if it is FALSE.
+*/
+SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
+ assert( pExpr->op==TK_TRUEFALSE );
+ assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
+ || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
+ return pExpr->u.zToken[4]==0;
+}
+
+
+/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
@@ -93803,6 +97867,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
return WRC_Abort;
}
case TK_ID:
+ /* Convert "true" or "false" in a DEFAULT clause into the
+ ** appropriate TK_TRUEFALSE operator */
+ if( sqlite3ExprIdToTrueFalse(pExpr) ){
+ return WRC_Prune;
+ }
+ /* Fall thru */
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
@@ -93810,11 +97880,16 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
testcase( pExpr->op==TK_AGG_COLUMN );
+ if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){
+ return WRC_Continue;
+ }
if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
return WRC_Continue;
}
/* Fall through */
case TK_IF_NULL_ROW:
+ case TK_REGISTER:
+ testcase( pExpr->op==TK_REGISTER );
testcase( pExpr->op==TK_IF_NULL_ROW );
pWalker->eCode = 0;
return WRC_Abort;
@@ -93832,8 +97907,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
}
/* Fall through */
default:
- testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail will disallow */
- testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail will disallow */
+ testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
+ testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
return WRC_Continue;
}
}
@@ -93863,10 +97938,17 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
}
/*
-** Walk an expression tree. Return non-zero if the expression is constant
-** that does no originate from the ON or USING clauses of a join.
-** Return 0 if it involves variables or function calls or terms from
-** an ON or USING clause.
+** Walk an expression tree. Return non-zero if
+**
+** (1) the expression is constant, and
+** (2) the expression does originate in the ON or USING clause
+** of a LEFT JOIN, and
+** (3) the expression does not contain any EP_FixedCol TK_COLUMN
+** operands created by the constant propagation optimization.
+**
+** When this routine returns true, it indicates that the expression
+** can be added to the pParse->pConstExpr list and evaluated once when
+** the prepared statement starts up. See sqlite3ExprCodeAtInit().
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 2, 0);
@@ -93896,7 +97978,7 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
Expr *p = pGroupBy->a[i].pExpr;
if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
- if( sqlite3_stricmp("BINARY", pColl->zName)==0 ){
+ if( sqlite3IsBinary(pColl) ){
return WRC_Prune;
}
}
@@ -94120,7 +98202,6 @@ static Select *isCandidateForInOpt(Expr *pX){
}
assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
- assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;
assert( pSrc!=0 );
@@ -94210,16 +98291,15 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** pX->iTable made to point to the ephemeral table instead of an
** existing table.
**
-** The inFlags parameter must contain exactly one of the bits
-** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains
-** IN_INDEX_MEMBERSHIP, then the generated table will be used for a
-** fast membership test. When the IN_INDEX_LOOP bit is set, the
-** IN index will be used to loop over all values of the RHS of the
-** IN operator.
+** The inFlags parameter must contain, at a minimum, one of the bits
+** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains
+** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast
+** membership test. When the IN_INDEX_LOOP bit is set, the IN index will
+** be used to loop over all values of the RHS of the IN operator.
**
** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
** through the set members) then the b-tree must not contain duplicates.
-** An epheremal table must be used unless the selected columns are guaranteed
+** An epheremal table will be created unless the selected columns are guaranteed
** to be unique - either because it is an INTEGER PRIMARY KEY or due to
** a UNIQUE constraint or index.
**
@@ -94320,7 +98400,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
eType = IN_INDEX_ROWID;
-
+ ExplainQueryPlan((pParse, 0,
+ "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName));
sqlite3VdbeJumpHere(v, iAddr);
}else{
Index *pIdx; /* Iterator variable */
@@ -94399,11 +98480,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
if( colUsed==(MASKBIT(nExpr)-1) ){
/* If we reach this point, that means the index pIdx is usable */
int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
-#ifndef SQLITE_OMIT_EXPLAIN
- sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
- sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
- P4_DYNAMIC);
-#endif
+ ExplainQueryPlan((pParse, 0,
+ "USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
@@ -94582,7 +98660,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
int rReg = 0; /* Register storing resulting */
Vdbe *v = sqlite3GetVdbe(pParse);
if( NEVER(v==0) ) return 0;
- sqlite3ExprCachePush(pParse);
/* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
** is encountered if any of the following is true:
@@ -94598,17 +98675,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
-#ifndef SQLITE_OMIT_EXPLAIN
- if( pParse->explain==2 ){
- char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
- jmpIfDynamic>=0?"":"CORRELATED ",
- pExpr->op==TK_IN?"LIST":"SCALAR",
- pParse->iNextSelectId
- );
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
-#endif
-
switch( pExpr->op ){
case TK_IN: {
int addr; /* Address of OP_OpenEphemeral instruction */
@@ -94646,6 +98712,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
Select *pSelect = pExpr->x.pSelect;
ExprList *pEList = pSelect->pEList;
+ ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
+ jmpIfDynamic>=0?"":"CORRELATED "
+ ));
assert( !isRowid );
/* If the LHS and RHS of the IN operator do not match, that
** error will have been caught long before we reach this point. */
@@ -94687,7 +98756,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
int r1, r2, r3;
-
affinity = sqlite3ExprAffinity(pLeft);
if( !affinity ){
affinity = SQLITE_AFF_BLOB;
@@ -94727,7 +98795,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, r3, 1);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
}
}
@@ -94760,6 +98827,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
Select *pSel; /* SELECT statement to encode */
SelectDest dest; /* How to deal with SELECT result */
int nReg; /* Registers to allocate */
+ Expr *pLimit; /* New limit expression */
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
@@ -94767,6 +98835,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
+ ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
+ jmpIfDynamic>=0?"":"CORRELATED "));
nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
pParse->nMem += nReg;
@@ -94781,11 +98851,14 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
- sqlite3ExprDelete(pParse->db, pSel->pLimit);
- pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
- &sqlite3IntTokens[1], 0);
+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
+ if( pSel->pLimit ){
+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
+ pSel->pLimit->pLeft = pLimit;
+ }else{
+ pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
+ }
pSel->iLimit = 0;
- pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
@@ -94802,7 +98875,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
if( jmpIfDynamic>=0 ){
sqlite3VdbeJumpHere(v, jmpIfDynamic);
}
- sqlite3ExprCachePop(pParse);
return rReg;
}
@@ -94921,7 +98993,6 @@ static void sqlite3ExprCodeIN(
** aiMap[] array contains a mapping from the original LHS field order to
** the field order that matches the RHS index.
*/
- sqlite3ExprCachePush(pParse);
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
if( i==nVector ){
@@ -95080,7 +99151,6 @@ static void sqlite3ExprCodeIN(
sqlite3ExprCodeIN_finished:
if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
- sqlite3ExprCachePop(pParse);
VdbeComment((v, "end IN expr"));
sqlite3ExprCodeIN_oom_error:
sqlite3DbFree(pParse->db, aiMap);
@@ -95148,145 +99218,6 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
}
}
-/*
-** Erase column-cache entry number i
-*/
-static void cacheEntryClear(Parse *pParse, int i){
- if( pParse->aColCache[i].tempReg ){
- if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
- }
- }
- pParse->nColCache--;
- if( i<pParse->nColCache ){
- pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
- }
-}
-
-
-/*
-** Record in the column cache that a particular column from a
-** particular table is stored in a particular register.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
- int i;
- int minLru;
- int idxLru;
- struct yColCache *p;
-
- /* Unless an error has occurred, register numbers are always positive. */
- assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
- assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
-
- /* The SQLITE_ColumnCache flag disables the column cache. This is used
- ** for testing only - to verify that SQLite always gets the same answer
- ** with and without the column cache.
- */
- if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
-
- /* First replace any existing entry.
- **
- ** Actually, the way the column cache is currently used, we are guaranteed
- ** that the object will never already be in cache. Verify this guarantee.
- */
-#ifndef NDEBUG
- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
- assert( p->iTable!=iTab || p->iColumn!=iCol );
- }
-#endif
-
- /* If the cache is already full, delete the least recently used entry */
- if( pParse->nColCache>=SQLITE_N_COLCACHE ){
- minLru = 0x7fffffff;
- idxLru = -1;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->lru<minLru ){
- idxLru = i;
- minLru = p->lru;
- }
- }
- p = &pParse->aColCache[idxLru];
- }else{
- p = &pParse->aColCache[pParse->nColCache++];
- }
-
- /* Add the new entry to the end of the cache */
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
-}
-
-/*
-** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
-** Purge the range of registers from the column cache.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
- int i = 0;
- while( i<pParse->nColCache ){
- struct yColCache *p = &pParse->aColCache[i];
- if( p->iReg >= iReg && p->iReg < iReg+nReg ){
- cacheEntryClear(pParse, i);
- }else{
- i++;
- }
- }
-}
-
-/*
-** Remember the current column cache context. Any new entries added
-** added to the column cache after this call are removed when the
-** corresponding pop occurs.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
- pParse->iCacheLevel++;
-#ifdef SQLITE_DEBUG
- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
- printf("PUSH to %d\n", pParse->iCacheLevel);
- }
-#endif
-}
-
-/*
-** Remove from the column cache any entries that were added since the
-** the previous sqlite3ExprCachePush operation. In other words, restore
-** the cache to the state it was in prior the most recent Push.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
- int i = 0;
- assert( pParse->iCacheLevel>=1 );
- pParse->iCacheLevel--;
-#ifdef SQLITE_DEBUG
- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
- printf("POP to %d\n", pParse->iCacheLevel);
- }
-#endif
- while( i<pParse->nColCache ){
- if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
- cacheEntryClear(pParse, i);
- }else{
- i++;
- }
- }
-}
-
-/*
-** When a cached column is reused, make sure that its register is
-** no longer available as a temp register. ticket #3879: that same
-** register might be in the cache in multiple places, so be sure to
-** get them all.
-*/
-static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 0;
- }
- }
-}
/* Generate code that will load into register regOut a value that is
** appropriate for the iIdxCol-th column of index pIdx.
@@ -95342,12 +99273,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
/*
** Generate code that will extract the iColumn-th column from
-** table pTab and store the column value in a register.
-**
-** An effort is made to store the column value in register iReg. This
-** is not garanteeed for GetColumn() - the result can be stored in
-** any register. But the result is guaranteed to land in register iReg
-** for GetColumnToReg().
+** table pTab and store the column value in register iReg.
**
** There must be an open cursor to pTab in iTable when this routine
** is called. If iColumn<0 then code is generated that extracts the rowid.
@@ -95361,95 +99287,22 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
u8 p5 /* P5 value for OP_Column + FLAGS */
){
Vdbe *v = pParse->pVdbe;
- int i;
- struct yColCache *p;
-
- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
- if( p->iTable==iTable && p->iColumn==iColumn ){
- p->lru = pParse->iCacheCnt++;
- sqlite3ExprCachePinRegister(pParse, p->iReg);
- return p->iReg;
- }
- }
assert( v!=0 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
if( p5 ){
sqlite3VdbeChangeP5(v, p5);
- }else{
- sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
}
return iReg;
}
-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
- Parse *pParse, /* Parsing and code generating context */
- Table *pTab, /* Description of the table we are reading from */
- int iColumn, /* Index of the table column */
- int iTable, /* The cursor pointing to the table */
- int iReg /* Store results here */
-){
- int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
- if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
-}
-
-
-/*
-** Clear all column cache entries.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
- int i;
-
-#ifdef SQLITE_DEBUG
- if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
- printf("CLEAR\n");
- }
-#endif
- for(i=0; i<pParse->nColCache; i++){
- if( pParse->aColCache[i].tempReg
- && pParse->nTempReg<ArraySize(pParse->aTempReg)
- ){
- pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
- }
- }
- pParse->nColCache = 0;
-}
-
-/*
-** Record the fact that an affinity change has occurred on iCount
-** registers starting with iStart.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
- sqlite3ExprCacheRemove(pParse, iStart, iCount);
-}
/*
** Generate code to move content from registers iFrom...iFrom+nReg-1
-** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
+** over to iTo..iTo+nReg-1.
*/
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
- sqlite3ExprCacheRemove(pParse, iFrom, nReg);
-}
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
-/*
-** Return true if any register in the range iFrom..iTo (inclusive)
-** is used as part of the column cache.
-**
-** This routine is used within assert() and testcase() macros only
-** and does not appear in a normal build.
-*/
-static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
- int r = p->iReg;
- if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
- }
- return 0;
}
-#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
-
/*
** Convert a scalar expression node to a TK_REGISTER referencing
@@ -95526,6 +99379,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
return 0;
}
+expr_code_doover:
if( pExpr==0 ){
op = TK_NULL;
}else{
@@ -95547,6 +99401,28 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
case TK_COLUMN: {
int iTab = pExpr->iTable;
+ if( ExprHasProperty(pExpr, EP_FixedCol) ){
+ /* This COLUMN expression is really a constant due to WHERE clause
+ ** constraints, and that constant is coded by the pExpr->pLeft
+ ** expresssion. However, make sure the constant has the correct
+ ** datatype by applying the Affinity of the table column to the
+ ** constant.
+ */
+ int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
+ int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ if( aff!=SQLITE_AFF_BLOB ){
+ static const char zAff[] = "B\000C\000D\000E";
+ assert( SQLITE_AFF_BLOB=='A' );
+ assert( SQLITE_AFF_TEXT=='B' );
+ if( iReg!=target ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
+ iReg = target;
+ }
+ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
+ &zAff[(aff-'B')*2], P4_STATIC);
+ }
+ return iReg;
+ }
if( iTab<0 ){
if( pParse->iSelfTab<0 ){
/* Generating CHECK constraints or inserting into partial index */
@@ -95565,6 +99441,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
codeInteger(pParse, pExpr, 0, target);
return target;
}
+ case TK_TRUEFALSE: {
+ sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
+ return target;
+ }
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
@@ -95623,8 +99503,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
sqlite3VdbeAddOp2(v, OP_Cast, target,
sqlite3AffinityType(pExpr->u.zToken, 0));
- testcase( usedAsColumnCache(pParse, inReg, inReg) );
- sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
return inReg;
}
#endif /* SQLITE_OMIT_CAST */
@@ -95720,6 +99598,18 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3VdbeAddOp2(v, op, r1, inReg);
break;
}
+ case TK_TRUTH: {
+ int isTrue; /* IS TRUE or IS NOT TRUE */
+ int bNormal; /* IS TRUE or IS FALSE */
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
+ testcase( regFree1==0 );
+ isTrue = sqlite3ExprTruthValue(pExpr->pRight);
+ bNormal = pExpr->op2==TK_IS;
+ testcase( isTrue && bNormal);
+ testcase( !isTrue && bNormal);
+ sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal);
+ break;
+ }
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
@@ -95756,6 +99646,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
+ return pExpr->pWin->regResult;
+ }
+#endif
+
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
/* SQL functions can be expensive. So try to move constant functions
** out of the inner loop, even if that means an extra OP_Copy. */
@@ -95792,10 +99688,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
for(i=1; i<nFarg; i++){
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
VdbeCoverage(v);
- sqlite3ExprCacheRemove(pParse, target, 1);
- sqlite3ExprCachePush(pParse);
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
- sqlite3ExprCachePop(pParse);
}
sqlite3VdbeResolveLabel(v, endCoalesce);
break;
@@ -95861,10 +99754,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
}
- sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
- sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */
}else{
r1 = 0;
}
@@ -95881,7 +99772,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** "glob(B,A). We want to use the A in "A glob B" to test
** for function overloading. But we use the B term in "glob(B,A)".
*/
- if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
+ if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
}else if( nFarg>0 ){
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
@@ -95891,9 +99782,21 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( !pColl ) pColl = db->pDfltColl;
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
- sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
- constMask, r1, target, (char*)pDef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nFarg);
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){
+ Expr *pArg = pFarg->a[0].pExpr;
+ if( pArg->op==TK_COLUMN ){
+ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+ }
+ }else
+#endif
+ {
+ sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
+ constMask, r1, target, (char*)pDef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, (u8)nFarg);
+ }
if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
@@ -95958,7 +99861,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_SPAN:
case TK_COLLATE:
case TK_UPLUS: {
- return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+ pExpr = pExpr->pLeft;
+ goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
}
case TK_TRIGGER: {
@@ -95996,10 +99900,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
- VdbeComment((v, "%s.%s -> $%d",
+ VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
- target
+ (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -96025,9 +99928,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_IF_NULL_ROW: {
int addrINR;
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
- sqlite3ExprCachePush(pParse);
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- sqlite3ExprCachePop(pParse);
sqlite3VdbeJumpHere(v, addrINR);
sqlite3VdbeChangeP3(v, addrINR, inReg);
break;
@@ -96064,7 +99965,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
Expr opCompare; /* The X==Ei expression */
Expr *pX; /* The X expression */
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
- VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
assert(pExpr->x.pList->nExpr > 0);
@@ -96088,7 +99988,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
regFree1 = 0;
}
for(i=0; i<nExpr-1; i=i+2){
- sqlite3ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
opCompare.pRight = aListelem[i].pExpr;
@@ -96101,18 +100000,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
sqlite3VdbeGoto(v, endLabel);
- sqlite3ExprCachePop(pParse);
sqlite3VdbeResolveLabel(v, nextCase);
}
if( (nExpr&1)!=0 ){
- sqlite3ExprCachePush(pParse);
sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
- sqlite3ExprCachePop(pParse);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
- assert( pParse->db->mallocFailed || pParse->nErr>0
- || pParse->iCacheLevel==iCacheLevel );
sqlite3VdbeResolveLabel(v, endLabel);
break;
}
@@ -96262,7 +100156,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
** might choose to code the expression at initialization time.
*/
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
- if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
+ if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
sqlite3ExprCodeAtInit(pParse, pExpr, target);
}else{
sqlite3ExprCode(pParse, pExpr, target);
@@ -96331,6 +100225,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( pItem->bSorterRef ){
+ i--;
+ n--;
+ }else
+#endif
if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
if( flags & SQLITE_ECEL_OMITREF ){
i--;
@@ -96338,7 +100238,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
}else{
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
}
- }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
+ }else if( (flags & SQLITE_ECEL_FACTOR)!=0
+ && sqlite3ExprIsConstantNotJoin(pExpr)
+ ){
sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
@@ -96464,18 +100366,14 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse);
break;
}
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3ExprCachePop(pParse);
break;
}
case TK_NOT: {
@@ -96483,6 +100381,23 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
+ case TK_TRUTH: {
+ int isNot; /* IS NOT TRUE or IS NOT FALSE */
+ int isTrue; /* IS TRUE or IS NOT TRUE */
+ testcase( jumpIfNull==0 );
+ isNot = pExpr->op2==TK_ISNOT;
+ isTrue = sqlite3ExprTruthValue(pExpr->pRight);
+ testcase( isTrue && isNot );
+ testcase( !isTrue && isNot );
+ if( isTrue ^ isNot ){
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
+ isNot ? SQLITE_JUMPIFNULL : 0);
+ }else{
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
+ isNot ? SQLITE_JUMPIFNULL : 0);
+ }
+ break;
+ }
case TK_IS:
case TK_ISNOT:
testcase( op==TK_IS );
@@ -96617,19 +100532,15 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3ExprCachePop(pParse);
break;
}
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse);
break;
}
case TK_NOT: {
@@ -96637,6 +100548,26 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
+ case TK_TRUTH: {
+ int isNot; /* IS NOT TRUE or IS NOT FALSE */
+ int isTrue; /* IS TRUE or IS NOT TRUE */
+ testcase( jumpIfNull==0 );
+ isNot = pExpr->op2==TK_ISNOT;
+ isTrue = sqlite3ExprTruthValue(pExpr->pRight);
+ testcase( isTrue && isNot );
+ testcase( !isTrue && isNot );
+ if( isTrue ^ isNot ){
+ /* IS TRUE and IS NOT FALSE */
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
+ isNot ? 0 : SQLITE_JUMPIFNULL);
+
+ }else{
+ /* IS FALSE and IS NOT TRUE */
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
+ isNot ? 0 : SQLITE_JUMPIFNULL);
+ }
+ break;
+ }
case TK_IS:
case TK_ISNOT:
testcase( pExpr->op==TK_IS );
@@ -96822,21 +100753,40 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+ }else if( pA->op==TK_COLLATE ){
+ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
- return pA->op==TK_COLLATE ? 1 : 2;
+ return 2;
}
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
- if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
+ if( (combinedFlags & EP_FixedCol)==0
+ && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
- if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
+ assert( (combinedFlags & EP_Reduced)==0 );
+ if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ /* Justification for the assert():
+ ** window functions have p->op==TK_FUNCTION but aggregate functions
+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
+ ** function and a window function should have failed before reaching
+ ** this point. And, it is not possible to have a window function and
+ ** a scalar function with the same name and number of arguments. So
+ ** if we reach this point, either A and B both window functions or
+ ** neither are a window functions. */
+ assert( (pA->pWin==0)==(pB->pWin==0) );
+
+ if( pA->pWin!=0 ){
+ if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
+ }
+#endif
}
return 0;
}
@@ -96925,6 +100875,102 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i
}
/*
+** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
+** If the expression node requires that the table at pWalker->iCur
+** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
+**
+** This routine controls an optimization. False positives (setting
+** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
+** (never setting pWalker->eCode) is a harmless missed optimization.
+*/
+static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
+ testcase( pExpr->op==TK_AGG_COLUMN );
+ testcase( pExpr->op==TK_AGG_FUNCTION );
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
+ switch( pExpr->op ){
+ case TK_ISNOT:
+ case TK_NOT:
+ case TK_ISNULL:
+ case TK_IS:
+ case TK_OR:
+ case TK_CASE:
+ case TK_IN:
+ case TK_FUNCTION:
+ testcase( pExpr->op==TK_ISNOT );
+ testcase( pExpr->op==TK_NOT );
+ testcase( pExpr->op==TK_ISNULL );
+ testcase( pExpr->op==TK_IS );
+ testcase( pExpr->op==TK_OR );
+ testcase( pExpr->op==TK_CASE );
+ testcase( pExpr->op==TK_IN );
+ testcase( pExpr->op==TK_FUNCTION );
+ return WRC_Prune;
+ case TK_COLUMN:
+ if( pWalker->u.iCur==pExpr->iTable ){
+ pWalker->eCode = 1;
+ return WRC_Abort;
+ }
+ return WRC_Prune;
+
+ /* Virtual tables are allowed to use constraints like x=NULL. So
+ ** a term of the form x=y does not prove that y is not null if x
+ ** is the column of a virtual table */
+ case TK_EQ:
+ case TK_NE:
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ testcase( pExpr->op==TK_EQ );
+ testcase( pExpr->op==TK_NE );
+ testcase( pExpr->op==TK_LT );
+ testcase( pExpr->op==TK_LE );
+ testcase( pExpr->op==TK_GT );
+ testcase( pExpr->op==TK_GE );
+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
+ ){
+ return WRC_Prune;
+ }
+ default:
+ return WRC_Continue;
+ }
+}
+
+/*
+** Return true (non-zero) if expression p can only be true if at least
+** one column of table iTab is non-null. In other words, return true
+** if expression p will always be NULL or false if every column of iTab
+** is NULL.
+**
+** False negatives are acceptable. In other words, it is ok to return
+** zero even if expression p will never be true of every column of iTab
+** is NULL. A false negative is merely a missed optimization opportunity.
+**
+** False positives are not allowed, however. A false positive may result
+** in an incorrect answer.
+**
+** Terms of p that are marked with EP_FromJoin (and hence that come from
+** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
+**
+** This routine is used to check if a LEFT JOIN can be converted into
+** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
+** clause requires that some column of the right table of the LEFT JOIN
+** be non-NULL, then the LEFT JOIN can be safely converted into an
+** ordinary join.
+*/
+SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
+ Walker w;
+ w.xExprCallback = impliesNotNullRow;
+ w.xSelectCallback = 0;
+ w.xSelectCallback2 = 0;
+ w.eCode = 0;
+ w.u.iCur = iTab;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode;
+}
+
+/*
** An instance of the following structure is used by the tree walker
** to determine if an expression can be evaluated by reference to the
** index only, without having to do a search for the corresponding
@@ -97079,8 +101125,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
NameContext *pNC = pWalker->u.pNC;
Parse *pParse = pNC->pParse;
SrcList *pSrcList = pNC->pSrcList;
- AggInfo *pAggInfo = pNC->pAggInfo;
+ AggInfo *pAggInfo = pNC->uNC.pAggInfo;
+ assert( pNC->ncFlags & NC_UAggInfo );
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
@@ -97258,21 +101305,9 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
/*
** Deallocate a register, making available for reuse for some other
** purpose.
-**
-** If a register is currently being used by the column cache, then
-** the deallocation is deferred until the column cache line that uses
-** the register becomes stale.
*/
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 1;
- return;
- }
- }
pParse->aTempReg[pParse->nTempReg++] = iReg;
}
}
@@ -97286,7 +101321,6 @@ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
i = pParse->iRangeReg;
n = pParse->nRangeReg;
if( nReg<=n ){
- assert( !usedAsColumnCache(pParse, i, i+n-1) );
pParse->iRangeReg += nReg;
pParse->nRangeReg -= nReg;
}else{
@@ -97300,7 +101334,6 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
sqlite3ReleaseTempReg(pParse, iReg);
return;
}
- sqlite3ExprCacheRemove(pParse, iReg, nReg);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
@@ -97362,366 +101395,63 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
*/
#ifndef SQLITE_OMIT_ALTERTABLE
-
/*
-** This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
-** CREATE INDEX command. The second is a table name. The table name in
-** the CREATE TABLE or CREATE INDEX statement is replaced with the third
-** argument and the result returned. Examples:
-**
-** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
-** -> 'CREATE TABLE def(a, b, c)'
-**
-** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
-** -> 'CREATE INDEX i ON def(a, b, c)'
-*/
-static void renameTableFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
-
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TABLE
- ** statement is that the table name is the first non-space token that
- ** is immediately followed by a TK_LP or TK_USING token.
- */
- if( zSql ){
- do {
- if( !*zCsr ){
- /* Ran out of input before finding an opening bracket. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- } while( token==TK_SPACE );
- assert( len>0 );
- } while( token!=TK_LP && token!=TK_USING );
-
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
- zSql, zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-
-/*
-** This C function implements an SQL user function that is used by SQL code
-** generated by the ALTER TABLE ... RENAME command to modify the definition
-** of any foreign key constraints that use the table being renamed as the
-** parent table. It is passed three arguments:
-**
-** 1) The complete text of the CREATE TABLE statement being modified,
-** 2) The old name of the table being renamed, and
-** 3) The new name of the table being renamed.
-**
-** It returns the new CREATE TABLE statement. For example:
-**
-** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
-** -> 'CREATE TABLE t1(a REFERENCES t3)'
-*/
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-static void renameParentFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- char *zOutput = 0;
- char *zResult;
- unsigned char const *zInput = sqlite3_value_text(argv[0]);
- unsigned char const *zOld = sqlite3_value_text(argv[1]);
- unsigned char const *zNew = sqlite3_value_text(argv[2]);
-
- unsigned const char *z; /* Pointer to token */
- int n; /* Length of token z */
- int token; /* Type of token */
-
- UNUSED_PARAMETER(NotUsed);
- if( zInput==0 || zOld==0 ) return;
- for(z=zInput; *z; z=z+n){
- n = sqlite3GetToken(z, &token);
- if( token==TK_REFERENCES ){
- char *zParent;
- do {
- z += n;
- n = sqlite3GetToken(z, &token);
- }while( token==TK_SPACE );
-
- if( token==TK_ILLEGAL ) break;
- zParent = sqlite3DbStrNDup(db, (const char *)z, n);
- if( zParent==0 ) break;
- sqlite3Dequote(zParent);
- if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
- char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
- (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
- );
- sqlite3DbFree(db, zOutput);
- zOutput = zOut;
- zInput = &z[n];
- }
- sqlite3DbFree(db, zParent);
- }
- }
-
- zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput),
- sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
- sqlite3DbFree(db, zOutput);
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-/* This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
-** statement. The second is a table name. The table name in the CREATE
-** TRIGGER statement is replaced with the third argument and the result
-** returned. This is analagous to renameTableFunc() above, except for CREATE
-** TRIGGER, not CREATE INDEX and CREATE TABLE.
-*/
-static void renameTriggerFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- int dist = 3;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TRIGGER
- ** statement is that the table name is the first token that is immediately
- ** preceded by either TK_ON or TK_DOT and immediately followed by one
- ** of TK_WHEN, TK_BEGIN or TK_FOR.
- */
- if( zSql ){
- do {
-
- if( !*zCsr ){
- /* Ran out of input before finding the table name. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- }while( token==TK_SPACE );
- assert( len>0 );
-
- /* Variable 'dist' stores the number of tokens read since the most
- ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
- ** token is read and 'dist' equals 2, the condition stated above
- ** to be met.
- **
- ** Note that ON cannot be a database, table or column name, so
- ** there is no need to worry about syntax like
- ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
- */
- dist++;
- if( token==TK_DOT || token==TK_ON ){
- dist = 0;
- }
- } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
-
- /* Variable tname now contains the token that is the old table-name
- ** in the CREATE TRIGGER statement.
- */
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
- zSql, zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-#endif /* !SQLITE_OMIT_TRIGGER */
-
-/*
-** Register built-in functions used to help implement ALTER TABLE
-*/
-SQLITE_PRIVATE void sqlite3AlterFunctions(void){
- static FuncDef aAlterTableFuncs[] = {
- FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
-#ifndef SQLITE_OMIT_TRIGGER
- FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
-#endif
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
-#endif
- };
- sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
-}
-
-/*
-** This function is used to create the text of expressions of the form:
-**
-** name=<constant1> OR name=<constant2> OR ...
-**
-** If argument zWhere is NULL, then a pointer string containing the text
-** "name=<constant>" is returned, where <constant> is the quoted version
-** of the string passed as argument zConstant. The returned buffer is
-** allocated using sqlite3DbMalloc(). It is the responsibility of the
-** caller to ensure that it is eventually freed.
+** Parameter zName is the name of a table that is about to be altered
+** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
+** If the table is a system table, this function leaves an error message
+** in pParse->zErr (system tables may not be altered) and returns non-zero.
**
-** If argument zWhere is not NULL, then the string returned is
-** "<where> OR name=<constant>", where <where> is the contents of zWhere.
-** In this case zWhere is passed to sqlite3DbFree() before returning.
-**
-*/
-static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
- char *zNew;
- if( !zWhere ){
- zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
- }else{
- zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
- sqlite3DbFree(db, zWhere);
- }
- return zNew;
-}
-
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
-/*
-** Generate the text of a WHERE expression which can be used to select all
-** tables that have foreign key constraints that refer to table pTab (i.e.
-** constraints for which pTab is the parent table) from the sqlite_master
-** table.
+** Or, if zName is not a system table, zero is returned.
*/
-static char *whereForeignKeys(Parse *pParse, Table *pTab){
- FKey *p;
- char *zWhere = 0;
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
+static int isSystemTable(Parse *pParse, const char *zName){
+ if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+ sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+ return 1;
}
- return zWhere;
+ return 0;
}
-#endif
/*
-** Generate the text of a WHERE expression which can be used to select all
-** temporary triggers on table pTab from the sqlite_temp_master table. If
-** table pTab has no temporary triggers, or is itself stored in the
-** temporary database, NULL is returned.
+** Generate code to verify that the schemas of database zDb and, if
+** bTemp is not true, database "temp", can still be parsed. This is
+** called at the end of the generation of an ALTER TABLE ... RENAME ...
+** statement to ensure that the operation has not rendered any schema
+** objects unusable.
*/
-static char *whereTempTriggers(Parse *pParse, Table *pTab){
- Trigger *pTrig;
- char *zWhere = 0;
- const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
+static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
+ sqlite3NestedParse(pParse,
+ "SELECT 1 "
+ "FROM \"%w\".%s "
+ "WHERE name NOT LIKE 'sqlite_%%'"
+ " AND sql NOT LIKE 'create virtual%%'"
+ " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
+ zDb, MASTER_NAME,
+ zDb, bTemp
+ );
- /* If the table is not located in the temp-db (in which case NULL is
- ** returned, loop through the tables list of triggers. For each trigger
- ** that is not part of the temp-db schema, add a clause to the WHERE
- ** expression being built up in zWhere.
- */
- if( pTab->pSchema!=pTempSchema ){
- sqlite3 *db = pParse->db;
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- if( pTrig->pSchema==pTempSchema ){
- zWhere = whereOrName(db, zWhere, pTrig->zName);
- }
- }
- }
- if( zWhere ){
- char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
- sqlite3DbFree(pParse->db, zWhere);
- zWhere = zNew;
+ if( bTemp==0 ){
+ sqlite3NestedParse(pParse,
+ "SELECT 1 "
+ "FROM temp.%s "
+ "WHERE name NOT LIKE 'sqlite_%%'"
+ " AND sql NOT LIKE 'create virtual%%'"
+ " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
+ MASTER_NAME, zDb
+ );
}
- return zWhere;
}
/*
-** Generate code to drop and reload the internal representation of table
-** pTab from the database, including triggers and temporary triggers.
-** Argument zName is the name of the table in the database schema at
-** the time the generated code is executed. This can be different from
-** pTab->zName if this function is being called to code part of an
-** "ALTER TABLE RENAME TO" statement.
+** Generate code to reload the schema for database iDb. And, if iDb!=1, for
+** the temp database as well.
*/
-static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
- Vdbe *v;
- char *zWhere;
- int iDb; /* Index of database containing pTab */
-#ifndef SQLITE_OMIT_TRIGGER
- Trigger *pTrig;
-#endif
-
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- assert( iDb>=0 );
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Drop any table triggers from the internal schema. */
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
- assert( iTrigDb==iDb || iTrigDb==1 );
- sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
- }
-#endif
-
- /* Drop the table and index from the internal schema. */
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
-
- /* Reload the table, index and permanent trigger schemas. */
- zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
- if( !zWhere ) return;
- sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Now, if the table is not stored in the temp database, reload any temp
- ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
- sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
- }
-#endif
-}
-
-/*
-** Parameter zName is the name of a table that is about to be altered
-** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
-** If the table is a system table, this function leaves an error message
-** in pParse->zErr (system tables may not be altered) and returns non-zero.
-**
-** Or, if zName is not a system table, zero is returned.
-*/
-static int isSystemTable(Parse *pParse, const char *zName){
- if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
- return 1;
+static void renameReloadSchema(Parse *pParse, int iDb){
+ Vdbe *v = pParse->pVdbe;
+ if( v ){
+ sqlite3ChangeCookie(pParse, iDb);
+ sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0);
+ if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0);
}
- return 0;
}
/*
@@ -97741,9 +101471,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
int nTabName; /* Number of UTF-8 characters in zTabName */
const char *zTabName; /* Original name of the table */
Vdbe *v;
-#ifndef SQLITE_OMIT_TRIGGER
- char *zWhere = 0; /* Where clause to locate temp triggers */
-#endif
VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
u32 savedDbFlags; /* Saved value of db->mDbFlags */
@@ -97816,52 +101543,25 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
if( v==0 ){
goto exit_rename_table;
}
- sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
- sqlite3ChangeCookie(pParse, iDb);
-
- /* If this is a virtual table, invoke the xRename() function if
- ** one is defined. The xRename() callback will modify the names
- ** of any resources used by the v-table implementation (including other
- ** SQLite tables) that are identified by the name of the virtual table.
- */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pVTab ){
- int i = ++pParse->nMem;
- sqlite3VdbeLoadString(v, i, zName);
- sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- }
-#endif
/* figure out how many UTF-8 characters are in zName */
zTabName = pTab->zName;
nTabName = sqlite3Utf8CharLen(zTabName, -1);
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- if( db->flags&SQLITE_ForeignKeys ){
- /* If foreign-key support is enabled, rewrite the CREATE TABLE
- ** statements corresponding to all child tables of foreign key constraints
- ** for which the renamed table is the parent table. */
- if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".%s SET "
- "sql = sqlite_rename_parent(sql, %Q, %Q) "
- "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere);
- sqlite3DbFree(db, zWhere);
- }
- }
-#endif
+ /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
+ ** the schema to use the new table name. */
+ sqlite3NestedParse(pParse,
+ "UPDATE \"%w\".%s SET "
+ "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
+ "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
+ "AND name NOT LIKE 'sqlite_%%'"
+ , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
+ );
- /* Modify the sqlite_master table to use the new table name. */
+ /* Update the tbl_name and name columns of the sqlite_master table
+ ** as required. */
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET "
-#ifdef SQLITE_OMIT_TRIGGER
- "sql = sqlite_rename_table(sql, %Q), "
-#else
- "sql = CASE "
- "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
- "ELSE sqlite_rename_table(sql, %Q) END, "
-#endif
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
@@ -97870,11 +101570,9 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
"(type='table' OR type='index' OR type='trigger');",
- zDb, MASTER_NAME, zName, zName, zName,
-#ifndef SQLITE_OMIT_TRIGGER
- zName,
-#endif
- zName, nTabName, zTabName
+ zDb, MASTER_NAME,
+ zName, zName, zName,
+ nTabName, zTabName
);
#ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -97888,35 +101586,37 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
}
#endif
-#ifndef SQLITE_OMIT_TRIGGER
- /* If there are TEMP triggers on this table, modify the sqlite_temp_master
- ** table. Don't do this if the table being ALTERed is itself located in
- ** the temp database.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
+ /* If the table being renamed is not itself part of the temp database,
+ ** edit view and trigger definitions within the temp database
+ ** as required. */
+ if( iDb!=1 ){
sqlite3NestedParse(pParse,
"UPDATE sqlite_temp_master SET "
- "sql = sqlite_rename_trigger(sql, %Q), "
- "tbl_name = %Q "
- "WHERE %s;", zName, zName, zWhere);
- sqlite3DbFree(db, zWhere);
+ "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
+ "tbl_name = "
+ "CASE WHEN tbl_name=%Q COLLATE nocase AND "
+ " sqlite_rename_test(%Q, sql, type, name, 1) "
+ "THEN %Q ELSE tbl_name END "
+ "WHERE type IN ('view', 'trigger')"
+ , zDb, zTabName, zName, zTabName, zDb, zName);
}
-#endif
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- if( db->flags&SQLITE_ForeignKeys ){
- FKey *p;
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- Table *pFrom = p->pFrom;
- if( pFrom!=pTab ){
- reloadTableSchema(pParse, p->pFrom, pFrom->zName);
- }
- }
+ /* If this is a virtual table, invoke the xRename() function if
+ ** one is defined. The xRename() callback will modify the names
+ ** of any resources used by the v-table implementation (including other
+ ** SQLite tables) that are identified by the name of the virtual table.
+ */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( pVTab ){
+ int i = ++pParse->nMem;
+ sqlite3VdbeLoadString(v, i, zName);
+ sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
+ sqlite3MayAbort(pParse);
}
#endif
- /* Drop and reload the internal table schema. */
- reloadTableSchema(pParse, pTab, zName);
+ renameReloadSchema(pParse, iDb);
+ renameTestSchema(pParse, zDb, iDb==1);
exit_rename_table:
sqlite3SrcListDelete(db, pSrc);
@@ -97942,12 +101642,11 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
Column *pCol; /* The new column */
Expr *pDflt; /* Default value for the new column */
sqlite3 *db; /* The database connection; */
- Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
+ Vdbe *v; /* The prepared statement under construction */
int r1; /* Temporary registers */
db = pParse->db;
if( pParse->nErr || db->mallocFailed ) return;
- assert( v!=0 );
pNew = pParse->pNewTable;
assert( pNew );
@@ -98042,17 +101741,20 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
** from less than 3 to 4, as that will corrupt any preexisting DESC
** index.
*/
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
- sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
- sqlite3ReleaseTempReg(pParse, r1);
+ v = sqlite3GetVdbe(pParse);
+ if( v ){
+ r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+ sqlite3VdbeUsesBtree(v, iDb);
+ sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
+ sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
+ sqlite3ReleaseTempReg(pParse, r1);
+ }
- /* Reload the schema of the modified table. */
- reloadTableSchema(pParse, pTab, pTab->zName);
+ /* Reload the table definition */
+ renameReloadSchema(pParse, iDb);
}
/*
@@ -98073,7 +101775,6 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
Table *pNew;
Table *pTab;
- Vdbe *v;
int iDb;
int i;
int nAlloc;
@@ -98137,16 +101838,1142 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pNew->addColOffset = pTab->addColOffset;
pNew->nTabRef = 1;
- /* Begin a transaction and increment the schema cookie. */
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- v = sqlite3GetVdbe(pParse);
- if( !v ) goto exit_begin_add_column;
- sqlite3ChangeCookie(pParse, iDb);
-
exit_begin_add_column:
sqlite3SrcListDelete(db, pSrc);
return;
}
+
+/*
+** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN
+** command. This function checks if the table is a view or virtual
+** table (columns of views or virtual tables may not be renamed). If so,
+** it loads an error message into pParse and returns non-zero.
+**
+** Or, if pTab is not a view or virtual table, zero is returned.
+*/
+#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
+static int isRealTable(Parse *pParse, Table *pTab){
+ const char *zType = 0;
+#ifndef SQLITE_OMIT_VIEW
+ if( pTab->pSelect ){
+ zType = "view";
+ }
+#endif
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( IsVirtual(pTab) ){
+ zType = "virtual table";
+ }
+#endif
+ if( zType ){
+ sqlite3ErrorMsg(
+ pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName
+ );
+ return 1;
+ }
+ return 0;
+}
+#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
+# define isRealTable(x,y) (0)
+#endif
+
+/*
+** Handles the following parser reduction:
+**
+** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
+*/
+SQLITE_PRIVATE void sqlite3AlterRenameColumn(
+ Parse *pParse, /* Parsing context */
+ SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */
+ Token *pOld, /* Name of column being changed */
+ Token *pNew /* New column name */
+){
+ sqlite3 *db = pParse->db; /* Database connection */
+ Table *pTab; /* Table being updated */
+ int iCol; /* Index of column being renamed */
+ char *zOld = 0; /* Old column name */
+ char *zNew = 0; /* New column name */
+ const char *zDb; /* Name of schema containing the table */
+ int iSchema; /* Index of the schema */
+ int bQuote; /* True to quote the new name */
+
+ /* Locate the table to be altered */
+ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
+ if( !pTab ) goto exit_rename_column;
+
+ /* Cannot alter a system table */
+ if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
+ if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
+
+ /* Which schema holds the table to be altered */
+ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
+ assert( iSchema>=0 );
+ zDb = db->aDb[iSchema].zDbSName;
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ /* Invoke the authorization callback. */
+ if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
+ goto exit_rename_column;
+ }
+#endif
+
+ /* Make sure the old name really is a column name in the table to be
+ ** altered. Set iCol to be the index of the column being renamed */
+ zOld = sqlite3NameFromToken(db, pOld);
+ if( !zOld ) goto exit_rename_column;
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break;
+ }
+ if( iCol==pTab->nCol ){
+ sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
+ goto exit_rename_column;
+ }
+
+ /* Do the rename operation using a recursive UPDATE statement that
+ ** uses the sqlite_rename_column() SQL function to compute the new
+ ** CREATE statement text for the sqlite_master table.
+ */
+ zNew = sqlite3NameFromToken(db, pNew);
+ if( !zNew ) goto exit_rename_column;
+ assert( pNew->n>0 );
+ bQuote = sqlite3Isquote(pNew->z[0]);
+ sqlite3NestedParse(pParse,
+ "UPDATE \"%w\".%s SET "
+ "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
+ "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
+ " AND sql NOT LIKE 'create virtual%%'",
+ zDb, MASTER_NAME,
+ zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
+ pTab->zName
+ );
+
+ sqlite3NestedParse(pParse,
+ "UPDATE temp.%s SET "
+ "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
+ "WHERE type IN ('trigger', 'view')",
+ MASTER_NAME,
+ zDb, pTab->zName, iCol, zNew, bQuote
+ );
+
+ /* Drop and reload the database schema. */
+ renameReloadSchema(pParse, iSchema);
+ renameTestSchema(pParse, zDb, iSchema==1);
+
+ exit_rename_column:
+ sqlite3SrcListDelete(db, pSrc);
+ sqlite3DbFree(db, zOld);
+ sqlite3DbFree(db, zNew);
+ return;
+}
+
+/*
+** Each RenameToken object maps an element of the parse tree into
+** the token that generated that element. The parse tree element
+** might be one of:
+**
+** * A pointer to an Expr that represents an ID
+** * The name of a table column in Column.zName
+**
+** A list of RenameToken objects can be constructed during parsing.
+** Each new object is created by sqlite3RenameTokenMap().
+** As the parse tree is transformed, the sqlite3RenameTokenRemap()
+** routine is used to keep the mapping current.
+**
+** After the parse finishes, renameTokenFind() routine can be used
+** to look up the actual token value that created some element in
+** the parse tree.
+*/
+struct RenameToken {
+ void *p; /* Parse tree element created by token t */
+ Token t; /* The token that created parse tree element p */
+ RenameToken *pNext; /* Next is a list of all RenameToken objects */
+};
+
+/*
+** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
+** down into the Walker.
+*/
+typedef struct RenameCtx RenameCtx;
+struct RenameCtx {
+ RenameToken *pList; /* List of tokens to overwrite */
+ int nList; /* Number of tokens in pList */
+ int iCol; /* Index of column being renamed */
+ Table *pTab; /* Table being ALTERed */
+ const char *zOld; /* Old column name */
+};
+
+#ifdef SQLITE_DEBUG
+/*
+** This function is only for debugging. It performs two tasks:
+**
+** 1. Checks that pointer pPtr does not already appear in the
+** rename-token list.
+**
+** 2. Dereferences each pointer in the rename-token list.
+**
+** The second is most effective when debugging under valgrind or
+** address-sanitizer or similar. If any of these pointers no longer
+** point to valid objects, an exception is raised by the memory-checking
+** tool.
+**
+** The point of this is to prevent comparisons of invalid pointer values.
+** Even though this always seems to work, it is undefined according to the
+** C standard. Example of undefined comparison:
+**
+** sqlite3_free(x);
+** if( x==y ) ...
+**
+** Technically, as x no longer points into a valid object or to the byte
+** following a valid object, it may not be used in comparison operations.
+*/
+static void renameTokenCheckAll(Parse *pParse, void *pPtr){
+ if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
+ RenameToken *p;
+ u8 i = 0;
+ for(p=pParse->pRename; p; p=p->pNext){
+ if( p->p ){
+ assert( p->p!=pPtr );
+ i += *(u8*)(p->p);
+ }
+ }
+ }
+}
+#else
+# define renameTokenCheckAll(x,y)
+#endif
+
+/*
+** Add a new RenameToken object mapping parse tree element pPtr into
+** token *pToken to the Parse object currently under construction.
+**
+** Return a copy of pPtr.
+*/
+SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
+ RenameToken *pNew;
+ assert( pPtr || pParse->db->mallocFailed );
+ renameTokenCheckAll(pParse, pPtr);
+ pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
+ if( pNew ){
+ pNew->p = pPtr;
+ pNew->t = *pToken;
+ pNew->pNext = pParse->pRename;
+ pParse->pRename = pNew;
+ }
+
+ return pPtr;
+}
+
+/*
+** It is assumed that there is already a RenameToken object associated
+** with parse tree element pFrom. This function remaps the associated token
+** to parse tree element pTo.
+*/
+SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){
+ RenameToken *p;
+ renameTokenCheckAll(pParse, pTo);
+ for(p=pParse->pRename; p; p=p->pNext){
+ if( p->p==pFrom ){
+ p->p = pTo;
+ break;
+ }
+ }
+}
+
+/*
+** Walker callback used by sqlite3RenameExprUnmap().
+*/
+static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
+ Parse *pParse = pWalker->pParse;
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
+ return WRC_Continue;
+}
+
+/*
+** Remove all nodes that are part of expression pExpr from the rename list.
+*/
+SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
+ Walker sWalker;
+ memset(&sWalker, 0, sizeof(Walker));
+ sWalker.pParse = pParse;
+ sWalker.xExprCallback = renameUnmapExprCb;
+ sqlite3WalkExpr(&sWalker, pExpr);
+}
+
+/*
+** Remove all nodes that are part of expression-list pEList from the
+** rename list.
+*/
+SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
+ if( pEList ){
+ int i;
+ Walker sWalker;
+ memset(&sWalker, 0, sizeof(Walker));
+ sWalker.pParse = pParse;
+ sWalker.xExprCallback = renameUnmapExprCb;
+ sqlite3WalkExprList(&sWalker, pEList);
+ for(i=0; i<pEList->nExpr; i++){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
+ }
+ }
+}
+
+/*
+** Free the list of RenameToken objects given in the second argument
+*/
+static void renameTokenFree(sqlite3 *db, RenameToken *pToken){
+ RenameToken *pNext;
+ RenameToken *p;
+ for(p=pToken; p; p=pNext){
+ pNext = p->pNext;
+ sqlite3DbFree(db, p);
+ }
+}
+
+/*
+** Search the Parse object passed as the first argument for a RenameToken
+** object associated with parse tree element pPtr. If found, remove it
+** from the Parse object and add it to the list maintained by the
+** RenameCtx object passed as the second argument.
+*/
+static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
+ RenameToken **pp;
+ assert( pPtr!=0 );
+ for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
+ if( (*pp)->p==pPtr ){
+ RenameToken *pToken = *pp;
+ *pp = pToken->pNext;
+ pToken->pNext = pCtx->pList;
+ pCtx->pList = pToken;
+ pCtx->nList++;
+ break;
+ }
+ }
+}
+
+/*
+** This is a Walker select callback. It does nothing. It is only required
+** because without a dummy callback, sqlite3WalkExpr() and similar do not
+** descend into sub-select statements.
+*/
+static int renameColumnSelectCb(Walker *pWalker, Select *p){
+ UNUSED_PARAMETER(pWalker);
+ UNUSED_PARAMETER(p);
+ return WRC_Continue;
+}
+
+/*
+** This is a Walker expression callback.
+**
+** For every TK_COLUMN node in the expression tree, search to see
+** if the column being references is the column being renamed by an
+** ALTER TABLE statement. If it is, then attach its associated
+** RenameToken object to the list of RenameToken objects being
+** constructed in RenameCtx object at pWalker->u.pRename.
+*/
+static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
+ RenameCtx *p = pWalker->u.pRename;
+ if( pExpr->op==TK_TRIGGER
+ && pExpr->iColumn==p->iCol
+ && pWalker->pParse->pTriggerTab==p->pTab
+ ){
+ renameTokenFind(pWalker->pParse, p, (void*)pExpr);
+ }else if( pExpr->op==TK_COLUMN
+ && pExpr->iColumn==p->iCol
+ && p->pTab==pExpr->pTab
+ ){
+ renameTokenFind(pWalker->pParse, p, (void*)pExpr);
+ }
+ return WRC_Continue;
+}
+
+/*
+** The RenameCtx contains a list of tokens that reference a column that
+** is being renamed by an ALTER TABLE statement. Return the "last"
+** RenameToken in the RenameCtx and remove that RenameToken from the
+** RenameContext. "Last" means the last RenameToken encountered when
+** the input SQL is parsed from left to right. Repeated calls to this routine
+** return all column name tokens in the order that they are encountered
+** in the SQL statement.
+*/
+static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){
+ RenameToken *pBest = pCtx->pList;
+ RenameToken *pToken;
+ RenameToken **pp;
+
+ for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){
+ if( pToken->t.z>pBest->t.z ) pBest = pToken;
+ }
+ for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
+ *pp = pBest->pNext;
+
+ return pBest;
+}
+
+/*
+** An error occured while parsing or otherwise processing a database
+** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
+** ALTER TABLE RENAME COLUMN program. The error message emitted by the
+** sub-routine is currently stored in pParse->zErrMsg. This function
+** adds context to the error message and then stores it in pCtx.
+*/
+static void renameColumnParseError(
+ sqlite3_context *pCtx,
+ int bPost,
+ sqlite3_value *pType,
+ sqlite3_value *pObject,
+ Parse *pParse
+){
+ const char *zT = (const char*)sqlite3_value_text(pType);
+ const char *zN = (const char*)sqlite3_value_text(pObject);
+ char *zErr;
+
+ zErr = sqlite3_mprintf("error in %s %s%s: %s",
+ zT, zN, (bPost ? " after rename" : ""),
+ pParse->zErrMsg
+ );
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+}
+
+/*
+** For each name in the the expression-list pEList (i.e. each
+** pEList->a[i].zName) that matches the string in zOld, extract the
+** corresponding rename-token from Parse object pParse and add it
+** to the RenameCtx pCtx.
+*/
+static void renameColumnElistNames(
+ Parse *pParse,
+ RenameCtx *pCtx,
+ ExprList *pEList,
+ const char *zOld
+){
+ if( pEList ){
+ int i;
+ for(i=0; i<pEList->nExpr; i++){
+ char *zName = pEList->a[i].zName;
+ if( 0==sqlite3_stricmp(zName, zOld) ){
+ renameTokenFind(pParse, pCtx, (void*)zName);
+ }
+ }
+ }
+}
+
+/*
+** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName)
+** that matches the string in zOld, extract the corresponding rename-token
+** from Parse object pParse and add it to the RenameCtx pCtx.
+*/
+static void renameColumnIdlistNames(
+ Parse *pParse,
+ RenameCtx *pCtx,
+ IdList *pIdList,
+ const char *zOld
+){
+ if( pIdList ){
+ int i;
+ for(i=0; i<pIdList->nId; i++){
+ char *zName = pIdList->a[i].zName;
+ if( 0==sqlite3_stricmp(zName, zOld) ){
+ renameTokenFind(pParse, pCtx, (void*)zName);
+ }
+ }
+ }
+}
+
+/*
+** Parse the SQL statement zSql using Parse object (*p). The Parse object
+** is initialized by this function before it is used.
+*/
+static int renameParseSql(
+ Parse *p, /* Memory to use for Parse object */
+ const char *zDb, /* Name of schema SQL belongs to */
+ int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL to parse */
+ int bTemp /* True if SQL is from temp schema */
+){
+ int rc;
+ char *zErr = 0;
+
+ db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
+
+ /* Parse the SQL statement passed as the first argument. If no error
+ ** occurs and the parse does not result in a new table, index or
+ ** trigger object, the database must be corrupt. */
+ memset(p, 0, sizeof(Parse));
+ p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
+ p->db = db;
+ p->nQueryLoop = 1;
+ rc = sqlite3RunParser(p, zSql, &zErr);
+ assert( p->zErrMsg==0 );
+ assert( rc!=SQLITE_OK || zErr==0 );
+ assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 );
+ p->zErrMsg = zErr;
+ if( db->mallocFailed ) rc = SQLITE_NOMEM;
+ if( rc==SQLITE_OK
+ && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
+ ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }
+
+#ifdef SQLITE_DEBUG
+ /* Ensure that all mappings in the Parse.pRename list really do map to
+ ** a part of the input string. */
+ if( rc==SQLITE_OK ){
+ int nSql = sqlite3Strlen30(zSql);
+ RenameToken *pToken;
+ for(pToken=p->pRename; pToken; pToken=pToken->pNext){
+ assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] );
+ }
+ }
+#endif
+
+ db->init.iDb = 0;
+ return rc;
+}
+
+/*
+** This function edits SQL statement zSql, replacing each token identified
+** by the linked list pRename with the text of zNew. If argument bQuote is
+** true, then zNew is always quoted first. If no error occurs, the result
+** is loaded into context object pCtx as the result.
+**
+** Or, if an error occurs (i.e. an OOM condition), an error is left in
+** pCtx and an SQLite error code returned.
+*/
+static int renameEditSql(
+ sqlite3_context *pCtx, /* Return result here */
+ RenameCtx *pRename, /* Rename context */
+ const char *zSql, /* SQL statement to edit */
+ const char *zNew, /* New token text */
+ int bQuote /* True to always quote token */
+){
+ int nNew = sqlite3Strlen30(zNew);
+ int nSql = sqlite3Strlen30(zSql);
+ sqlite3 *db = sqlite3_context_db_handle(pCtx);
+ int rc = SQLITE_OK;
+ char *zQuot;
+ char *zOut;
+ int nQuot;
+
+ /* Set zQuot to point to a buffer containing a quoted copy of the
+ ** identifier zNew. If the corresponding identifier in the original
+ ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to
+ ** point to zQuot so that all substitutions are made using the
+ ** quoted version of the new column name. */
+ zQuot = sqlite3MPrintf(db, "\"%w\"", zNew);
+ if( zQuot==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ nQuot = sqlite3Strlen30(zQuot);
+ }
+ if( bQuote ){
+ zNew = zQuot;
+ nNew = nQuot;
+ }
+
+ /* At this point pRename->pList contains a list of RenameToken objects
+ ** corresponding to all tokens in the input SQL that must be replaced
+ ** with the new column name. All that remains is to construct and
+ ** return the edited SQL string. */
+ assert( nQuot>=nNew );
+ zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1);
+ if( zOut ){
+ int nOut = nSql;
+ memcpy(zOut, zSql, nSql);
+ while( pRename->pList ){
+ int iOff; /* Offset of token to replace in zOut */
+ RenameToken *pBest = renameColumnTokenNext(pRename);
+
+ u32 nReplace;
+ const char *zReplace;
+ if( sqlite3IsIdChar(*pBest->t.z) ){
+ nReplace = nNew;
+ zReplace = zNew;
+ }else{
+ nReplace = nQuot;
+ zReplace = zQuot;
+ }
+
+ iOff = pBest->t.z - zSql;
+ if( pBest->t.n!=nReplace ){
+ memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n],
+ nOut - (iOff + pBest->t.n)
+ );
+ nOut += nReplace - pBest->t.n;
+ zOut[nOut] = '\0';
+ }
+ memcpy(&zOut[iOff], zReplace, nReplace);
+ sqlite3DbFree(db, pBest);
+ }
+
+ sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT);
+ sqlite3DbFree(db, zOut);
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+
+ sqlite3_free(zQuot);
+ return rc;
+}
+
+/*
+** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming
+** it was read from the schema of database zDb. Return SQLITE_OK if
+** successful. Otherwise, return an SQLite error code and leave an error
+** message in the Parse object.
+*/
+static int renameResolveTrigger(Parse *pParse, const char *zDb){
+ sqlite3 *db = pParse->db;
+ Trigger *pNew = pParse->pNewTrigger;
+ TriggerStep *pStep;
+ NameContext sNC;
+ int rc = SQLITE_OK;
+
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ assert( pNew->pTabSchema );
+ pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
+ db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
+ );
+ pParse->eTriggerOp = pNew->op;
+
+ /* Resolve symbols in WHEN clause */
+ if( pNew->pWhen ){
+ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
+ }
+
+ for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
+ if( pStep->pSelect ){
+ sqlite3SelectPrep(pParse, pStep->pSelect, &sNC);
+ if( pParse->nErr ) rc = pParse->rc;
+ }
+ if( rc==SQLITE_OK && pStep->zTarget ){
+ Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
+ if( pTarget==0 ){
+ rc = SQLITE_ERROR;
+ }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){
+ SrcList sSrc;
+ memset(&sSrc, 0, sizeof(sSrc));
+ sSrc.nSrc = 1;
+ sSrc.a[0].zName = pStep->zTarget;
+ sSrc.a[0].pTab = pTarget;
+ sNC.pSrcList = &sSrc;
+ if( pStep->pWhere ){
+ rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
+ }
+ assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
+ if( pStep->pUpsert ){
+ Upsert *pUpsert = pStep->pUpsert;
+ assert( rc==SQLITE_OK );
+ pUpsert->pUpsertSrc = &sSrc;
+ sNC.uNC.pUpsert = pUpsert;
+ sNC.ncFlags = NC_UUpsert;
+ rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
+ if( rc==SQLITE_OK ){
+ ExprList *pUpsertSet = pUpsert->pUpsertSet;
+ rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
+ }
+ sNC.ncFlags = 0;
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr
+** objects that are part of the trigger passed as the second argument.
+*/
+static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
+ TriggerStep *pStep;
+
+ /* Find tokens to edit in WHEN clause */
+ sqlite3WalkExpr(pWalker, pTrigger->pWhen);
+
+ /* Find tokens to edit in trigger steps */
+ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
+ sqlite3WalkSelect(pWalker, pStep->pSelect);
+ sqlite3WalkExpr(pWalker, pStep->pWhere);
+ sqlite3WalkExprList(pWalker, pStep->pExprList);
+ if( pStep->pUpsert ){
+ Upsert *pUpsert = pStep->pUpsert;
+ sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget);
+ sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet);
+ sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
+ sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
+ }
+ }
+}
+
+/*
+** Free the contents of Parse object (*pParse). Do not free the memory
+** occupied by the Parse object itself.
+*/
+static void renameParseCleanup(Parse *pParse){
+ sqlite3 *db = pParse->db;
+ if( pParse->pVdbe ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
+ }
+ sqlite3DeleteTable(db, pParse->pNewTable);
+ if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
+ sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+ sqlite3DbFree(db, pParse->zErrMsg);
+ renameTokenFree(db, pParse->pRename);
+ sqlite3ParserReset(pParse);
+}
+
+/*
+** SQL function:
+**
+** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
+**
+** 0. zSql: SQL statement to rewrite
+** 1. type: Type of object ("table", "view" etc.)
+** 2. object: Name of object
+** 3. Database: Database name (e.g. "main")
+** 4. Table: Table name
+** 5. iCol: Index of column to rename
+** 6. zNew: New column name
+** 7. bQuote: Non-zero if the new column name should be quoted.
+** 8. bTemp: True if zSql comes from temp schema
+**
+** Do a column rename operation on the CREATE statement given in zSql.
+** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
+** into zNew. The name should be quoted if bQuote is true.
+**
+** This function is used internally by the ALTER TABLE RENAME COLUMN command.
+** Though accessible to application code, it is not intended for use by
+** applications. The existance of this function, and the way it works,
+** is subject to change without notice.
+**
+** If any of the parameters are out-of-bounds, then simply return NULL.
+** An out-of-bounds parameter can only occur when the application calls
+** this function directly. The parameters will always be well-formed when
+** this routine is invoked by the bytecode for a legitimate ALTER TABLE
+** statement.
+*/
+static void renameColumnFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ RenameCtx sCtx;
+ const char *zSql = (const char*)sqlite3_value_text(argv[0]);
+ const char *zDb = (const char*)sqlite3_value_text(argv[3]);
+ const char *zTable = (const char*)sqlite3_value_text(argv[4]);
+ int iCol = sqlite3_value_int(argv[5]);
+ const char *zNew = (const char*)sqlite3_value_text(argv[6]);
+ int bQuote = sqlite3_value_int(argv[7]);
+ int bTemp = sqlite3_value_int(argv[8]);
+ const char *zOld;
+ int rc;
+ Parse sParse;
+ Walker sWalker;
+ Index *pIdx;
+ int i;
+ Table *pTab;
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ sqlite3_xauth xAuth = db->xAuth;
+#endif
+
+ UNUSED_PARAMETER(NotUsed);
+ if( zSql==0 ) return;
+ if( zTable==0 ) return;
+ if( zNew==0 ) return;
+ if( iCol<0 ) return;
+ sqlite3BtreeEnterAll(db);
+ pTab = sqlite3FindTable(db, zTable, zDb);
+ if( pTab==0 || iCol>=pTab->nCol ){
+ sqlite3BtreeLeaveAll(db);
+ return;
+ }
+ zOld = pTab->aCol[iCol].zName;
+ memset(&sCtx, 0, sizeof(sCtx));
+ sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ db->xAuth = 0;
+#endif
+ rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);
+
+ /* Find tokens that need to be replaced. */
+ memset(&sWalker, 0, sizeof(Walker));
+ sWalker.pParse = &sParse;
+ sWalker.xExprCallback = renameColumnExprCb;
+ sWalker.xSelectCallback = renameColumnSelectCb;
+ sWalker.u.pRename = &sCtx;
+
+ sCtx.pTab = pTab;
+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
+ if( sParse.pNewTable ){
+ Select *pSelect = sParse.pNewTable->pSelect;
+ if( pSelect ){
+ sParse.rc = SQLITE_OK;
+ sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
+ rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
+ if( rc==SQLITE_OK ){
+ sqlite3WalkSelect(&sWalker, pSelect);
+ }
+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
+ }else{
+ /* A regular table */
+ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
+ FKey *pFKey;
+ assert( sParse.pNewTable->pSelect==0 );
+ sCtx.pTab = sParse.pNewTable;
+ if( bFKOnly==0 ){
+ renameTokenFind(
+ &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName
+ );
+ if( sCtx.iCol<0 ){
+ renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey);
+ }
+ sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck);
+ for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
+ }
+ }
+
+ for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
+ for(i=0; i<pFKey->nCol; i++){
+ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
+ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
+ }
+ if( 0==sqlite3_stricmp(pFKey->zTo, zTable)
+ && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld)
+ ){
+ renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol);
+ }
+ }
+ }
+ }
+ }else if( sParse.pNewIndex ){
+ sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
+ sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
+ }else{
+ /* A trigger */
+ TriggerStep *pStep;
+ rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb));
+ if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
+
+ for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
+ if( pStep->zTarget ){
+ Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb);
+ if( pTarget==pTab ){
+ if( pStep->pUpsert ){
+ ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet;
+ renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld);
+ }
+ renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld);
+ renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld);
+ }
+ }
+ }
+
+
+ /* Find tokens to edit in UPDATE OF clause */
+ if( sParse.pTriggerTab==pTab ){
+ renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld);
+ }
+
+ /* Find tokens to edit in various expressions and selects */
+ renameWalkTrigger(&sWalker, sParse.pNewTrigger);
+ }
+
+ assert( rc==SQLITE_OK );
+ rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
+
+renameColumnFunc_done:
+ if( rc!=SQLITE_OK ){
+ if( sParse.zErrMsg ){
+ renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
+ }else{
+ sqlite3_result_error_code(context, rc);
+ }
+ }
+
+ renameParseCleanup(&sParse);
+ renameTokenFree(db, sCtx.pList);
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ db->xAuth = xAuth;
+#endif
+ sqlite3BtreeLeaveAll(db);
+}
+
+/*
+** Walker expression callback used by "RENAME TABLE".
+*/
+static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
+ RenameCtx *p = pWalker->u.pRename;
+ if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
+ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+ }
+ return WRC_Continue;
+}
+
+/*
+** Walker select callback used by "RENAME TABLE".
+*/
+static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
+ int i;
+ RenameCtx *p = pWalker->u.pRename;
+ SrcList *pSrc = pSelect->pSrc;
+ for(i=0; i<pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &pSrc->a[i];
+ if( pItem->pTab==p->pTab ){
+ renameTokenFind(pWalker->pParse, p, pItem->zName);
+ }
+ }
+
+ return WRC_Continue;
+}
+
+
+/*
+** This C function implements an SQL user function that is used by SQL code
+** generated by the ALTER TABLE ... RENAME command to modify the definition
+** of any foreign key constraints that use the table being renamed as the
+** parent table. It is passed three arguments:
+**
+** 0: The database containing the table being renamed.
+** 1. type: Type of object ("table", "view" etc.)
+** 2. object: Name of object
+** 3: The complete text of the schema statement being modified,
+** 4: The old name of the table being renamed, and
+** 5: The new name of the table being renamed.
+** 6: True if the schema statement comes from the temp db.
+**
+** It returns the new schema statement. For example:
+**
+** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0)
+** -> 'CREATE TABLE t1(a REFERENCES t3)'
+*/
+static void renameTableFunc(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ const char *zDb = (const char*)sqlite3_value_text(argv[0]);
+ const char *zInput = (const char*)sqlite3_value_text(argv[3]);
+ const char *zOld = (const char*)sqlite3_value_text(argv[4]);
+ const char *zNew = (const char*)sqlite3_value_text(argv[5]);
+ int bTemp = sqlite3_value_int(argv[6]);
+ UNUSED_PARAMETER(NotUsed);
+
+ if( zInput && zOld && zNew ){
+ Parse sParse;
+ int rc;
+ int bQuote = 1;
+ RenameCtx sCtx;
+ Walker sWalker;
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ sqlite3_xauth xAuth = db->xAuth;
+ db->xAuth = 0;
+#endif
+
+ sqlite3BtreeEnterAll(db);
+
+ memset(&sCtx, 0, sizeof(RenameCtx));
+ sCtx.pTab = sqlite3FindTable(db, zOld, zDb);
+ memset(&sWalker, 0, sizeof(Walker));
+ sWalker.pParse = &sParse;
+ sWalker.xExprCallback = renameTableExprCb;
+ sWalker.xSelectCallback = renameTableSelectCb;
+ sWalker.u.pRename = &sCtx;
+
+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
+
+ if( rc==SQLITE_OK ){
+ int isLegacy = (db->flags & SQLITE_LegacyAlter);
+ if( sParse.pNewTable ){
+ Table *pTab = sParse.pNewTable;
+
+ if( pTab->pSelect ){
+ if( isLegacy==0 ){
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = &sParse;
+
+ sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
+ if( sParse.nErr ) rc = sParse.rc;
+ sqlite3WalkSelect(&sWalker, pTab->pSelect);
+ }
+ }else{
+ /* Modify any FK definitions to point to the new table. */
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+ if( db->flags & SQLITE_ForeignKeys ){
+ FKey *pFKey;
+ for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
+ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
+ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
+ }
+ }
+ }
+#endif
+
+ /* If this is the table being altered, fix any table refs in CHECK
+ ** expressions. Also update the name that appears right after the
+ ** "CREATE [VIRTUAL] TABLE" bit. */
+ if( sqlite3_stricmp(zOld, pTab->zName)==0 ){
+ sCtx.pTab = pTab;
+ if( isLegacy==0 ){
+ sqlite3WalkExprList(&sWalker, pTab->pCheck);
+ }
+ renameTokenFind(&sParse, &sCtx, pTab->zName);
+ }
+ }
+ }
+
+ else if( sParse.pNewIndex ){
+ renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName);
+ if( isLegacy==0 ){
+ sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
+ }
+ }
+
+#ifndef SQLITE_OMIT_TRIGGER
+ else{
+ Trigger *pTrigger = sParse.pNewTrigger;
+ TriggerStep *pStep;
+ if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld)
+ && sCtx.pTab->pSchema==pTrigger->pTabSchema
+ ){
+ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
+ }
+
+ if( isLegacy==0 ){
+ rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
+ if( rc==SQLITE_OK ){
+ renameWalkTrigger(&sWalker, pTrigger);
+ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
+ if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
+ renameTokenFind(&sParse, &sCtx, pStep->zTarget);
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
+ }
+ if( rc!=SQLITE_OK ){
+ if( sParse.zErrMsg ){
+ renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
+ }else{
+ sqlite3_result_error_code(context, rc);
+ }
+ }
+
+ renameParseCleanup(&sParse);
+ renameTokenFree(db, sCtx.pList);
+ sqlite3BtreeLeaveAll(db);
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ db->xAuth = xAuth;
+#endif
+ }
+
+ return;
+}
+
+/*
+** An SQL user function that checks that there are no parse or symbol
+** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
+** After an ALTER TABLE .. RENAME operation is performed and the schema
+** reloaded, this function is called on each SQL statement in the schema
+** to ensure that it is still usable.
+**
+** 0: Database name ("main", "temp" etc.).
+** 1: SQL statement.
+** 2: Object type ("view", "table", "trigger" or "index").
+** 3: Object name.
+** 4: True if object is from temp schema.
+**
+** Unless it finds an error, this function normally returns NULL. However, it
+** returns integer value 1 if:
+**
+** * the SQL argument creates a trigger, and
+** * the table that the trigger is attached to is in database zDb.
+*/
+static void renameTableTest(
+ sqlite3_context *context,
+ int NotUsed,
+ sqlite3_value **argv
+){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ char const *zDb = (const char*)sqlite3_value_text(argv[0]);
+ char const *zInput = (const char*)sqlite3_value_text(argv[1]);
+ int bTemp = sqlite3_value_int(argv[4]);
+ int isLegacy = (db->flags & SQLITE_LegacyAlter);
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ sqlite3_xauth xAuth = db->xAuth;
+ db->xAuth = 0;
+#endif
+
+ UNUSED_PARAMETER(NotUsed);
+ if( zDb && zInput ){
+ int rc;
+ Parse sParse;
+ rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
+ if( rc==SQLITE_OK ){
+ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = &sParse;
+ sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
+ if( sParse.nErr ) rc = sParse.rc;
+ }
+
+ else if( sParse.pNewTrigger ){
+ if( isLegacy==0 ){
+ rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
+ }
+ if( rc==SQLITE_OK ){
+ int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
+ int i2 = sqlite3FindDbName(db, zDb);
+ if( i1==i2 ) sqlite3_result_int(context, 1);
+ }
+ }
+ }
+
+ if( rc!=SQLITE_OK ){
+ renameColumnParseError(context, 1, argv[2], argv[3], &sParse);
+ }
+ renameParseCleanup(&sParse);
+ }
+
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ db->xAuth = xAuth;
+#endif
+}
+
+/*
+** Register built-in functions used to help implement ALTER TABLE
+*/
+SQLITE_PRIVATE void sqlite3AlterFunctions(void){
+ static FuncDef aAlterTableFuncs[] = {
+ FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
+ FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
+ FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
+ };
+ sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
+}
#endif /* SQLITE_ALTER_TABLE */
/************** End of alter.c ***********************************************/
@@ -98387,6 +103214,10 @@ static void openStatTable(
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ }else if( db->xPreUpdateCallback ){
+ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
+#endif
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
@@ -98634,6 +103465,7 @@ static const FuncDef statInitFuncdef = {
0, /* pNext */
statInit, /* xSFunc */
0, /* xFinalize */
+ 0, 0, /* xValue, xInverse */
"stat_init", /* zName */
{0}
};
@@ -98950,6 +103782,7 @@ static const FuncDef statPushFuncdef = {
0, /* pNext */
statPush, /* xSFunc */
0, /* xFinalize */
+ 0, 0, /* xValue, xInverse */
"stat_push", /* zName */
{0}
};
@@ -99101,6 +103934,7 @@ static const FuncDef statGetFuncdef = {
0, /* pNext */
statGet, /* xSFunc */
0, /* xFinalize */
+ 0, 0, /* xValue, xInverse */
"stat_get", /* zName */
{0}
};
@@ -99151,6 +103985,9 @@ static void analyzeOneTable(
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
int regPrev = iMem; /* MUST BE LAST (see below) */
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ Table *pStat1 = 0;
+#endif
pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
@@ -99161,7 +103998,7 @@ static void analyzeOneTable(
/* Do not gather statistics on views or virtual tables */
return;
}
- if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
+ if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
/* Do not gather statistics on system tables */
return;
}
@@ -99176,6 +104013,18 @@ static void analyzeOneTable(
}
#endif
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( db->xPreUpdateCallback ){
+ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
+ if( pStat1==0 ) return;
+ pStat1->zName = (char*)&pStat1[1];
+ memcpy(pStat1->zName, "sqlite_stat1", 13);
+ pStat1->nCol = 3;
+ pStat1->iPKey = -1;
+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
+ }
+#endif
+
/* Establish a read-lock on the table at the shared-cache level.
** Open a read-only cursor on the table. Also allocate a cursor number
** to use for scanning indexes (iIdxCur). No index cursor is opened at
@@ -99377,6 +104226,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat3 or stat4 table. */
@@ -99402,10 +104254,7 @@ static void analyzeOneTable(
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
- /* We know that the regSampleRowid row exists because it was read by
- ** the previous loop. Thus the not-found jump of seekOp will never
- ** be taken */
- VdbeCoverageNeverTaken(v);
+ VdbeCoverage(v);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
#else
@@ -99440,6 +104289,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeJumpHere(v, jZeroRows);
}
}
@@ -100043,7 +104895,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
+ if( rc==SQLITE_OK ){
db->lookaside.bDisable++;
rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bDisable--;
@@ -100123,6 +104975,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
**
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
** third argument.
+**
+** If the db->init.reopenMemdb flags is set, then instead of attaching a
+** new database, close the database on db->init.iDb and reopen it as an
+** empty MemDB.
*/
static void attachFunc(
sqlite3_context *context,
@@ -100143,66 +104999,86 @@ static void attachFunc(
sqlite3_vfs *pVfs;
UNUSED_PARAMETER(NotUsed);
-
zFile = (const char *)sqlite3_value_text(argv[0]);
zName = (const char *)sqlite3_value_text(argv[1]);
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
- /* Check for the following errors:
- **
- ** * Too many attached databases,
- ** * Transaction currently open
- ** * Specified database name already being used.
- */
- if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
- zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
- db->aLimit[SQLITE_LIMIT_ATTACHED]
- );
- goto attach_error;
- }
- for(i=0; i<db->nDb; i++){
- const char *z = db->aDb[i].zDbSName;
- assert( z && zName );
- if( sqlite3StrICmp(z, zName)==0 ){
- zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
+#ifdef SQLITE_ENABLE_DESERIALIZE
+# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb)
+#else
+# define REOPEN_AS_MEMDB(db) (0)
+#endif
+
+ if( REOPEN_AS_MEMDB(db) ){
+ /* This is not a real ATTACH. Instead, this routine is being called
+ ** from sqlite3_deserialize() to close database db->init.iDb and
+ ** reopen it as a MemDB */
+ pVfs = sqlite3_vfs_find("memdb");
+ if( pVfs==0 ) return;
+ pNew = &db->aDb[db->init.iDb];
+ if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
+ pNew->pBt = 0;
+ pNew->pSchema = 0;
+ rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ }else{
+ /* This is a real ATTACH
+ **
+ ** Check for the following errors:
+ **
+ ** * Too many attached databases,
+ ** * Transaction currently open
+ ** * Specified database name already being used.
+ */
+ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
+ zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
+ db->aLimit[SQLITE_LIMIT_ATTACHED]
+ );
goto attach_error;
}
+ for(i=0; i<db->nDb; i++){
+ const char *z = db->aDb[i].zDbSName;
+ assert( z && zName );
+ if( sqlite3StrICmp(z, zName)==0 ){
+ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
+ goto attach_error;
+ }
+ }
+
+ /* Allocate the new entry in the db->aDb[] array and initialize the schema
+ ** hash tables.
+ */
+ if( db->aDb==db->aDbStatic ){
+ aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
+ if( aNew==0 ) return;
+ memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+ }else{
+ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+ if( aNew==0 ) return;
+ }
+ db->aDb = aNew;
+ pNew = &db->aDb[db->nDb];
+ memset(pNew, 0, sizeof(*pNew));
+
+ /* Open the database file. If the btree is successfully opened, use
+ ** it to obtain the database schema. At this point the schema may
+ ** or may not be initialized.
+ */
+ flags = db->openFlags;
+ rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
+ return;
+ }
+ assert( pVfs );
+ flags |= SQLITE_OPEN_MAIN_DB;
+ rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
+ sqlite3_free( zPath );
+ db->nDb++;
}
-
- /* Allocate the new entry in the db->aDb[] array and initialize the schema
- ** hash tables.
- */
- if( db->aDb==db->aDbStatic ){
- aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
- if( aNew==0 ) return;
- memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
- }else{
- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
- if( aNew==0 ) return;
- }
- db->aDb = aNew;
- pNew = &db->aDb[db->nDb];
- memset(pNew, 0, sizeof(*pNew));
-
- /* Open the database file. If the btree is successfully opened, use
- ** it to obtain the database schema. At this point the schema may
- ** or may not be initialized.
- */
- flags = db->openFlags;
- rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- assert( pVfs );
- flags |= SQLITE_OPEN_MAIN_DB;
- rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
- sqlite3_free( zPath );
- db->nDb++;
- db->skipBtreeMutex = 0;
+ db->noSharedCache = 0;
if( rc==SQLITE_CONSTRAINT ){
rc = SQLITE_ERROR;
zErrDyn = sqlite3MPrintf(db, "database is already attached");
@@ -100228,7 +105104,7 @@ static void attachFunc(
sqlite3BtreeLeave(pNew->pBt);
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- pNew->zDbSName = sqlite3DbStrDup(db, zName);
+ if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -100268,13 +105144,16 @@ static void attachFunc(
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
- ** remove the entry from the db->aDb[] array. i.e. put everything back the way
- ** we found it.
+ ** remove the entry from the db->aDb[] array. i.e. put everything back the
+ ** way we found it.
*/
if( rc==SQLITE_OK ){
sqlite3BtreeEnterAll(db);
+ db->init.iDb = 0;
+ db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
rc = sqlite3Init(db, &zErrDyn);
sqlite3BtreeLeaveAll(db);
+ assert( zErrDyn==0 || rc!=SQLITE_OK );
}
#ifdef SQLITE_USER_AUTHENTICATION
if( rc==SQLITE_OK ){
@@ -100286,21 +105165,23 @@ static void attachFunc(
}
#endif
if( rc ){
- int iDb = db->nDb - 1;
- assert( iDb>=2 );
- if( db->aDb[iDb].pBt ){
- sqlite3BtreeClose(db->aDb[iDb].pBt);
- db->aDb[iDb].pBt = 0;
- db->aDb[iDb].pSchema = 0;
- }
- sqlite3ResetAllSchemasOfConnection(db);
- db->nDb = iDb;
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- sqlite3OomFault(db);
- sqlite3DbFree(db, zErrDyn);
- zErrDyn = sqlite3MPrintf(db, "out of memory");
- }else if( zErrDyn==0 ){
- zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
+ if( !REOPEN_AS_MEMDB(db) ){
+ int iDb = db->nDb - 1;
+ assert( iDb>=2 );
+ if( db->aDb[iDb].pBt ){
+ sqlite3BtreeClose(db->aDb[iDb].pBt);
+ db->aDb[iDb].pBt = 0;
+ db->aDb[iDb].pSchema = 0;
+ }
+ sqlite3ResetAllSchemasOfConnection(db);
+ db->nDb = iDb;
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ sqlite3OomFault(db);
+ sqlite3DbFree(db, zErrDyn);
+ zErrDyn = sqlite3MPrintf(db, "out of memory");
+ }else if( zErrDyn==0 ){
+ zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
+ }
}
goto attach_error;
}
@@ -100453,6 +105334,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
0, /* pNext */
detachFunc, /* xSFunc */
0, /* xFinalize */
+ 0, 0, /* xValue, xInverse */
"sqlite_detach", /* zName */
{0}
};
@@ -100472,6 +105354,7 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p
0, /* pNext */
attachFunc, /* xSFunc */
0, /* xFinalize */
+ 0, 0, /* xValue, xInverse */
"sqlite_attach", /* zName */
{0}
};
@@ -100542,6 +105425,9 @@ SQLITE_PRIVATE int sqlite3FixSrcList(
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
+ if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){
+ return 1;
+ }
}
return 0;
}
@@ -100572,8 +105458,13 @@ SQLITE_PRIVATE int sqlite3FixSelect(
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
return 1;
}
- if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
- return 1;
+ if( pSelect->pWith ){
+ int i;
+ for(i=0; i<pSelect->pWith->nCte; i++){
+ if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
+ return 1;
+ }
+ }
}
pSelect = pSelect->pPrior;
}
@@ -100636,6 +105527,18 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
if( sqlite3FixExprList(pFix, pStep->pExprList) ){
return 1;
}
+#ifndef SQLITE_OMIT_UPSERT
+ if( pStep->pUpsert ){
+ Upsert *pUp = pStep->pUpsert;
+ if( sqlite3FixExprList(pFix, pUp->pUpsertTarget)
+ || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere)
+ || sqlite3FixExprList(pFix, pUp->pUpsertSet)
+ || sqlite3FixExpr(pFix, pUp->pUpsertWhere)
+ ){
+ return 1;
+ }
+ }
+#endif
pStep = pStep->pNext;
}
return 0;
@@ -100724,7 +105627,7 @@ SQLITE_API int sqlite3_set_authorizer(
sqlite3_mutex_enter(db->mutex);
db->xAuth = (sqlite3_xauth)xAuth;
db->pAuthArg = pArg;
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@@ -100796,6 +105699,7 @@ SQLITE_PRIVATE void sqlite3AuthRead(
int iDb; /* The index of the database the expression refers to */
int iCol; /* Index of column in table */
+ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
if( db->xAuth==0 ) return;
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
if( iDb<0 ){
@@ -100804,7 +105708,6 @@ SQLITE_PRIVATE void sqlite3AuthRead(
return;
}
- assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
if( pExpr->op==TK_TRIGGER ){
pTab = pParse->pTriggerTab;
}else{
@@ -100853,7 +105756,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
/* Don't do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite3_declare_vtab.
*/
- if( db->init.busy || IN_DECLARE_VTAB ){
+ if( db->init.busy || IN_SPECIAL_PARSE ){
return SQLITE_OK;
}
@@ -101145,7 +106048,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
if( v && pParse->nErr==0 && !db->mallocFailed ){
- assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
@@ -101263,24 +106165,27 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
const char *zDbase /* Name of the database. Might be NULL */
){
Table *p;
+ sqlite3 *db = pParse->db;
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+ if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0
+ && SQLITE_OK!=sqlite3ReadSchema(pParse)
+ ){
return 0;
}
- p = sqlite3FindTable(pParse->db, zName, zDbase);
+ p = sqlite3FindTable(db, zName, zDbase);
if( p==0 ){
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
+ if( sqlite3FindDbName(db, zDbase)<1 ){
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
- Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
- pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
+ pMod = sqlite3PragmaVtabRegister(db, zName);
}
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
@@ -101357,7 +106262,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
/*
** Reclaim the memory used by an index
*/
-static void freeIndex(sqlite3 *db, Index *p){
+SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
@@ -101397,7 +106302,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char
p->pNext = pIndex->pNext;
}
}
- freeIndex(db, pIndex);
+ sqlite3FreeIndex(db, pIndex);
}
db->mDbFlags |= DBFLAG_SchemaChange;
}
@@ -101445,6 +106350,7 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
DbSetProperty(db, iDb, DB_ResetWanted);
DbSetProperty(db, 1, DB_ResetWanted);
+ db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
}
if( db->nSchemaLock==0 ){
@@ -101470,7 +106376,7 @@ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
sqlite3SchemaClear(pDb->pSchema);
}
}
- db->mDbFlags &= ~DBFLAG_SchemaChange;
+ db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
sqlite3CollapseDatabaseArray(db);
@@ -101542,7 +106448,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
assert( pOld==pIndex || pOld==0 );
}
- freeIndex(db, pIndex);
+ sqlite3FreeIndex(db, pIndex);
}
/* Delete any foreign keys attached to this table. */
@@ -101700,7 +106606,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
return -1;
}
}else{
- assert( db->init.iDb==0 || db->init.busy
+ assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT
|| (db->mDbFlags & DBFLAG_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
@@ -101795,6 +106701,9 @@ SQLITE_PRIVATE void sqlite3StartTable(
}
if( !OMIT_TEMPDB && isTemp ) iDb = 1;
zName = sqlite3NameFromToken(db, pName);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)zName, pName);
+ }
}
pParse->sNameToken = *pName;
if( zName==0 ) return;
@@ -101830,7 +106739,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
** and types will be used, so there is no need to test for namespace
** collisions.
*/
- if( !IN_DECLARE_VTAB ){
+ if( !IN_SPECIAL_PARSE ){
const char *zDb = db->aDb[iDb].zDbSName;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto begin_table_error;
@@ -101989,6 +106898,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
}
z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
if( z==0 ) return;
+ if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
memcpy(z, pName->z, pName->n);
z[pName->n] = 0;
sqlite3Dequote(z);
@@ -102015,15 +106925,20 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
if( pType->n==0 ){
/* If there is no type specified, columns have the default affinity
- ** 'BLOB'. */
+ ** 'BLOB' with a default size of 4 bytes. */
pCol->affinity = SQLITE_AFF_BLOB;
pCol->szEst = 1;
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( 4>=sqlite3GlobalConfig.szSorterRef ){
+ pCol->colFlags |= COLFLAG_SORTERREF;
+ }
+#endif
}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->affinity = sqlite3AffinityType(zType, pCol);
pCol->colFlags |= COLFLAG_HASTYPE;
}
p->nCol++;
@@ -102038,10 +106953,24 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
*/
SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p;
+ Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
- p->aCol[p->nCol-1].notNull = (u8)onError;
+ pCol = &p->aCol[p->nCol-1];
+ pCol->notNull = (u8)onError;
p->tabFlags |= TF_HasNotNull;
+
+ /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created
+ ** on this column. */
+ if( pCol->colFlags & COLFLAG_UNIQUE ){
+ Index *pIdx;
+ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None );
+ if( pIdx->aiColumn[0]==p->nCol-1 ){
+ pIdx->uniqNotNull = 1;
+ }
+ }
+ }
}
/*
@@ -102069,7 +106998,7 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
const char *zChar = 0;
@@ -102106,27 +107035,32 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
}
}
- /* If pszEst is not NULL, store an estimate of the field size. The
+ /* If pCol is not NULL, store an estimate of the field size. The
** estimate is scaled so that the size of an integer is 1. */
- if( pszEst ){
- *pszEst = 1; /* default size is approx 4 bytes */
+ if( pCol ){
+ int v = 0; /* default size is approx 4 bytes */
if( aff<SQLITE_AFF_NUMERIC ){
if( zChar ){
while( zChar[0] ){
if( sqlite3Isdigit(zChar[0]) ){
- int v = 0;
+ /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
sqlite3GetInt32(zChar, &v);
- v = v/4 + 1;
- if( v>255 ) v = 255;
- *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
break;
}
zChar++;
}
}else{
- *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/
+ v = 16; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/
}
}
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( v>=sqlite3GlobalConfig.szSorterRef ){
+ pCol->colFlags |= COLFLAG_SORTERREF;
+ }
+#endif
+ v = v/4 + 1;
+ if( v>255 ) v = 255;
+ pCol->szEst = v;
}
return aff;
}
@@ -102141,34 +107075,40 @@ 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.
*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
+SQLITE_PRIVATE void sqlite3AddDefaultValue(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The parsed expression of the default value */
+ const char *zStart, /* Start of the default value text */
+ const char *zEnd /* First character past end of defaut value text */
+){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
- ** tokens that point to volatile memory. The 'span' of the expression
- ** is required by pragma table_info.
+ ** tokens that point to volatile memory.
*/
Expr x;
sqlite3ExprDelete(db, pCol->pDflt);
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.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
+ x.pLeft = pExpr;
x.flags = EP_Skip;
pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
sqlite3DbFree(db, x.u.zToken);
}
}
- sqlite3ExprDelete(db, pSpan->pExpr);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprUnmap(pParse, pExpr);
+ }
+ sqlite3ExprDelete(db, pExpr);
}
/*
@@ -102259,6 +107199,9 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
&& sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
&& sortOrder!=SQLITE_SO_DESC
){
+ if( IN_RENAME_OBJECT && pList ){
+ sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
+ }
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
@@ -102399,7 +107342,7 @@ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
Vdbe *v = pParse->pVdbe;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION,
- db->aDb[iDb].pSchema->schema_cookie+1);
+ (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie));
}
/*
@@ -102584,6 +107527,31 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){
return 0;
}
+/* Recompute the colNotIdxed field of the Index.
+**
+** colNotIdxed is a bitmask that has a 0 bit representing each indexed
+** columns that are within the first 63 columns of the table. The
+** high-order bit of colNotIdxed is always 1. All unindexed columns
+** of the table have a 1.
+**
+** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
+** to determine if the index is covering index.
+*/
+static void recomputeColumnsNotIndexed(Index *pIdx){
+ Bitmask m = 0;
+ int j;
+ for(j=pIdx->nColumn-1; j>=0; j--){
+ int x = pIdx->aiColumn[j];
+ if( x>=0 ){
+ testcase( x==BMS-1 );
+ testcase( x==BMS-2 );
+ if( x<BMS-1 ) m |= MASKBIT(x);
+ }
+ }
+ pIdx->colNotIdxed = ~m;
+ assert( (pIdx->colNotIdxed>>63)==1 );
+}
+
/*
** This routine runs at the end of parsing a CREATE TABLE statement that
** has a WITHOUT ROWID clause. The job of this routine is to convert both
@@ -102626,10 +107594,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
}
- /* The remaining transformations only apply to b-tree tables, not to
- ** virtual tables */
- if( IN_DECLARE_VTAB ) return;
-
/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
** into BTREE_BLOBKEY.
*/
@@ -102652,7 +107616,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
assert( pParse->pNewTable==pTab );
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
- if( db->mallocFailed ) return;
+ if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
pTab->iPKey = -1;
}else{
@@ -102732,6 +107696,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}else{
pPk->nColumn = pTab->nCol;
}
+ recomputeColumnsNotIndexed(pPk);
}
/*
@@ -102773,8 +107738,6 @@ SQLITE_PRIVATE void sqlite3EndTable(
p = pParse->pNewTable;
if( p==0 ) return;
- assert( !db->init.busy || !pSelect );
-
/* If the db->init.busy is 1 it means we are reading the SQL off the
** "sqlite_master" or "sqlite_temp_master" table on the disk.
** So do not write to the disk again. Extract the root page number
@@ -102785,6 +107748,10 @@ SQLITE_PRIVATE void sqlite3EndTable(
** table itself. So mark it read-only.
*/
if( db->init.busy ){
+ if( pSelect ){
+ sqlite3ErrorMsg(pParse, "");
+ return;
+ }
p->tnum = db->init.newTnum;
if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
}
@@ -102885,10 +107852,6 @@ SQLITE_PRIVATE void sqlite3EndTable(
pParse->nTab = 2;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
- sqlite3Select(pParse, pSelect, &dest);
- sqlite3VdbeEndCoroutine(v, regYield);
- sqlite3VdbeJumpHere(v, addrTop - 1);
if( pParse->nErr ) return;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
if( pSelTab==0 ) return;
@@ -102898,6 +107861,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(db, pSelTab);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ sqlite3Select(pParse, pSelect, &dest);
+ if( pParse->nErr ) return;
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1);
addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
@@ -103032,7 +108000,12 @@ SQLITE_PRIVATE void sqlite3CreateView(
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
- p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ if( IN_RENAME_OBJECT ){
+ p->pSelect = pSelect;
+ pSelect = 0;
+ }else{
+ p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ }
p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
if( db->mallocFailed ) goto create_view_fail;
@@ -103040,7 +108013,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
** the end.
*/
sEnd = pParse->sLastToken;
- assert( sEnd.z[0]!=0 );
+ assert( sEnd.z[0]!=0 || sEnd.n==0 );
if( sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
@@ -103057,6 +108030,9 @@ SQLITE_PRIVATE void sqlite3CreateView(
create_view_fail:
sqlite3SelectDelete(db, pSelect);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprlistUnmap(pParse, pCNames);
+ }
sqlite3ExprListDelete(db, pCNames);
return;
}
@@ -103074,7 +108050,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
int nErr = 0; /* Number of errors encountered */
int n; /* Temporarily holds the number of cursors assigned */
sqlite3 *db = pParse->db; /* Database connection for malloc errors */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
+#ifndef SQLITE_OMIT_VIRTUALTABLE
int rc;
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -103130,6 +108106,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
assert( pTable->pSelect );
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
+#ifndef SQLITE_OMIT_ALTERTABLE
+ u8 eParseMode = pParse->eParseMode;
+ pParse->eParseMode = PARSE_MODE_NORMAL;
+#endif
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
@@ -103175,10 +108155,18 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDelete(db, pSel);
db->lookaside.bDisable--;
+#ifndef SQLITE_OMIT_ALTERTABLE
+ pParse->eParseMode = eParseMode;
+#endif
} else {
nErr++;
}
pTable->pSchema->schemaFlags |= DB_UnresetViews;
+ if( db->mallocFailed ){
+ sqlite3DeleteColumnNames(db, pTable);
+ pTable->aCol = 0;
+ pTable->nCol = 0;
+ }
#endif /* SQLITE_OMIT_VIEW */
return nErr;
}
@@ -103517,8 +108505,10 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
- sqlite3FkDropTable(pParse, pName, pTab);
+ if( !isView ){
+ sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
+ sqlite3FkDropTable(pParse, pName, pTab);
+ }
sqlite3CodeDropTable(pParse, pTab, iDb, isView);
}
@@ -103593,6 +108583,9 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
pFKey->pNextFrom = p->pFKey;
z = (char*)&pFKey->aCol[nCol];
pFKey->zTo = z;
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)z, pTo);
+ }
memcpy(z, pTo->z, pTo->n);
z[pTo->n] = 0;
sqlite3Dequote(z);
@@ -103615,12 +108608,18 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
pFromCol->a[i].zName);
goto fk_end;
}
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName);
+ }
}
}
if( pToCol ){
for(i=0; i<nCol; i++){
int n = sqlite3Strlen30(pToCol->a[i].zName);
pFKey->aCol[i].zCol = z;
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName);
+ }
memcpy(z, pToCol->a[i].zName, n);
z[n] = 0;
z += n+1;
@@ -103729,6 +108728,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
regRecord = sqlite3GetTempReg(pParse);
+ sqlite3MultiWrite(pParse);
sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
@@ -103742,12 +108742,13 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
if( IsUniqueIndex(pIndex) ){
- int j2 = sqlite3VdbeCurrentAddr(v) + 3;
- sqlite3VdbeGoto(v, j2);
+ int j2 = sqlite3VdbeGoto(v, 1);
addr2 = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeVerifyAbortable(v, OE_Abort);
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
+ sqlite3VdbeJumpHere(v, j2);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
@@ -103910,7 +108911,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
#if SQLITE_USER_AUTHENTICATION
&& sqlite3UserAuthTable(pTab->zName)==0
#endif
- && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
+#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
+ && sqlite3StrICmp(&pTab->zName[7],"master")!=0
+#endif
+ && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0
+ ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
@@ -103947,20 +108952,22 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
- if( !db->init.busy ){
- if( sqlite3FindTable(db, zName, 0)!=0 ){
- sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
- goto exit_create_index;
+ if( !IN_RENAME_OBJECT ){
+ if( !db->init.busy ){
+ if( sqlite3FindTable(db, zName, 0)!=0 ){
+ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
+ goto exit_create_index;
+ }
}
- }
- if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
- if( !ifNotExist ){
- sqlite3ErrorMsg(pParse, "index %s already exists", zName);
- }else{
- assert( !db->init.busy );
- sqlite3CodeVerifySchema(pParse, iDb);
+ if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
+ if( !ifNotExist ){
+ sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+ }else{
+ assert( !db->init.busy );
+ sqlite3CodeVerifySchema(pParse, iDb);
+ }
+ goto exit_create_index;
}
- goto exit_create_index;
}
}else{
int n;
@@ -103976,13 +108983,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** The following statement converts "sqlite3_autoindex..." into
** "sqlite3_butoindex..." in order to make the names distinct.
** The "vtab_err.test" test demonstrates the need of this statement. */
- if( IN_DECLARE_VTAB ) zName[7]++;
+ if( IN_SPECIAL_PARSE ) zName[7]++;
}
/* Check for authorization to create an index.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
- {
+ if( !IN_RENAME_OBJECT ){
const char *zDb = pDb->zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
goto exit_create_index;
@@ -104001,7 +109008,9 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
if( pList==0 ){
Token prevCol;
- sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
+ Column *pCol = &pTab->aCol[pTab->nCol-1];
+ pCol->colFlags |= COLFLAG_UNIQUE;
+ sqlite3TokenInit(&prevCol, pCol->zName);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
@@ -104067,7 +109076,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** TODO: Issue a warning if the table primary key is used as part of the
** index key.
*/
- for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
+ pListItem = pList->a;
+ if( IN_RENAME_OBJECT ){
+ pIndex->aColExpr = pList;
+ pList = 0;
+ }
+ for(i=0; i<pIndex->nKeyCol; i++, pListItem++){
Expr *pCExpr; /* The i-th index expression */
int requestedSortOrder; /* ASC or DESC on the i-th expression */
const char *zColl; /* Collation sequence name */
@@ -104083,12 +109097,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
goto exit_create_index;
}
if( pIndex->aColExpr==0 ){
- ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
- pIndex->aColExpr = pCopy;
- if( !db->mallocFailed ){
- assert( pCopy!=0 );
- pListItem = &pCopy->a[i];
- }
+ pIndex->aColExpr = pList;
+ pList = 0;
}
j = XN_EXPR;
pIndex->aiColumn[i] = XN_EXPR;
@@ -104154,6 +109164,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** it as a covering index */
assert( HasRowid(pTab)
|| pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
+ recomputeColumnsNotIndexed(pIndex);
if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
pIndex->isCovering = 1;
for(j=0; j<pTab->nCol; j++){
@@ -104226,98 +109237,101 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
}
- /* Link the new Index structure to its table and to the other
- ** in-memory database structures.
- */
- assert( pParse->nErr==0 );
- if( db->init.busy ){
- Index *p;
- assert( !IN_DECLARE_VTAB );
- assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
- p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
- pIndex->zName, pIndex);
- if( p ){
- assert( p==pIndex ); /* Malloc must have failed */
- sqlite3OomFault(db);
- goto exit_create_index;
- }
- db->mDbFlags |= DBFLAG_SchemaChange;
- if( pTblName!=0 ){
- pIndex->tnum = db->init.newTnum;
- }
- }
-
- /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
- ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
- ** emit code to allocate the index rootpage on disk and make an entry for
- ** the index in the sqlite_master table and populate the index with
- ** content. But, do not do this if we are simply reading the sqlite_master
- ** table to parse the schema, or if this index is the PRIMARY KEY index
- ** of a WITHOUT ROWID table.
- **
- ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
- ** or UNIQUE index in a CREATE TABLE statement. Since the table
- ** has just been created, it contains no data and the index initialization
- ** step can be skipped.
- */
- else if( HasRowid(pTab) || pTblName!=0 ){
- Vdbe *v;
- char *zStmt;
- int iMem = ++pParse->nMem;
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto exit_create_index;
-
- sqlite3BeginWriteOperation(pParse, 1, iDb);
+ if( !IN_RENAME_OBJECT ){
- /* Create the rootpage for the index using CreateIndex. But before
- ** doing so, code a Noop instruction and store its address in
- ** Index.tnum. This is required in case this index is actually a
- ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In
- ** that case the convertToWithoutRowidTable() routine will replace
- ** the Noop with a Goto to jump over the VDBE code generated below. */
- pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
- sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
-
- /* Gather the complete text of the CREATE INDEX statement into
- ** the zStmt variable
+ /* Link the new Index structure to its table and to the other
+ ** in-memory database structures.
*/
- if( pStart ){
- int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
- if( pName->z[n-1]==';' ) n--;
- /* A named index with an explicit CREATE INDEX statement */
- zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
- onError==OE_None ? "" : " UNIQUE", n, pName->z);
- }else{
- /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
- /* zStmt = sqlite3MPrintf(""); */
- zStmt = 0;
+ assert( pParse->nErr==0 );
+ if( db->init.busy ){
+ Index *p;
+ assert( !IN_SPECIAL_PARSE );
+ assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+ p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
+ pIndex->zName, pIndex);
+ if( p ){
+ assert( p==pIndex ); /* Malloc must have failed */
+ sqlite3OomFault(db);
+ goto exit_create_index;
+ }
+ db->mDbFlags |= DBFLAG_SchemaChange;
+ if( pTblName!=0 ){
+ pIndex->tnum = db->init.newTnum;
+ }
}
- /* Add an entry in sqlite_master for this index
+ /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+ ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+ ** emit code to allocate the index rootpage on disk and make an entry for
+ ** the index in the sqlite_master table and populate the index with
+ ** content. But, do not do this if we are simply reading the sqlite_master
+ ** table to parse the schema, or if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table.
+ **
+ ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+ ** or UNIQUE index in a CREATE TABLE statement. Since the table
+ ** has just been created, it contains no data and the index initialization
+ ** step can be skipped.
*/
- sqlite3NestedParse(pParse,
- "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
- db->aDb[iDb].zDbSName, MASTER_NAME,
- pIndex->zName,
- pTab->zName,
- iMem,
- zStmt
- );
- sqlite3DbFree(db, zStmt);
+ else if( HasRowid(pTab) || pTblName!=0 ){
+ Vdbe *v;
+ char *zStmt;
+ int iMem = ++pParse->nMem;
+
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto exit_create_index;
+
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
+
+ /* Create the rootpage for the index using CreateIndex. But before
+ ** doing so, code a Noop instruction and store its address in
+ ** Index.tnum. This is required in case this index is actually a
+ ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In
+ ** that case the convertToWithoutRowidTable() routine will replace
+ ** the Noop with a Goto to jump over the VDBE code generated below. */
+ pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
+
+ /* Gather the complete text of the CREATE INDEX statement into
+ ** the zStmt variable
+ */
+ if( pStart ){
+ int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+ if( pName->z[n-1]==';' ) n--;
+ /* A named index with an explicit CREATE INDEX statement */
+ zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
+ onError==OE_None ? "" : " UNIQUE", n, pName->z);
+ }else{
+ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
+ /* zStmt = sqlite3MPrintf(""); */
+ zStmt = 0;
+ }
- /* Fill the index with data and reparse the schema. Code an OP_Expire
- ** to invalidate all pre-compiled statements.
- */
- if( pTblName ){
- sqlite3RefillIndex(pParse, pIndex, iMem);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
- sqlite3VdbeAddOp0(v, OP_Expire);
- }
+ /* Add an entry in sqlite_master for this index
+ */
+ sqlite3NestedParse(pParse,
+ "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
+ db->aDb[iDb].zDbSName, MASTER_NAME,
+ pIndex->zName,
+ pTab->zName,
+ iMem,
+ zStmt
+ );
+ sqlite3DbFree(db, zStmt);
+
+ /* Fill the index with data and reparse the schema. Code an OP_Expire
+ ** to invalidate all pre-compiled statements.
+ */
+ if( pTblName ){
+ sqlite3RefillIndex(pParse, pIndex, iMem);
+ sqlite3ChangeCookie(pParse, iDb);
+ sqlite3VdbeAddParseSchemaOp(v, iDb,
+ sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
+ sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
+ }
- sqlite3VdbeJumpHere(v, pIndex->tnum);
+ sqlite3VdbeJumpHere(v, pIndex->tnum);
+ }
}
/* When adding an index to the list of indices for a table, make
@@ -104341,10 +109355,15 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
pIndex = 0;
}
+ else if( IN_RENAME_OBJECT ){
+ assert( pParse->pNewIndex==0 );
+ pParse->pNewIndex = pIndex;
+ pIndex = 0;
+ }
/* Clean up before exiting */
exit_create_index:
- if( pIndex ) freeIndex(db, pIndex);
+ if( pIndex ) sqlite3FreeIndex(db, pIndex);
sqlite3ExprDelete(db, pPIWhere);
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
@@ -104513,7 +109532,8 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate(
**
** A new IdList is returned, or NULL if malloc() fails.
*/
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
+SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){
+ sqlite3 *db = pParse->db;
int i;
if( pList==0 ){
pList = sqlite3DbMallocZero(db, sizeof(IdList) );
@@ -104531,6 +109551,9 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pT
return 0;
}
pList->a[i].zName = sqlite3NameFromToken(db, pToken);
+ if( IN_RENAME_OBJECT && pList->a[i].zName ){
+ sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
+ }
return pList;
}
@@ -104772,10 +109795,17 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
goto append_from_error;
}
p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || NEVER(p->nSrc==0) ){
+ if( p==0 ){
goto append_from_error;
}
+ assert( p->nSrc>0 );
pItem = &p->a[p->nSrc-1];
+ assert( (pTable==0)==(pDatabase==0) );
+ assert( pItem->zName==0 || pDatabase!=0 );
+ if( IN_RENAME_OBJECT && pItem->zName ){
+ Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable;
+ sqlite3RenameTokenMap(pParse, pItem->zName, pToken);
+ }
assert( pAlias!=0 );
if( pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
@@ -105086,16 +110116,16 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
if( pIdx->aColExpr ){
- sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
+ sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
}else{
for(j=0; j<pIdx->nKeyCol; j++){
char *zCol;
assert( pIdx->aiColumn[j]>=0 );
zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
- sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
- sqlite3StrAccumAppend(&errMsg, ".", 1);
- sqlite3StrAccumAppendAll(&errMsg, zCol);
+ if( j ) sqlite3_str_append(&errMsg, ", ", 2);
+ sqlite3_str_appendall(&errMsg, pTab->zName);
+ sqlite3_str_append(&errMsg, ".", 1);
+ sqlite3_str_appendall(&errMsg, zCol);
}
}
zErr = sqlite3StrAccumFinish(&errMsg);
@@ -105283,6 +110313,18 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
if( pParse->nErr ){
+ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
+ if( pIdx->bNoQuery==0 ){
+ /* Deactivate the index because it contains an unknown collating
+ ** sequence. The only way to reactive the index is to reload the
+ ** schema. Adding the missing collating sequence later does not
+ ** reactive the index. The application had the chance to register
+ ** the missing index using the collation-needed callback. For
+ ** simplicity, SQLite will not give the application a second chance.
+ */
+ pIdx->bNoQuery = 1;
+ pParse->rc = SQLITE_ERROR_RETRY;
+ }
sqlite3KeyInfoUnref(pKey);
pKey = 0;
}
@@ -105468,6 +110510,7 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+ pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
}
return p;
}
@@ -105768,10 +110811,12 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
FuncDef *pOther;
+ u8 *z;
pBest->zName = (const char*)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->funcFlags = enc;
memcpy((char*)&pBest[1], zName, nName+1);
+ for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z];
pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
if( pOther==pBest ){
sqlite3DbFree(db, pBest);
@@ -105941,6 +110986,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
Parse *pParse, /* Parsing context */
Table *pView, /* View definition */
Expr *pWhere, /* Optional WHERE clause to be added */
+ ExprList *pOrderBy, /* Optional ORDER BY clause */
+ Expr *pLimit, /* Optional LIMIT clause */
int iCur /* Cursor number for ephemeral table */
){
SelectDest dest;
@@ -105957,8 +111004,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
- pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
- SF_IncludeHidden, 0, 0);
+ pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
+ SF_IncludeHidden, pLimit);
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
sqlite3SelectDelete(db, pSel);
@@ -105980,29 +111027,29 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
Expr *pWhere, /* The WHERE clause. May be null */
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 */
const char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
- Expr *pWhereRowid = NULL; /* WHERE rowid .. */
+ sqlite3 *db = pParse->db;
+ Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
- Expr *pSelectRowid = NULL; /* SELECT rowid ... */
ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
Select *pSelect = NULL; /* Complete SELECT tree */
+ Table *pTab;
/* Check that there isn't an ORDER BY without a LIMIT clause.
*/
- if( pOrderBy && (pLimit == 0) ) {
+ if( pOrderBy && pLimit==0 ) {
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
- goto limit_where_cleanup;
+ sqlite3ExprDelete(pParse->db, pWhere);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ return 0;
}
/* We only need to generate a select expression if there
** is a limit/offset term to enforce.
*/
if( pLimit == 0 ) {
- /* if pLimit is null, pOffset will always be null as well. */
- assert( pOffset == 0 );
return pWhere;
}
@@ -106015,36 +111062,47 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
- if( pSelectRowid == 0 ) goto limit_where_cleanup;
- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
- if( pEList == 0 ) goto limit_where_cleanup;
+ pTab = pSrc->a[0].pTab;
+ if( HasRowid(pTab) ){
+ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ pEList = sqlite3ExprListAppend(
+ pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
+ );
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ if( pPk->nKeyCol==1 ){
+ const char *zName = pTab->aCol[pPk->aiColumn[0]].zName;
+ pLhs = sqlite3Expr(db, TK_ID, zName);
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));
+ }else{
+ int i;
+ for(i=0; i<pPk->nKeyCol; i++){
+ Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName);
+ pEList = sqlite3ExprListAppend(pParse, pEList, p);
+ }
+ pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( pLhs ){
+ pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);
+ }
+ }
+ }
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
+ pSrc->a[0].pTab = 0;
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
- if( pSelectSrc == 0 ) {
- sqlite3ExprListDelete(pParse->db, pEList);
- goto limit_where_cleanup;
- }
+ pSrc->a[0].pTab = pTab;
+ pSrc->a[0].pIBIndex = 0;
/* generate the SELECT expression tree. */
- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
- pOrderBy,0,pLimit,pOffset);
- if( pSelect == 0 ) return 0;
+ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0,
+ pOrderBy,0,pLimit
+ );
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
- pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
+ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
return pInClause;
-
-limit_where_cleanup:
- sqlite3ExprDelete(pParse->db, pWhere);
- sqlite3ExprListDelete(pParse->db, pOrderBy);
- sqlite3ExprDelete(pParse->db, pLimit);
- sqlite3ExprDelete(pParse->db, pOffset);
- return 0;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
/* && !defined(SQLITE_OMIT_SUBQUERY) */
@@ -106059,7 +111117,9 @@ limit_where_cleanup:
SQLITE_PRIVATE void sqlite3DeleteFrom(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* The table from which we should delete things */
- Expr *pWhere /* The WHERE clause. May be null */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ Expr *pLimit /* LIMIT clause. May be null */
){
Vdbe *v; /* The virtual database engine */
Table *pTab; /* The table from which records will be deleted */
@@ -106074,7 +111134,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
AuthContext sContext; /* Authorization context */
NameContext sNC; /* Name context to resolve expressions in */
int iDb; /* Database number */
- int memCnt = -1; /* Memory cell used for change counting */
+ int memCnt = 0; /* Memory cell used for change counting */
int rcauth; /* Value returned by authorization callback */
int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
@@ -106104,6 +111164,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
assert( pTabList->nSrc==1 );
+
/* Locate the table which we want to delete. This table has to be
** put in an SrcList structure because some of the subroutines we
** will be calling are designed to work with multiple tables and expect
@@ -106118,16 +111179,31 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
isView = pTab->pSelect!=0;
- bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#else
# define pTrigger 0
# define isView 0
#endif
+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ if( !isView ){
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#else
+ if( pOrderBy || pLimit ){
+ sqlite3ErrorMsg(pParse, "%s on DELETE not supported", pOrderBy?"ORDER BY":"LIMIT");
+ goto delete_from_cleanup;
+ }
+#endif
+
/* If pTab is really a view, make sure it has been initialized.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -106168,15 +111244,19 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
goto delete_from_cleanup;
}
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1, iDb);
+ sqlite3BeginWriteOperation(pParse, bComplex, iDb);
/* If we are trying to delete from a view, realize that view into
** an ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ sqlite3MaterializeView(pParse, pTab,
+ pWhere, pOrderBy, pLimit, iTabCur
+ );
iDataCur = iIdxCur = iTabCur;
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -106192,7 +111272,10 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* Initialize the counter of the number of rows deleted, if
** we are counting rows.
*/
- if( db->flags & SQLITE_CountRows ){
+ if( (db->flags & SQLITE_CountRows)!=0
+ && !pParse->nested
+ && !pParse->pTriggerTab
+ ){
memCnt = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
}
@@ -106220,7 +111303,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
assert( !isView );
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
if( HasRowid(pTab) ){
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1,
pTab->zName, P4_STATIC);
}
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -106265,9 +111348,10 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
+ if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
/* Keep track of the number of rows to be deleted */
- if( db->flags & SQLITE_CountRows ){
+ if( memCnt ){
sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
}
@@ -106280,9 +111364,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
iKey = iPk;
}else{
- iKey = pParse->nMem + 1;
- iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
- if( iKey>pParse->nMem ) pParse->nMem = iKey;
+ iKey = ++pParse->nMem;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);
}
if( eOnePass!=ONEPASS_OFF ){
@@ -106370,13 +111453,16 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( IsVirtual(pTab) ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
- sqlite3VdbeChangeP5(v, OE_Abort);
assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
sqlite3MayAbort(pParse);
- if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
- pParse->isMultiWrite = 0;
+ if( eOnePass==ONEPASS_SINGLE ){
+ sqlite3VdbeAddOp1(v, OP_Close, iTabCur);
+ if( sqlite3IsToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
}
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
+ sqlite3VdbeChangeP5(v, OE_Abort);
}else
#endif
{
@@ -106410,7 +111496,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
** generating code because of a call to sqlite3NestedParse(), do not
** invoke the callback function.
*/
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+ if( memCnt ){
sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
@@ -106420,6 +111506,8 @@ delete_from_cleanup:
sqlite3AuthContextPop(&sContext);
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprDelete(db, pWhere);
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
sqlite3DbFree(db, aToOpen);
return;
}
@@ -106577,7 +111665,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
u8 p5 = 0;
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
- if( pParse->nested==0 ){
+ if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
}
if( eMode!=ONEPASS_OFF ){
@@ -106708,7 +111796,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
if( pIdx->pPartIdxWhere ){
*piPartIdxLabel = sqlite3VdbeMakeLabel(v);
pParse->iSelfTab = iDataCur + 1;
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
pParse->iSelfTab = 0;
@@ -106755,7 +111842,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
if( iLabel ){
sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
- sqlite3ExprCachePop(pParse);
}
}
@@ -106798,6 +111884,8 @@ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
** iteration of the aggregate loop.
*/
static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
+ assert( context->isError<=0 );
+ context->isError = -1;
context->skipFlag = 1;
}
@@ -106864,8 +111952,6 @@ static void lengthFunc(
int argc,
sqlite3_value **argv
){
- int len;
-
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
@@ -106877,13 +111963,17 @@ static void lengthFunc(
}
case SQLITE_TEXT: {
const unsigned char *z = sqlite3_value_text(argv[0]);
+ const unsigned char *z0;
+ unsigned char c;
if( z==0 ) return;
- len = 0;
- while( *z ){
- len++;
- SQLITE_SKIP_UTF8(z);
+ z0 = z;
+ while( (c = *z)!=0 ){
+ z++;
+ if( c>=0xc0 ){
+ while( (*z & 0xc0)==0x80 ){ z++; z0++; }
+ }
}
- sqlite3_result_int(context, len);
+ sqlite3_result_int(context, (int)(z-z0));
break;
}
default: {
@@ -107010,7 +112100,7 @@ static void printfFunc(
x.apArg = argv+1;
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
str.printfFlags = SQLITE_PRINTF_SQLFUNC;
- sqlite3XPrintf(&str, zFormat, &x);
+ sqlite3_str_appendf(&str, zFormat, &x);
n = str.nChar;
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
SQLITE_DYNAMIC);
@@ -107461,16 +112551,20 @@ static int patternCompare(
** c or cx.
*/
if( c<=0x80 ){
- u32 cx;
+ char zStop[3];
int bMatch;
if( noCase ){
- cx = sqlite3Toupper(c);
- c = sqlite3Tolower(c);
+ zStop[0] = sqlite3Toupper(c);
+ zStop[1] = sqlite3Tolower(c);
+ zStop[2] = 0;
}else{
- cx = c;
+ zStop[0] = c;
+ zStop[1] = 0;
}
- while( (c2 = *(zString++))!=0 ){
- if( c2!=c && c2!=cx ) continue;
+ while(1){
+ zString += strcspn((const char*)zString, zStop);
+ if( zString[0]==0 ) break;
+ zString++;
bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
@@ -107954,6 +113048,8 @@ static void replaceFunc(
i64 nOut; /* Maximum size of zOut */
int loopLimit; /* Last zStr[] that might match zPattern[] */
int i, j; /* Loop counters */
+ unsigned cntExpand; /* Number zOut expansions */
+ sqlite3 *db = sqlite3_context_db_handle(context);
assert( argc==3 );
UNUSED_PARAMETER(argc);
@@ -107985,33 +113081,40 @@ static void replaceFunc(
return;
}
loopLimit = nStr - nPattern;
+ cntExpand = 0;
for(i=j=0; i<=loopLimit; i++){
if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
zOut[j++] = zStr[i];
}else{
- u8 *zOld;
- sqlite3 *db = sqlite3_context_db_handle(context);
- nOut += nRep - nPattern;
- testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- sqlite3_free(zOut);
- return;
- }
- zOld = zOut;
- zOut = sqlite3Realloc(zOut, (int)nOut);
- if( zOut==0 ){
- sqlite3_result_error_nomem(context);
- sqlite3_free(zOld);
- return;
+ if( nRep>nPattern ){
+ nOut += nRep - nPattern;
+ testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
+ testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
+ if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ sqlite3_result_error_toobig(context);
+ sqlite3_free(zOut);
+ return;
+ }
+ cntExpand++;
+ if( (cntExpand&(cntExpand-1))==0 ){
+ /* Grow the size of the output buffer only on substitutions
+ ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
+ u8 *zOld;
+ zOld = zOut;
+ zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1));
+ if( zOut==0 ){
+ sqlite3_result_error_nomem(context);
+ sqlite3_free(zOld);
+ return;
+ }
+ }
}
memcpy(&zOut[j], zRep, nRep);
j += nRep;
i += nPattern-1;
}
}
- assert( j+nStr-i+1==nOut );
+ assert( j+nStr-i+1<=nOut );
memcpy(&zOut[j], &zStr[i], nStr-i);
j += nStr - i;
assert( j<=nOut );
@@ -108251,7 +113354,7 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
i64 v = sqlite3_value_int64(argv[0]);
p->rSum += v;
if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
- p->overflow = 1;
+ p->approx = p->overflow = 1;
}
}else{
p->rSum += sqlite3_value_double(argv[0]);
@@ -108259,6 +113362,32 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
}
}
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
+ SumCtx *p;
+ int type;
+ assert( argc==1 );
+ UNUSED_PARAMETER(argc);
+ p = sqlite3_aggregate_context(context, sizeof(*p));
+ type = sqlite3_value_numeric_type(argv[0]);
+ /* p is always non-NULL because sumStep() will have been called first
+ ** to initialize it */
+ if( ALWAYS(p) && type!=SQLITE_NULL ){
+ assert( p->cnt>0 );
+ p->cnt--;
+ assert( type==SQLITE_INTEGER || p->approx );
+ if( type==SQLITE_INTEGER && p->approx==0 ){
+ i64 v = sqlite3_value_int64(argv[0]);
+ p->rSum -= v;
+ p->iSum -= v;
+ }else{
+ p->rSum -= sqlite3_value_double(argv[0]);
+ }
+ }
+}
+#else
+# define sumInverse 0
+#endif /* SQLITE_OMIT_WINDOWFUNC */
static void sumFinalize(sqlite3_context *context){
SumCtx *p;
p = sqlite3_aggregate_context(context, 0);
@@ -108293,6 +113422,9 @@ static void totalFinalize(sqlite3_context *context){
typedef struct CountCtx CountCtx;
struct CountCtx {
i64 n;
+#ifdef SQLITE_DEBUG
+ int bInverse; /* True if xInverse() ever called */
+#endif
};
/*
@@ -108310,7 +113442,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
** sure it still operates correctly, verify that its count agrees with our
** internal count when using count(*) and when the total count can be
** expressed as a 32-bit integer. */
- assert( argc==1 || p==0 || p->n>0x7fffffff
+ assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse
|| p->n==sqlite3_aggregate_count(context) );
#endif
}
@@ -108319,6 +113451,21 @@ static void countFinalize(sqlite3_context *context){
p = sqlite3_aggregate_context(context, 0);
sqlite3_result_int64(context, p ? p->n : 0);
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){
+ CountCtx *p;
+ p = sqlite3_aggregate_context(ctx, sizeof(*p));
+ /* p is always non-NULL since countStep() will have been called first */
+ if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){
+ p->n--;
+#ifdef SQLITE_DEBUG
+ p->bInverse = 1;
+#endif
+ }
+}
+#else
+# define countInverse 0
+#endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** Routines to implement min() and max() aggregate functions.
@@ -108335,7 +113482,7 @@ static void minmaxStep(
pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
if( !pBest ) return;
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ if( sqlite3_value_type(pArg)==SQLITE_NULL ){
if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
}else if( pBest->flags ){
int max;
@@ -108361,16 +113508,26 @@ static void minmaxStep(
sqlite3VdbeMemCopy(pBest, pArg);
}
}
-static void minMaxFinalize(sqlite3_context *context){
+static void minMaxValueFinalize(sqlite3_context *context, int bValue){
sqlite3_value *pRes;
pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
if( pRes ){
if( pRes->flags ){
sqlite3_result_value(context, pRes);
}
- sqlite3VdbeMemRelease(pRes);
+ if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
}
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+static void minMaxValue(sqlite3_context *context){
+ minMaxValueFinalize(context, 1);
+}
+#else
+# define minMaxValue 0
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+static void minMaxFinalize(sqlite3_context *context){
+ minMaxValueFinalize(context, 0);
+}
/*
** group_concat(EXPR, ?SEPARATOR?)
@@ -108400,20 +113557,52 @@ static void groupConcatStep(
zSep = ",";
nSep = 1;
}
- if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
+ if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
}
zVal = (char*)sqlite3_value_text(argv[0]);
nVal = sqlite3_value_bytes(argv[0]);
- if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
+ if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
+ }
+}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+static void groupConcatInverse(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int n;
+ StrAccum *pAccum;
+ assert( argc==1 || argc==2 );
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+ pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
+ /* pAccum is always non-NULL since groupConcatStep() will have always
+ ** run frist to initialize it */
+ if( ALWAYS(pAccum) ){
+ n = sqlite3_value_bytes(argv[0]);
+ if( argc==2 ){
+ n += sqlite3_value_bytes(argv[1]);
+ }else{
+ n++;
+ }
+ if( n>=(int)pAccum->nChar ){
+ pAccum->nChar = 0;
+ }else{
+ pAccum->nChar -= n;
+ memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
+ }
+ if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
}
}
+#else
+# define groupConcatInverse 0
+#endif /* SQLITE_OMIT_WINDOWFUNC */
static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum;
pAccum = sqlite3_aggregate_context(context, 0);
if( pAccum ){
- if( pAccum->accError==STRACCUM_TOOBIG ){
+ if( pAccum->accError==SQLITE_TOOBIG ){
sqlite3_result_error_toobig(context);
- }else if( pAccum->accError==STRACCUM_NOMEM ){
+ }else if( pAccum->accError==SQLITE_NOMEM ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
@@ -108421,6 +113610,24 @@ static void groupConcatFinalize(sqlite3_context *context){
}
}
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+static void groupConcatValue(sqlite3_context *context){
+ sqlite3_str *pAccum;
+ pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
+ if( pAccum ){
+ if( pAccum->accError==SQLITE_TOOBIG ){
+ sqlite3_result_error_toobig(context);
+ }else if( pAccum->accError==SQLITE_NOMEM ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ const char *zText = sqlite3_str_value(pAccum);
+ sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
+ }
+ }
+}
+#else
+# define groupConcatValue 0
+#endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** This routine does per-connection function registration. Most
@@ -108458,10 +113665,10 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
}
- sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
- sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
+ sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
+ sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
+ (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
setLikeOptFlag(db, "like",
caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
@@ -108558,6 +113765,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
#ifdef SQLITE_DEBUG
FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY),
#endif
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
+ SQLITE_FUNC_TYPEOF),
+#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -108566,11 +113777,11 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -1, 0, 1, minmaxFunc ),
FUNCTION(min, 0, 0, 1, 0 ),
- AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize,
+ WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX ),
FUNCTION(max, -1, 1, 1, minmaxFunc ),
FUNCTION(max, 0, 1, 1, 0 ),
- AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize,
+ WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX ),
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
@@ -108601,14 +113812,17 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
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 ),
- AGGREGATE2(count, 0, 0, 0, countStep, countFinalize,
- SQLITE_FUNC_COUNT ),
- AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
- AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
- AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
+ WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
+ WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0),
+ WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0),
+ WAGGREGATE(count, 0,0,0, countStep,
+ countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ),
+ WAGGREGATE(count, 1,0,0, countStep,
+ countFinalize, countFinalize, countInverse, 0 ),
+ WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep,
+ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
+ WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep,
+ groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#ifdef SQLITE_CASE_SENSITIVE_LIKE
@@ -108628,6 +113842,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
+ sqlite3WindowFunctions();
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
sqlite3AnalyzeFunctions();
#endif
@@ -108986,6 +114201,12 @@ static void fkLookupParent(
int iCur = pParse->nTab - 1; /* Cursor number to use */
int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */
+ sqlite3VdbeVerifyAbortable(v,
+ (!pFKey->isDeferred
+ && !(pParse->db->flags & SQLITE_DeferFKs)
+ && !pParse->pToplevel
+ && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore);
+
/* If nIncr is less than zero, then check at runtime if there are any
** outstanding constraints to resolve. If there are not, there is no need
** to check if deleting this row resolves any outstanding violations.
@@ -109359,11 +114580,12 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){
*/
SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
sqlite3 *db = pParse->db;
- if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
+ if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){
int iSkip = 0;
Vdbe *v = sqlite3GetVdbe(pParse);
assert( v ); /* VDBE has already been allocated */
+ assert( pTab->pSelect==0 ); /* Not a view */
if( sqlite3FkReferences(pTab)==0 ){
/* Search for a deferred foreign key constraint for which this table
** is the child table. If one cannot be found, return without
@@ -109380,7 +114602,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
pParse->disableTriggers = 1;
- sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
+ sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
pParse->disableTriggers = 0;
/* If the DELETE has generated immediate foreign key constraint
@@ -109393,6 +114615,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
** constraints are violated.
*/
if( (db->flags & SQLITE_DeferFKs)==0 ){
+ sqlite3VdbeVerifyAbortable(v, OE_Abort);
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
@@ -109938,7 +115161,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprListAppend(pParse, 0, pRaise),
sqlite3SrcListAppend(db, 0, &tFrom, 0),
pWhere,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0
);
pWhere = 0;
}
@@ -110289,11 +115512,12 @@ static int readsTable(Parse *p, int iDb, Table *pTab){
** first use of table pTab. On 2nd and subsequent uses, the original
** AutoincInfo structure is used.
**
-** Three memory locations are allocated:
+** Four consecutive registers are allocated:
**
-** (1) Register to hold the name of the pTab table.
-** (2) Register to hold the maximum ROWID of pTab.
-** (3) Register to hold the rowid in sqlite_sequence of pTab
+** (1) The name of the pTab table.
+** (2) The maximum ROWID of pTab.
+** (3) The rowid in sqlite_sequence of pTab
+** (4) The original value of the max ROWID in pTab, or NULL if none
**
** The 2nd register is the one that is returned. That is all the
** insert routine needs to know about.
@@ -110304,11 +115528,26 @@ static int autoIncBegin(
Table *pTab /* The table we are writing to */
){
int memId = 0; /* Register holding maximum rowid */
+ assert( pParse->db->aDb[iDb].pSchema!=0 );
if( (pTab->tabFlags & TF_Autoincrement)!=0
&& (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
+ Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
+
+ /* Verify that the sqlite_sequence table exists and is an ordinary
+ ** rowid table with exactly two columns.
+ ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */
+ if( pSeqTab==0
+ || !HasRowid(pSeqTab)
+ || IsVirtual(pSeqTab)
+ || pSeqTab->nCol!=2
+ ){
+ pParse->nErr++;
+ pParse->rc = SQLITE_CORRUPT_SEQUENCE;
+ return 0;
+ }
pInfo = pToplevel->pAinc;
while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
@@ -110321,7 +115560,7 @@ static int autoIncBegin(
pInfo->iDb = iDb;
pToplevel->nMem++; /* Register to hold name of table */
pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */
- pToplevel->nMem++; /* Rowid in sqlite_sequence */
+ pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */
}
memId = pInfo->regCtr;
}
@@ -110349,15 +115588,17 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList autoInc[] = {
/* 0 */ {OP_Null, 0, 0, 0},
- /* 1 */ {OP_Rewind, 0, 9, 0},
+ /* 1 */ {OP_Rewind, 0, 10, 0},
/* 2 */ {OP_Column, 0, 0, 0},
- /* 3 */ {OP_Ne, 0, 7, 0},
+ /* 3 */ {OP_Ne, 0, 9, 0},
/* 4 */ {OP_Rowid, 0, 0, 0},
/* 5 */ {OP_Column, 0, 1, 0},
- /* 6 */ {OP_Goto, 0, 9, 0},
- /* 7 */ {OP_Next, 0, 2, 0},
- /* 8 */ {OP_Integer, 0, 0, 0},
- /* 9 */ {OP_Close, 0, 0, 0}
+ /* 6 */ {OP_AddImm, 0, 0, 0},
+ /* 7 */ {OP_Copy, 0, 0, 0},
+ /* 8 */ {OP_Goto, 0, 11, 0},
+ /* 9 */ {OP_Next, 0, 2, 0},
+ /* 10 */ {OP_Integer, 0, 0, 0},
+ /* 11 */ {OP_Close, 0, 0, 0}
};
VdbeOp *aOp;
pDb = &db->aDb[p->iDb];
@@ -110368,14 +115609,17 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
if( aOp==0 ) break;
aOp[0].p2 = memId;
- aOp[0].p3 = memId+1;
+ aOp[0].p3 = memId+2;
aOp[2].p3 = memId;
aOp[3].p1 = memId-1;
aOp[3].p3 = memId;
aOp[3].p5 = SQLITE_JUMPIFNULL;
aOp[4].p2 = memId+1;
aOp[5].p3 = memId;
- aOp[8].p2 = memId;
+ aOp[6].p1 = memId;
+ aOp[7].p2 = memId+2;
+ aOp[7].p1 = memId;
+ aOp[10].p2 = memId;
}
}
@@ -110422,6 +115666,8 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){
iRec = sqlite3GetTempReg(pParse);
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
+ sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId);
+ VdbeCoverage(v);
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
if( aOp==0 ) break;
@@ -110559,7 +115805,8 @@ SQLITE_PRIVATE void sqlite3Insert(
SrcList *pTabList, /* Name of table into which we are inserting */
Select *pSelect, /* A SELECT statement to use as the data source */
IdList *pColumn, /* Column names corresponding to IDLIST. */
- int onError /* How to handle constraint errors */
+ int onError, /* How to handle constraint errors */
+ Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */
){
sqlite3 *db; /* The main database structure */
Table *pTab; /* The table to insert into. aka TABLE */
@@ -110854,7 +116101,10 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Initialize the count of rows to be inserted
*/
- if( db->flags & SQLITE_CountRows ){
+ if( (db->flags & SQLITE_CountRows)!=0
+ && !pParse->nested
+ && !pParse->pTriggerTab
+ ){
regRowCount = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
}
@@ -110874,6 +116124,19 @@ SQLITE_PRIVATE void sqlite3Insert(
pParse->nMem += pIdx->nColumn;
}
}
+#ifndef SQLITE_OMIT_UPSERT
+ if( pUpsert ){
+ pTabList->a[0].iCursor = iDataCur;
+ pUpsert->pUpsertSrc = pTabList;
+ pUpsert->regData = regData;
+ pUpsert->iDataCur = iDataCur;
+ pUpsert->iIdxCur = iIdxCur;
+ if( pUpsert->pUpsertTarget ){
+ sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert);
+ }
+ }
+#endif
+
/* This is the top of the main insertion loop */
if( useTempTable ){
@@ -110988,7 +116251,8 @@ SQLITE_PRIVATE void sqlite3Insert(
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
pOp = sqlite3VdbeGetOp(v, -1);
- if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+ assert( pOp!=0 );
+ if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
pOp->p1 = iDataCur;
@@ -111075,7 +116339,7 @@ SQLITE_PRIVATE void sqlite3Insert(
int isReplace; /* Set to true if constraints may cause a replace */
int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
- regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert
);
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
@@ -111098,7 +116362,7 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Update the count of rows that are inserted
*/
- if( (db->flags & SQLITE_CountRows)!=0 ){
+ if( regRowCount ){
sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
}
@@ -111135,7 +116399,7 @@ insert_end:
** generating code because of a call to sqlite3NestedParse(), do not
** invoke the callback function.
*/
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+ if( regRowCount ){
sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
@@ -111144,6 +116408,7 @@ insert_end:
insert_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pList);
+ sqlite3UpsertDelete(db, pUpsert);
sqlite3SelectDelete(db, pSelect);
sqlite3IdListDelete(db, pColumn);
sqlite3DbFree(db, aRegIdx);
@@ -111163,14 +116428,15 @@ insert_cleanup:
#endif
/*
-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
+** Meanings of bits in of pWalker->eCode for
+** sqlite3ExprReferencesUpdatedColumn()
*/
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
-/* This is the Walker callback from checkConstraintUnchanged(). Set
-** bit 0x01 of pWalker->eCode if
-** pWalker->eCode to 0 if this expression node references any of the
+/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
+* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
+** expression node references any of the
** columns that are being modifed by an UPDATE statement.
*/
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
@@ -111192,12 +116458,21 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
** only columns that are modified by the UPDATE are those for which
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
**
-** Return true if CHECK constraint pExpr does not use any of the
+** Return true if CHECK constraint pExpr uses any of the
** changing columns (or the rowid if it is changing). In other words,
-** return true if this CHECK constraint can be skipped when validating
+** return true if this CHECK constraint must be validated for
** the new row in the UPDATE statement.
+**
+** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
+** The operation of this routine is the same - return true if an only if
+** the expression uses one or more of columns identified by the second and
+** third arguments.
*/
-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
+ Expr *pExpr, /* The expression to be checked */
+ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
+ int chngRowid /* True if UPDATE changes the rowid */
+){
Walker w;
memset(&w, 0, sizeof(w));
w.eCode = 0;
@@ -111212,7 +116487,7 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
testcase( w.eCode==CKCNSTRNT_COLUMN );
testcase( w.eCode==CKCNSTRNT_ROWID );
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
- return !w.eCode;
+ return w.eCode!=0;
}
/*
@@ -111310,7 +116585,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
u8 overrideError, /* Override onError to this if not OE_Default */
int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */
- int *aiChng /* column i is unchanged if aiChng[i]<0 */
+ int *aiChng, /* column i is unchanged if aiChng[i]<0 */
+ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */
){
Vdbe *v; /* VDBE under constrution */
Index *pIdx; /* Pointer to one of the indices */
@@ -111323,10 +116599,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int addr1; /* Address of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
- int ipkTop = 0; /* Top of the rowid change constraint check */
- int ipkBottom = 0; /* Bottom of the rowid change constraint check */
+ Index *pUpIdx = 0; /* Index to which to apply the upsert */
u8 isUpdate; /* True if this is an UPDATE operation */
u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
+ int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */
+ int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */
+ int ipkTop = 0; /* Top of the IPK uniqueness check */
+ int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */
isUpdate = regOldData!=0;
db = pParse->db;
@@ -111414,8 +116693,15 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
for(i=0; i<pCheck->nExpr; i++){
int allOk;
Expr *pExpr = pCheck->a[i].pExpr;
- if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
+ if( aiChng
+ && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
+ ){
+ /* The check constraints do not reference any of the columns being
+ ** updated so there is no point it verifying the check constraint */
+ continue;
+ }
allOk = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeGoto(v, ignoreDest);
@@ -111433,6 +116719,50 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
+ /* UNIQUE and PRIMARY KEY constraints should be handled in the following
+ ** order:
+ **
+ ** (1) OE_Update
+ ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore
+ ** (3) OE_Replace
+ **
+ ** OE_Fail and OE_Ignore must happen before any changes are made.
+ ** OE_Update guarantees that only a single row will change, so it
+ ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback
+ ** could happen in any order, but they are grouped up front for
+ ** convenience.
+ **
+ ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43
+ ** The order of constraints used to have OE_Update as (2) and OE_Abort
+ ** and so forth as (1). But apparently PostgreSQL checks the OE_Update
+ ** constraint before any others, so it had to be moved.
+ **
+ ** Constraint checking code is generated in this order:
+ ** (A) The rowid constraint
+ ** (B) Unique index constraints that do not have OE_Replace as their
+ ** default conflict resolution strategy
+ ** (C) Unique index that do use OE_Replace by default.
+ **
+ ** The ordering of (2) and (3) is accomplished by making sure the linked
+ ** list of indexes attached to a table puts all OE_Replace indexes last
+ ** in the list. See sqlite3CreateIndex() for where that happens.
+ */
+
+ if( pUpsert ){
+ if( pUpsert->pUpsertTarget==0 ){
+ /* An ON CONFLICT DO NOTHING clause, without a constraint-target.
+ ** Make all unique constraint resolution be OE_Ignore */
+ assert( pUpsert->pUpsertSet==0 );
+ overrideError = OE_Ignore;
+ pUpsert = 0;
+ }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){
+ /* If the constraint-target uniqueness check must be run first.
+ ** Jump to that uniqueness check now */
+ upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
+ VdbeComment((v, "UPSERT constraint goes first"));
+ }
+ }
+
/* If rowid is changing, make sure the new rowid does not previously
** exist in the table.
*/
@@ -111447,13 +116777,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
onError = OE_Abort;
}
- if( isUpdate ){
- /* pkChng!=0 does not mean that the rowid has changed, only that
- ** it might have changed. Skip the conflict logic below if the rowid
- ** is unchanged. */
- sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- VdbeCoverage(v);
+ /* figure out whether or not upsert applies in this case */
+ if( pUpsert && pUpsert->pUpsertIdx==0 ){
+ if( pUpsert->pUpsertSet==0 ){
+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */
+ }else{
+ onError = OE_Update; /* DO UPDATE */
+ }
}
/* If the response to a rowid conflict is REPLACE but the response
@@ -111461,21 +116791,30 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** to defer the running of the rowid conflict checking until after
** the UNIQUE constraints have run.
*/
- if( onError==OE_Replace && overrideError!=OE_Replace ){
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
- ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
- break;
- }
- }
+ if( onError==OE_Replace /* IPK rule is REPLACE */
+ && onError!=overrideError /* Rules for other contraints are different */
+ && pTab->pIndex /* There exist other constraints */
+ ){
+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
+ VdbeComment((v, "defer IPK REPLACE until last"));
+ }
+
+ if( isUpdate ){
+ /* pkChng!=0 does not mean that the rowid has changed, only that
+ ** it might have changed. Skip the conflict logic below if the rowid
+ ** is unchanged. */
+ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
}
/* Check to see if the new rowid already exists in the table. Skip
** the following conflict logic if it does not. */
+ VdbeNoopComment((v, "uniqueness check for ROWID"));
+ sqlite3VdbeVerifyAbortable(v, onError);
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
VdbeCoverage(v);
- /* Generate code that deals with a rowid collision */
switch( onError ){
default: {
onError = OE_Abort;
@@ -111484,6 +116823,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
+ testcase( onError==OE_Rollback );
+ testcase( onError==OE_Abort );
+ testcase( onError==OE_Fail );
sqlite3RowidConstraint(pParse, onError, pTab);
break;
}
@@ -111520,14 +116862,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
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);
- sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
- }
+ assert( 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);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
if( pTab->pIndex ){
sqlite3MultiWrite(pParse);
@@ -111537,8 +116878,14 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
seenReplace = 1;
break;
}
+#ifndef SQLITE_OMIT_UPSERT
+ case OE_Update: {
+ sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur);
+ /* Fall through */
+ }
+#endif
case OE_Ignore: {
- /*assert( seenReplace==0 );*/
+ testcase( onError==OE_Ignore );
sqlite3VdbeGoto(v, ignoreDest);
break;
}
@@ -111546,7 +116893,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeResolveLabel(v, addrRowidOk);
if( ipkTop ){
ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, ipkTop);
+ sqlite3VdbeJumpHere(v, ipkTop-1);
}
}
@@ -111564,12 +116911,21 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
- if( bAffinityDone==0 ){
+ if( pUpIdx==pIdx ){
+ addrUniqueOk = upsertJump+1;
+ upsertBypass = sqlite3VdbeGoto(v, 0);
+ VdbeComment((v, "Skip upsert subroutine"));
+ sqlite3VdbeJumpHere(v, upsertJump);
+ }else{
+ addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ }
+ if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
sqlite3TableAffinity(v, pTab, regNewData+1);
bAffinityDone = 1;
}
+ VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
iThisCur = iIdxCur+ix;
- addrUniqueOk = sqlite3VdbeMakeLabel(v);
+
/* Skip partial indices for which the WHERE clause is not true */
if( pIdx->pPartIdxWhere ){
@@ -111629,6 +116985,15 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
onError = OE_Abort;
}
+ /* Figure out if the upsert clause applies to this index */
+ if( pUpIdx==pIdx ){
+ if( pUpsert->pUpsertSet==0 ){
+ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */
+ }else{
+ onError = OE_Update; /* DO UPDATE */
+ }
+ }
+
/* Collision detection may be omitted if all of the following are true:
** (1) The conflict resolution algorithm is REPLACE
** (2) The table is a WITHOUT ROWID table
@@ -111649,6 +117014,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
/* Check to see if the new index entry will be unique */
+ sqlite3VdbeVerifyAbortable(v, onError);
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
@@ -111710,25 +117076,37 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Generate code that executes if the new index entry is not unique */
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
+ || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update );
switch( onError ){
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
+ testcase( onError==OE_Rollback );
+ testcase( onError==OE_Abort );
+ testcase( onError==OE_Fail );
sqlite3UniqueConstraint(pParse, onError, pIdx);
break;
}
+#ifndef SQLITE_OMIT_UPSERT
+ case OE_Update: {
+ sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix);
+ /* Fall through */
+ }
+#endif
case OE_Ignore: {
+ testcase( onError==OE_Ignore );
sqlite3VdbeGoto(v, ignoreDest);
break;
}
default: {
Trigger *pTrigger = 0;
assert( onError==OE_Replace );
- sqlite3MultiWrite(pParse);
if( db->flags&SQLITE_RecTriggers ){
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
+ if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
+ sqlite3MultiWrite(pParse);
+ }
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regR, nPkField, 0, OE_Replace,
(pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
@@ -111736,14 +117114,22 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
break;
}
}
- sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ if( pUpIdx==pIdx ){
+ sqlite3VdbeGoto(v, upsertJump+1);
+ sqlite3VdbeJumpHere(v, upsertBypass);
+ }else{
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ }
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
+
+ /* If the IPK constraint is a REPLACE, run it last */
if( ipkTop ){
sqlite3VdbeGoto(v, ipkTop+1);
+ VdbeComment((v, "Do IPK REPLACE"));
sqlite3VdbeJumpHere(v, ipkBottom);
}
-
+
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
@@ -111839,7 +117225,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
sqlite3SetMakeRecordP5(v, pTab);
if( !bAffinityDone ){
sqlite3TableAffinity(v, pTab, 0);
- sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
}
if( pParse->nested ){
pik_flags = 0;
@@ -112085,7 +117470,6 @@ static int xferOptimization(
if( pSelect->pLimit ){
return 0; /* SELECT may not have a LIMIT clause */
}
- assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
if( pSelect->pPrior ){
return 0; /* SELECT may not be a compound query */
}
@@ -112243,6 +117627,7 @@ static int xferOptimization(
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
if( pDest->iPKey>=0 ){
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ sqlite3VdbeVerifyAbortable(v, onError);
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
VdbeCoverage(v);
sqlite3RowidConstraint(pParse, onError, pDest);
@@ -112797,6 +118182,30 @@ struct sqlite3_api_routines {
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
+ int (*vtab_nochange)(sqlite3_context*);
+ int (*value_nochange)(sqlite3_value*);
+ const char *(*vtab_collation)(sqlite3_index_info*,int);
+ /* Version 3.24.0 and later */
+ int (*keyword_count)(void);
+ int (*keyword_name)(int,const char**,int*);
+ int (*keyword_check)(const char*,int);
+ sqlite3_str *(*str_new)(sqlite3*);
+ char *(*str_finish)(sqlite3_str*);
+ void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
+ void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
+ void (*str_append)(sqlite3_str*, const char *zIn, int N);
+ void (*str_appendall)(sqlite3_str*, const char *zIn);
+ void (*str_appendchar)(sqlite3_str*, int N, char C);
+ void (*str_reset)(sqlite3_str*);
+ int (*str_errcode)(sqlite3_str*);
+ int (*str_length)(sqlite3_str*);
+ char *(*str_value)(sqlite3_str*);
+ int (*create_window_function)(sqlite3*,const char*,int,int,void*,
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInv)(sqlite3_context*,int,sqlite3_value**),
+ void(*xDestroy)(void*));
};
/*
@@ -113069,6 +118478,27 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
+#define sqlite3_value_nochange sqlite3_api->value_nochange
+#define sqlite3_vtab_collation sqlite3_api->vtab_collation
+/* Version 3.24.0 and later */
+#define sqlite3_keyword_count sqlite3_api->keyword_count
+#define sqlite3_keyword_name sqlite3_api->keyword_name
+#define sqlite3_keyword_check sqlite3_api->keyword_check
+#define sqlite3_str_new sqlite3_api->str_new
+#define sqlite3_str_finish sqlite3_api->str_finish
+#define sqlite3_str_appendf sqlite3_api->str_appendf
+#define sqlite3_str_vappendf sqlite3_api->str_vappendf
+#define sqlite3_str_append sqlite3_api->str_append
+#define sqlite3_str_appendall sqlite3_api->str_appendall
+#define sqlite3_str_appendchar sqlite3_api->str_appendchar
+#define sqlite3_str_reset sqlite3_api->str_reset
+#define sqlite3_str_errcode sqlite3_api->str_errcode
+#define sqlite3_str_length sqlite3_api->str_length
+#define sqlite3_str_value sqlite3_api->str_value
+/* Version 3.25.0 and later */
+#define sqlite3_create_window_function sqlite3_api->create_window_function
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -113516,7 +118946,28 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_prepare16_v3,
sqlite3_bind_pointer,
sqlite3_result_pointer,
- sqlite3_value_pointer
+ sqlite3_value_pointer,
+ /* Version 3.22.0 and later */
+ sqlite3_vtab_nochange,
+ sqlite3_value_nochange,
+ sqlite3_vtab_collation,
+ /* Version 3.24.0 and later */
+ sqlite3_keyword_count,
+ sqlite3_keyword_name,
+ sqlite3_keyword_check,
+ sqlite3_str_new,
+ sqlite3_str_finish,
+ sqlite3_str_appendf,
+ sqlite3_str_vappendf,
+ sqlite3_str_append,
+ sqlite3_str_appendall,
+ sqlite3_str_appendchar,
+ sqlite3_str_reset,
+ sqlite3_str_errcode,
+ sqlite3_str_length,
+ sqlite3_str_value,
+ /* Version 3.25.0 and later */
+ sqlite3_create_window_function
};
/*
@@ -114320,6 +119771,11 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ {/* zName: */ "legacy_alter_table",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_LegacyAlter },
{/* zName: */ "legacy_file_format",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -114573,7 +120029,7 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_WriteSchema },
#endif
};
-/* Number of pragmas: 60 on by default, 77 total. */
+/* Number of pragmas: 61 on by default, 78 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
@@ -115628,6 +121084,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** type: Column declaration type.
** notnull: True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
+ ** pk: Non-zero for PK fields.
*/
case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
@@ -116097,7 +121554,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
- sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
/* reg[7] counts the number of entries in the table.
@@ -116111,6 +121567,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( sqlite3NoTempsInRange(pParse,1,7+j) );
sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+ if( !isQuick ){
+ /* Sanity check on record header decoding */
+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ }
/* Verify that all NOT NULL columns really are NOT NULL */
for(j=0; j<pTab->nCol; j++){
char *zErr;
@@ -116135,7 +121596,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
char *zErr;
int k;
pParse->iSelfTab = iDataCur + 1;
- sqlite3ExprCachePush(pParse);
for(k=pCheck->nExpr-1; k>0; k--){
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
}
@@ -116148,14 +121608,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
integrityCheckResultRow(v);
sqlite3VdbeResolveLabel(v, addrCkOk);
- sqlite3ExprCachePop(pParse);
}
sqlite3ExprListDelete(db, pCheck);
}
if( !isQuick ){ /* Omit the remaining tests for quick_check */
- /* Sanity check on record header decoding */
- sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
- sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
/* Validate index entries for the current row */
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
@@ -116763,26 +122219,25 @@ static int pragmaVtabConnect(
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
- sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
+ sqlite3_str_appendall(&acc, "CREATE TABLE x");
for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
- sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
+ sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
cSep = ',';
}
if( i==0 ){
- sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
- cSep = ',';
+ sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
i++;
}
j = 0;
if( pPragma->mPragFlg & PragFlg_Result1 ){
- sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
+ sqlite3_str_appendall(&acc, ",arg HIDDEN");
j++;
}
if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
- sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
+ sqlite3_str_appendall(&acc, ",schema HIDDEN");
j++;
}
- sqlite3StrAccumAppend(&acc, ")", 1);
+ sqlite3_str_append(&acc, ")", 1);
sqlite3StrAccumFinish(&acc);
assert( strlen(zBuf) < sizeof(zBuf)-1 );
rc = sqlite3_declare_vtab(db, zBuf);
@@ -116934,13 +122389,13 @@ static int pragmaVtabFilter(
}
}
sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
- sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
+ sqlite3_str_appendall(&acc, "PRAGMA ");
if( pCsr->azArg[1] ){
- sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
+ sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
}
- sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
+ sqlite3_str_appendall(&acc, pTab->pName->zName);
if( pCsr->azArg[0] ){
- sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
+ sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
}
zSql = sqlite3StrAccumFinish(&acc);
if( zSql==0 ) return SQLITE_NOMEM;
@@ -117063,15 +122518,23 @@ static void corruptSchema(
const char *zExtra /* Error information */
){
sqlite3 *db = pData->db;
- if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
+ if( db->mallocFailed ){
+ pData->rc = SQLITE_NOMEM_BKPT;
+ }else if( pData->pzErrMsg[0]!=0 ){
+ /* A error message has already been generated. Do not overwrite it */
+ }else if( pData->mInitFlags & INITFLAG_AlterTable ){
+ *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);
+ pData->rc = SQLITE_ERROR;
+ }else if( db->flags & SQLITE_WriteSchema ){
+ pData->rc = SQLITE_CORRUPT_BKPT;
+ }else{
char *z;
if( zObj==0 ) zObj = "?";
z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
- if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
- sqlite3DbFree(db, *pData->pzErrMsg);
+ if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
*pData->pzErrMsg = z;
+ pData->rc = SQLITE_CORRUPT_BKPT;
}
- pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
}
/*
@@ -117123,7 +122586,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
- assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 );
+ /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
@@ -117170,7 +122633,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
** auxiliary databases. Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
-static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
+SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
int rc;
int i;
#ifndef SQLITE_OMIT_DEPRECATED
@@ -117183,6 +122646,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
const char *zMasterName;
int openedTransaction = 0;
+ assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pSchema );
assert( sqlite3_mutex_held(db->mutex) );
@@ -117204,6 +122668,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
initData.iDb = iDb;
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
+ initData.mInitFlags = mFlags;
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
if( initData.rc ){
rc = initData.rc;
@@ -117225,7 +122690,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** will be closed before this function returns. */
sqlite3BtreeEnter(pDb->pBt);
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
- rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
+ rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
if( rc!=SQLITE_OK ){
sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
goto initone_error_out;
@@ -117253,6 +122718,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
for(i=0; i<ArraySize(meta); i++){
sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
}
+ if( (db->flags & SQLITE_ResetDatabase)!=0 ){
+ memset(meta, 0, sizeof(meta));
+ }
pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
/* If opening a non-empty database, check the text encoding. For the
@@ -117407,13 +122875,14 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
assert( db->nDb>0 );
/* Do the main schema first */
if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
- rc = sqlite3InitOne(db, 0, pzErrMsg);
+ rc = sqlite3InitOne(db, 0, pzErrMsg, 0);
if( rc ) return rc;
}
/* All other schemas after the main schema. The "temp" schema must be last */
for(i=db->nDb-1; i>0; i--){
+ assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) );
if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
- rc = sqlite3InitOne(db, i, pzErrMsg);
+ rc = sqlite3InitOne(db, i, pzErrMsg, 0);
if( rc ) return rc;
}
}
@@ -117433,10 +122902,12 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){
assert( sqlite3_mutex_held(db->mutex) );
if( !db->init.busy ){
rc = sqlite3Init(db, &pParse->zErrMsg);
- }
- if( rc!=SQLITE_OK ){
- pParse->rc = rc;
- pParse->nErr++;
+ if( rc!=SQLITE_OK ){
+ pParse->rc = rc;
+ pParse->nErr++;
+ }else if( db->noSharedCache ){
+ db->mDbFlags |= DBFLAG_SchemaKnownOk;
+ }
}
return rc;
}
@@ -117464,7 +122935,7 @@ static void schemaIsValid(Parse *pParse){
** on the b-tree database, open one now. If a transaction is opened, it
** will be closed immediately after reading the meta-value. */
if( !sqlite3BtreeIsInReadTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
sqlite3OomFault(db);
}
@@ -117511,7 +122982,8 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
*/
assert( sqlite3_mutex_held(db->mutex) );
if( pSchema ){
- for(i=0; ALWAYS(i<db->nDb); i++){
+ for(i=0; 1; i++){
+ assert( i<db->nDb );
if( db->aDb[i].pSchema==pSchema ){
break;
}
@@ -117646,7 +123118,7 @@ static int sqlite3Prepare(
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
static const char * const azColName[] = {
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
- "selectid", "order", "from", "detail"
+ "id", "parent", "notused", "detail"
};
int iFirst, mx;
if( sParse.explain==2 ){
@@ -117692,8 +123164,6 @@ static int sqlite3Prepare(
end_prepare:
sqlite3ParserReset(&sParse);
- rc = sqlite3ApiExit(db, rc);
- assert( (rc&db->errMask)==rc );
return rc;
}
static int sqlite3LockAndPrepare(
@@ -117706,6 +123176,7 @@ static int sqlite3LockAndPrepare(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
+ int cnt = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
@@ -117716,15 +123187,18 @@ static int sqlite3LockAndPrepare(
}
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
- rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
- if( rc==SQLITE_SCHEMA ){
- sqlite3ResetOneSchema(db, -1);
- sqlite3_finalize(*ppStmt);
+ do{
+ /* Make multiple attempts to compile the SQL, until it either succeeds
+ ** or encounters a permanent error. A schema problem after one schema
+ ** reset is considered a permanent error. */
rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
- }
+ assert( rc==SQLITE_OK || *ppStmt==0 );
+ }while( rc==SQLITE_ERROR_RETRY
+ || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
sqlite3BtreeLeaveAll(db);
+ rc = sqlite3ApiExit(db, rc);
+ assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
- assert( rc==SQLITE_OK || *ppStmt==0 );
return rc;
}
@@ -117958,8 +123432,7 @@ SQLITE_API int sqlite3_prepare16_v3(
/***/ int sqlite3SelectTrace = 0;
# define SELECTTRACE(K,P,S,X) \
if(sqlite3SelectTrace&(K)) \
- sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
- (S)->zSelName,(S)),\
+ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
sqlite3DebugPrintf X
#else
# define SELECTTRACE(K,P,S,X)
@@ -117982,6 +123455,20 @@ struct DistinctCtx {
/*
** An instance of the following object is used to record information about
** the ORDER BY (or GROUP BY) clause of query is being coded.
+**
+** The aDefer[] array is used by the sorter-references optimization. For
+** example, assuming there is no index that can be used for the ORDER BY,
+** for the query:
+**
+** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10;
+**
+** it may be more efficient to add just the "a" values to the sorter, and
+** retrieve the associated "bigblob" values directly from table t1 as the
+** 10 smallest "a" values are extracted from the sorter.
+**
+** When the sorter-reference optimization is used, there is one entry in the
+** aDefer[] array for each database table that may be read as values are
+** extracted from the sorter.
*/
typedef struct SortCtx SortCtx;
struct SortCtx {
@@ -117992,8 +123479,17 @@ struct SortCtx {
int labelBkOut; /* Start label for the block-output subroutine */
int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */
int labelDone; /* Jump here when done, ex: LIMIT reached */
+ int labelOBLopt; /* Jump here when sorter is full */
u8 sortFlags; /* Zero or more SORTFLAG_* bits */
- u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ u8 nDefer; /* Number of valid entries in aDefer[] */
+ struct DeferredCsr {
+ Table *pTab; /* Table definition */
+ int iCsr; /* Cursor number for table */
+ int nKey; /* Number of PK columns for table pTab (>=1) */
+ } aDefer[4];
+#endif
+ struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */
};
#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */
@@ -118011,7 +123507,11 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3ExprDelete(db, p->pHaving);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
- sqlite3ExprDelete(db, p->pOffset);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
+ sqlite3WindowListDelete(db, p->pWinDefn);
+ }
+#endif
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
@@ -118044,8 +123544,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
u32 selFlags, /* Flag parameters, such as SF_Distinct */
- Expr *pLimit, /* LIMIT value. NULL means not used */
- Expr *pOffset /* OFFSET value. NULL means no offset */
+ Expr *pLimit /* LIMIT value. NULL means not used */
){
Select *pNew;
Select standin;
@@ -118063,9 +123562,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->selFlags = selFlags;
pNew->iLimit = 0;
pNew->iOffset = 0;
-#if SELECTTRACE_ENABLED
- pNew->zSelName[0] = 0;
-#endif
+ pNew->selId = ++pParse->nSelect;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = 0;
@@ -118078,10 +123575,11 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->pPrior = 0;
pNew->pNext = 0;
pNew->pLimit = pLimit;
- pNew->pOffset = pOffset;
pNew->pWith = 0;
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0
- || pParse->db->mallocFailed!=0 );
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ pNew->pWin = 0;
+ pNew->pWinDefn = 0;
+#endif
if( pParse->db->mallocFailed ) {
clearSelect(pParse->db, pNew, pNew!=&standin);
pNew = 0;
@@ -118092,17 +123590,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
return pNew;
}
-#if SELECTTRACE_ENABLED
-/*
-** Set the name of a Select object
-*/
-SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
- if( p && zName ){
- sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
- }
-}
-#endif
-
/*
** Delete the given Select structure and all of its substructures.
@@ -118325,6 +123812,29 @@ static void setJoinExpr(Expr *p, int iTable){
}
}
+/* Undo the work of setJoinExpr(). In the expression tree p, convert every
+** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
+** an ordinary term that omits the EP_FromJoin mark.
+**
+** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
+*/
+static void unsetJoinExpr(Expr *p, int iTable){
+ while( p ){
+ if( ExprHasProperty(p, EP_FromJoin)
+ && (iTable<0 || p->iRightJoinTable==iTable) ){
+ ExprClearProperty(p, EP_FromJoin);
+ }
+ if( p->op==TK_FUNCTION && p->x.pList ){
+ int i;
+ for(i=0; i<p->x.pList->nExpr; i++){
+ unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
+ }
+ }
+ unsetJoinExpr(p->pLeft, iTable);
+ p = p->pRight;
+ }
+}
+
/*
** This routine processes the join information for a SELECT statement.
** ON and USING clauses are converted into extra terms of the WHERE clause.
@@ -118426,13 +123936,61 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
return 0;
}
-/* Forward reference */
-static KeyInfo *keyInfoFromExprList(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* Form the KeyInfo object from this ExprList */
- int iStart, /* Begin with this column of pList */
- int nExtra /* Add this many extra columns to the end */
-);
+/*
+** An instance of this object holds information (beyond pParse and pSelect)
+** needed to load the next result row that is to be added to the sorter.
+*/
+typedef struct RowLoadInfo RowLoadInfo;
+struct RowLoadInfo {
+ int regResult; /* Store results in array of registers here */
+ u8 ecelFlags; /* Flag argument to ExprCodeExprList() */
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ ExprList *pExtra; /* Extra columns needed by sorter refs */
+ int regExtraResult; /* Where to load the extra columns */
+#endif
+};
+
+/*
+** This routine does the work of loading query data into an array of
+** registers so that it can be added to the sorter.
+*/
+static void innerLoopLoadRow(
+ Parse *pParse, /* Statement under construction */
+ Select *pSelect, /* The query being coded */
+ RowLoadInfo *pInfo /* Info needed to complete the row load */
+){
+ sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult,
+ 0, pInfo->ecelFlags);
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( pInfo->pExtra ){
+ sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0);
+ sqlite3ExprListDelete(pParse->db, pInfo->pExtra);
+ }
+#endif
+}
+
+/*
+** Code the OP_MakeRecord instruction that generates the entry to be
+** added into the sorter.
+**
+** Return the register in which the result is stored.
+*/
+static int makeSorterRecord(
+ Parse *pParse,
+ SortCtx *pSort,
+ Select *pSelect,
+ int regBase,
+ int nBase
+){
+ int nOBSat = pSort->nOBSat;
+ Vdbe *v = pParse->pVdbe;
+ int regOut = ++pParse->nMem;
+ if( pSort->pDeferredRowLoad ){
+ innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut);
+ return regOut;
+}
/*
** Generate code that will push the record in registers regData
@@ -118444,7 +124002,7 @@ static void pushOntoSorter(
Select *pSelect, /* The whole SELECT statement */
int regData, /* First register holding data to be sorted */
int regOrigData, /* First register holding data before packing */
- int nData, /* Number of elements in the data array */
+ int nData, /* Number of elements in the regData data array */
int nPrefixReg /* No. of reg prior to regData available for use */
){
Vdbe *v = pParse->pVdbe; /* Stmt under construction */
@@ -118452,16 +124010,32 @@ static void pushOntoSorter(
int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */
int nBase = nExpr + bSeq + nData; /* Fields in sorter record */
int regBase; /* Regs for sorter record */
- int regRecord = ++pParse->nMem; /* Assembled sorter record */
+ int regRecord = 0; /* Assembled sorter record */
int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */
int op; /* Opcode to add sorter record to sorter */
int iLimit; /* LIMIT counter */
+ int iSkip = 0; /* End of the sorter insert loop */
assert( bSeq==0 || bSeq==1 );
+
+ /* Three cases:
+ ** (1) The data to be sorted has already been packed into a Record
+ ** by a prior OP_MakeRecord. In this case nData==1 and regData
+ ** will be completely unrelated to regOrigData.
+ ** (2) All output columns are included in the sort record. In that
+ ** case regData==regOrigData.
+ ** (3) Some output columns are omitted from the sort record due to
+ ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the
+ ** SQLITE_ECEL_OMITREF optimization, or due to the
+ ** SortCtx.pDeferredRowLoad optimiation. In any of these cases
+ ** regOrigData is 0 to prevent this routine from trying to copy
+ ** values that might not yet exist.
+ */
assert( nData==1 || regData==regOrigData || regOrigData==0 );
+
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
- regBase = regData - nExpr - bSeq;
+ regBase = regData - nPrefixReg;
}else{
regBase = pParse->nMem + 1;
pParse->nMem += nBase;
@@ -118477,7 +124051,6 @@ static void pushOntoSorter(
if( nPrefixReg==0 && nData>0 ){
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
if( nOBSat>0 ){
int regPrevKey; /* The first nOBSat columns of the previous row */
int addrFirst; /* Address of the OP_IfNot opcode */
@@ -118486,6 +124059,7 @@ static void pushOntoSorter(
int nKey; /* Number of sorting key columns, including OP_Sequence */
KeyInfo *pKI; /* Original KeyInfo on the sorter table */
+ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
regPrevKey = pParse->nMem+1;
pParse->nMem += pSort->nOBSat;
nKey = nExpr - pSort->nOBSat + bSeq;
@@ -118503,7 +124077,7 @@ static void pushOntoSorter(
memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
testcase( pKI->nAllField > pKI->nKeyField+2 );
- pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
+ pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
pKI->nAllField-pKI->nKeyField-1);
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
@@ -118519,6 +124093,34 @@ static void pushOntoSorter(
sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
sqlite3VdbeJumpHere(v, addrJmp);
}
+ if( iLimit ){
+ /* At this point the values for the new sorter entry are stored
+ ** in an array of registers. They need to be composed into a record
+ ** and inserted into the sorter if either (a) there are currently
+ ** less than LIMIT+OFFSET items or (b) the new record is smaller than
+ ** the largest record currently in the sorter. If (b) is true and there
+ ** are already LIMIT+OFFSET items in the sorter, delete the largest
+ ** entry before inserting the new one. This way there are never more
+ ** than LIMIT+OFFSET items in the sorter.
+ **
+ ** If the new record does not need to be inserted into the sorter,
+ ** jump to the next iteration of the loop. If the pSort->labelOBLopt
+ ** value is not zero, then it is a label of where to jump. Otherwise,
+ ** just bypass the row insert logic. See the header comment on the
+ ** sqlite3WhereOrderByLimitOptLabel() function for additional info.
+ */
+ int iCsr = pSort->iECursor;
+ sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0);
+ iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE,
+ iCsr, 0, regBase+nOBSat, nExpr-nOBSat);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp1(v, OP_Delete, iCsr);
+ }
+ if( regRecord==0 ){
+ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
+ }
if( pSort->sortFlags & SORTFLAG_UseSorter ){
op = OP_SorterInsert;
}else{
@@ -118526,33 +124128,9 @@ static void pushOntoSorter(
}
sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
regBase+nOBSat, nBase-nOBSat);
- if( iLimit ){
- int addr;
- int r1 = 0;
- /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit
- ** register is initialized with value of LIMIT+OFFSET.) After the sorter
- ** fills up, delete the least entry in the sorter after each insert.
- ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
- addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
- sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
- if( pSort->bOrderedInnerLoop ){
- r1 = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1);
- VdbeComment((v, "seq"));
- }
- sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
- if( pSort->bOrderedInnerLoop ){
- /* If the inner loop is driven by an index such that values from
- ** the same iteration of the inner loop are in sorted order, then
- ** immediately jump to the next iteration of an inner loop if the
- ** entry from the current iteration does not fit into the top
- ** LIMIT+OFFSET entries of the sorter. */
- int iBrk = sqlite3VdbeCurrentAddr(v) + 2;
- sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1);
- sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
- VdbeCoverage(v);
- }
- sqlite3VdbeJumpHere(v, addr);
+ if( iSkip ){
+ sqlite3VdbeChangeP2(v, iSkip,
+ pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
}
}
@@ -118598,6 +124176,87 @@ static void codeDistinct(
sqlite3ReleaseTempReg(pParse, r1);
}
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+/*
+** This function is called as part of inner-loop generation for a SELECT
+** statement with an ORDER BY that is not optimized by an index. It
+** determines the expressions, if any, that the sorter-reference
+** optimization should be used for. The sorter-reference optimization
+** is used for SELECT queries like:
+**
+** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10
+**
+** If the optimization is used for expression "bigblob", then instead of
+** storing values read from that column in the sorter records, the PK of
+** the row from table t1 is stored instead. Then, as records are extracted from
+** the sorter to return to the user, the required value of bigblob is
+** retrieved directly from table t1. If the values are very large, this
+** can be more efficient than storing them directly in the sorter records.
+**
+** The ExprList_item.bSorterRef flag is set for each expression in pEList
+** for which the sorter-reference optimization should be enabled.
+** Additionally, the pSort->aDefer[] array is populated with entries
+** for all cursors required to evaluate all selected expressions. Finally.
+** output variable (*ppExtra) is set to an expression list containing
+** expressions for all extra PK values that should be stored in the
+** sorter records.
+*/
+static void selectExprDefer(
+ Parse *pParse, /* Leave any error here */
+ SortCtx *pSort, /* Sorter context */
+ ExprList *pEList, /* Expressions destined for sorter */
+ ExprList **ppExtra /* Expressions to append to sorter record */
+){
+ int i;
+ int nDefer = 0;
+ ExprList *pExtra = 0;
+ for(i=0; i<pEList->nExpr; i++){
+ struct ExprList_item *pItem = &pEList->a[i];
+ if( pItem->u.x.iOrderByCol==0 ){
+ Expr *pExpr = pItem->pExpr;
+ Table *pTab = pExpr->pTab;
+ if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
+ && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
+ ){
+ int j;
+ for(j=0; j<nDefer; j++){
+ if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
+ }
+ if( j==nDefer ){
+ if( nDefer==ArraySize(pSort->aDefer) ){
+ continue;
+ }else{
+ int nKey = 1;
+ int k;
+ Index *pPk = 0;
+ if( !HasRowid(pTab) ){
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ nKey = pPk->nKeyCol;
+ }
+ for(k=0; k<nKey; k++){
+ Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
+ if( pNew ){
+ pNew->iTable = pExpr->iTable;
+ pNew->pTab = pExpr->pTab;
+ pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
+ pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
+ }
+ }
+ pSort->aDefer[nDefer].pTab = pExpr->pTab;
+ pSort->aDefer[nDefer].iCsr = pExpr->iTable;
+ pSort->aDefer[nDefer].nKey = nKey;
+ nDefer++;
+ }
+ }
+ pItem->bSorterRef = 1;
+ }
+ }
+ }
+ pSort->nDefer = (u8)nDefer;
+ *ppExtra = pExtra;
+}
+#endif
+
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
@@ -118624,6 +124283,7 @@ static void selectInnerLoop(
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
int nPrefixReg = 0; /* Number of extra registers before regResult */
+ RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */
/* Usually, regResult is the first cell in an array of memory cells
** containing the current result row. In this case regOrig is set to the
@@ -118670,10 +124330,14 @@ static void selectInnerLoop(
VdbeComment((v, "%s", p->pEList->a[i].zName));
}
}else if( eDest!=SRT_Exists ){
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ ExprList *pExtra = 0;
+#endif
/* If the destination is an EXISTS(...) expression, the actual
** values returned by the SELECT are not required.
*/
- u8 ecelFlags;
+ u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */
+ ExprList *pEList;
if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
ecelFlags = SQLITE_ECEL_DUP;
}else{
@@ -118687,18 +124351,68 @@ static void selectInnerLoop(
** This allows the p->pEList field to be omitted from the sorted record,
** saving space and CPU cycles. */
ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
+
for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
int j;
if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
}
}
- regOrig = 0;
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ selectExprDefer(pParse, pSort, p->pEList, &pExtra);
+ if( pExtra && pParse->db->mallocFailed==0 ){
+ /* If there are any extra PK columns to add to the sorter records,
+ ** allocate extra memory cells and adjust the OpenEphemeral
+ ** instruction to account for the larger records. This is only
+ ** required if there are one or more WITHOUT ROWID tables with
+ ** composite primary keys in the SortCtx.aDefer[] array. */
+ VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
+ pOp->p2 += (pExtra->nExpr - pSort->nDefer);
+ pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer);
+ pParse->nMem += pExtra->nExpr;
+ }
+#endif
+
+ /* Adjust nResultCol to account for columns that are omitted
+ ** from the sorter by the optimizations in this branch */
+ pEList = p->pEList;
+ for(i=0; i<pEList->nExpr; i++){
+ if( pEList->a[i].u.x.iOrderByCol>0
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ || pEList->a[i].bSorterRef
+#endif
+ ){
+ nResultCol--;
+ regOrig = 0;
+ }
+ }
+
+ testcase( regOrig );
+ testcase( eDest==SRT_Set );
+ testcase( eDest==SRT_Mem );
+ testcase( eDest==SRT_Coroutine );
+ testcase( eDest==SRT_Output );
assert( eDest==SRT_Set || eDest==SRT_Mem
|| eDest==SRT_Coroutine || eDest==SRT_Output );
}
- nResultCol = sqlite3ExprCodeExprList(pParse,p->pEList,regResult,
- 0,ecelFlags);
+ sRowLoadInfo.regResult = regResult;
+ sRowLoadInfo.ecelFlags = ecelFlags;
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ sRowLoadInfo.pExtra = pExtra;
+ sRowLoadInfo.regExtraResult = regResult + nResultCol;
+ if( pExtra ) nResultCol += pExtra->nExpr;
+#endif
+ if( p->iLimit
+ && (ecelFlags & SQLITE_ECEL_OMITREF)!=0
+ && nPrefixReg>0
+ ){
+ assert( pSort!=0 );
+ assert( hasDistinct==0 );
+ pSort->pDeferredRowLoad = &sRowLoadInfo;
+ regOrig = 0;
+ }else{
+ innerLoopLoadRow(pParse, p, &sRowLoadInfo);
+ }
}
/* If the DISTINCT keyword was present on the SELECT statement
@@ -118814,7 +124528,8 @@ static void selectInnerLoop(
}
#endif
if( pSort ){
- pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
+ assert( regResult==regOrig );
+ pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg);
}else{
int r2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
@@ -118844,7 +124559,6 @@ static void selectInnerLoop(
assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol,
r1, pDest->zAffSdst, nResultCol);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
sqlite3ReleaseTempReg(pParse, r1);
}
@@ -118888,7 +124602,6 @@ static void selectInnerLoop(
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
}
break;
}
@@ -119031,7 +124744,7 @@ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
** function is responsible for seeing that this structure is eventually
** freed.
*/
-static KeyInfo *keyInfoFromExprList(
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* Form the KeyInfo object from this ExprList */
int iStart, /* Begin with this column of pList */
@@ -119081,11 +124794,7 @@ static const char *selectOpName(int id){
** is determined by the zUsage argument.
*/
static void explainTempTable(Parse *pParse, const char *zUsage){
- if( pParse->explain==2 ){
- Vdbe *v = pParse->pVdbe;
- char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
+ ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage));
}
/*
@@ -119103,42 +124812,6 @@ static void explainTempTable(Parse *pParse, const char *zUsage){
# define explainSetInteger(y,z)
#endif
-#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
-/*
-** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
-** is a no-op. Otherwise, it adds a single row of output to the EQP result,
-** where the caption is of one of the two forms:
-**
-** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
-** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
-**
-** where iSub1 and iSub2 are the integers passed as the corresponding
-** function parameters, and op is the text representation of the parameter
-** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
-** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
-** false, or the second form if it is true.
-*/
-static void explainComposite(
- Parse *pParse, /* Parse context */
- int op, /* One of TK_UNION, TK_EXCEPT etc. */
- int iSub1, /* Subquery id 1 */
- int iSub2, /* Subquery id 2 */
- int bUseTmp /* True if a temp table was used */
-){
- assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
- if( pParse->explain==2 ){
- Vdbe *v = pParse->pVdbe;
- char *zMsg = sqlite3MPrintf(
- pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
- bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
- );
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
-}
-#else
-/* No-op versions of the explainXXX() functions and macros. */
-# define explainComposite(v,w,x,y,z)
-#endif
/*
** If the inner loop was generated using a non-null pOrderBy argument,
@@ -119156,7 +124829,7 @@ static void generateSortTail(
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = pSort->labelDone; /* Jump here to exit loop */
int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
- int addr;
+ int addr; /* Top of output loop. Jump for Next. */
int addrOnce = 0;
int iTab;
ExprList *pOrderBy = pSort->pOrderBy;
@@ -119165,11 +124838,11 @@ static void generateSortTail(
int regRow;
int regRowid;
int iCol;
- int nKey;
+ int nKey; /* Number of key columns in sorter record */
int iSortTab; /* Sorter cursor to read from */
- int nSortData; /* Trailing values to read from sorter */
int i;
int bSeq; /* True if sorter record includes seq. no. */
+ int nRefKey = 0;
struct ExprList_item *aOutEx = p->pEList->a;
assert( addrBreak<0 );
@@ -119178,15 +124851,24 @@ static void generateSortTail(
sqlite3VdbeGoto(v, addrBreak);
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
}
+
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ /* Open any cursors needed for sorter-reference expressions */
+ for(i=0; i<pSort->nDefer; i++){
+ Table *pTab = pSort->aDefer[i].pTab;
+ int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead);
+ nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey);
+ }
+#endif
+
iTab = pSort->iECursor;
if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
regRowid = 0;
regRow = pDest->iSdst;
- nSortData = nColumn;
}else{
regRowid = sqlite3GetTempReg(pParse);
regRow = sqlite3GetTempRange(pParse, nColumn);
- nSortData = nColumn;
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
@@ -119195,7 +124877,8 @@ static void generateSortTail(
if( pSort->labelBkOut ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut,
+ nKey+1+nColumn+nRefKey);
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
@@ -119208,15 +124891,59 @@ static void generateSortTail(
iSortTab = iTab;
bSeq = 1;
}
- for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
- int iRead;
- if( aOutEx[i].u.x.iOrderByCol ){
- iRead = aOutEx[i].u.x.iOrderByCol-1;
- }else{
- iRead = iCol++;
+ for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( aOutEx[i].bSorterRef ) continue;
+#endif
+ if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
+ }
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( pSort->nDefer ){
+ int iKey = iCol+1;
+ int regKey = sqlite3GetTempRange(pParse, nRefKey);
+
+ for(i=0; i<pSort->nDefer; i++){
+ int iCsr = pSort->aDefer[i].iCsr;
+ Table *pTab = pSort->aDefer[i].pTab;
+ int nKey = pSort->aDefer[i].nKey;
+
+ sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr,
+ sqlite3VdbeCurrentAddr(v)+1, regKey);
+ }else{
+ int k;
+ int iJmp;
+ assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey );
+ for(k=0; k<nKey; k++){
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey+k);
+ }
+ iJmp = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp4Int(v, OP_SeekGE, iCsr, iJmp+2, regKey, nKey);
+ sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp+3, regKey, nKey);
+ sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
+ }
+ }
+ sqlite3ReleaseTempRange(pParse, regKey, nRefKey);
+ }
+#endif
+ for(i=nColumn-1; i>=0; i--){
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ if( aOutEx[i].bSorterRef ){
+ sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i);
+ }else
+#endif
+ {
+ int iRead;
+ if( aOutEx[i].u.x.iOrderByCol ){
+ iRead = aOutEx[i].u.x.iOrderByCol-1;
+ }else{
+ iRead = iCol--;
+ }
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
+ VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan));
}
- sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
- VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
switch( eDest ){
case SRT_Table:
@@ -119231,7 +124958,6 @@ static void generateSortTail(
assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
pDest->zAffSdst, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
break;
}
@@ -119246,7 +124972,6 @@ static void generateSortTail(
testcase( eDest==SRT_Coroutine );
if( eDest==SRT_Output ){
sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
}else{
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}
@@ -119323,8 +125048,9 @@ static const char *columnTypeImpl(
assert( pExpr!=0 );
assert( pNC->pSrcList!=0 );
+ assert( pExpr->op!=TK_AGG_COLUMN ); /* This routine runes before aggregates
+ ** are processed */
switch( pExpr->op ){
- case TK_AGG_COLUMN:
case TK_COLUMN: {
/* The expression is a column. Locate the table the column is being
** extracted from in NameContext.pSrcList. This table may be real
@@ -119333,8 +125059,6 @@ static const char *columnTypeImpl(
Table *pTab = 0; /* Table structure column is extracted from */
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
@@ -119535,9 +125259,10 @@ static void generateColumnNames(
}
#endif
- if( pParse->colNamesSet || db->mallocFailed ) return;
+ if( pParse->colNamesSet ) return;
/* Column names are determined by the left-most term of a compound select */
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+ SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
pTabList = pSelect->pSrc;
pEList = pSelect->pEList;
assert( v!=0 );
@@ -119646,12 +125371,12 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
- if( (pColExpr->op==TK_COLUMN || pColExpr->op==TK_AGG_COLUMN)
- && pColExpr->pTab!=0
- ){
+ assert( pColExpr->op!=TK_AGG_COLUMN );
+ if( pColExpr->op==TK_COLUMN ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
Table *pTab = pColExpr->pTab;
+ assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : (char *)"rowid";
}else if( pColExpr->op==TK_ID ){
@@ -119811,7 +125536,7 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
/*
** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
+** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
** are the integer memory register numbers for counters used to compute
@@ -119819,15 +125544,15 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
** iLimit and iOffset are negative.
**
** This routine changes the values of iLimit and iOffset only if
-** a limit or offset is defined by pLimit and pOffset. iLimit and
-** iOffset should have been preset to appropriate default values (zero)
+** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit
+** and iOffset should have been preset to appropriate default values (zero)
** prior to calling this routine.
**
** The iOffset register (if it exists) is initialized to the value
** of the OFFSET. The iLimit register is initialized to LIMIT. Register
** iOffset+1 is initialized to LIMIT+OFFSET.
**
-** Only if pLimit!=0 or pOffset!=0 do the limit registers get
+** Only if pLimit->pLeft!=0 do the limit registers get
** redefined. The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
@@ -119837,6 +125562,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
int iLimit = 0;
int iOffset;
int n;
+ Expr *pLimit = p->pLimit;
+
if( p->iLimit ) return;
/*
@@ -119845,13 +125572,13 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
- sqlite3ExprCacheClear(pParse);
- assert( p->pOffset==0 || p->pLimit!=0 );
- if( p->pLimit ){
+ if( pLimit ){
+ assert( pLimit->op==TK_LIMIT );
+ assert( pLimit->pLeft!=0 );
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- if( sqlite3ExprIsInteger(p->pLimit, &n) ){
+ if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
@@ -119861,15 +125588,15 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
p->selFlags |= SF_FixedLimit;
}
}else{
- sqlite3ExprCode(pParse, p->pLimit, iLimit);
+ sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
}
- if( p->pOffset ){
+ if( pLimit->pRight ){
p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
+ sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
@@ -119999,9 +125726,16 @@ static void generateWithRecursiveQuery(
int i; /* Loop counter */
int rc; /* Result code */
ExprList *pOrderBy; /* The ORDER BY clause */
- Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */
+ Expr *pLimit; /* Saved LIMIT and OFFSET */
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWin ){
+ sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
+ return;
+ }
+#endif
+
/* Obtain authorization to do a recursive query */
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
@@ -120010,10 +125744,9 @@ static void generateWithRecursiveQuery(
p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
- pOffset = p->pOffset;
regLimit = p->iLimit;
regOffset = p->iOffset;
- p->pLimit = p->pOffset = 0;
+ p->pLimit = 0;
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
@@ -120059,6 +125792,7 @@ static void generateWithRecursiveQuery(
/* Store the results of the setup-query in Queue. */
pSetup->pNext = 0;
+ ExplainQueryPlan((pParse, 1, "SETUP"));
rc = sqlite3Select(pParse, pSetup, &destQueue);
pSetup->pNext = p;
if( rc ) goto end_of_recursive_query;
@@ -120093,6 +125827,7 @@ static void generateWithRecursiveQuery(
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
}else{
p->pPrior = 0;
+ ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
sqlite3Select(pParse, p, &destQueue);
assert( p->pPrior==0 );
p->pPrior = pSetup;
@@ -120106,7 +125841,6 @@ end_of_recursive_query:
sqlite3ExprListDelete(pParse->db, p->pOrderBy);
p->pOrderBy = pOrderBy;
p->pLimit = pLimit;
- p->pOffset = pOffset;
return;
}
#endif /* SQLITE_OMIT_CTE */
@@ -120125,36 +125859,38 @@ static int multiSelectOrderBy(
** on a VALUES clause.
**
** Because the Select object originates from a VALUES clause:
-** (1) It has no LIMIT or OFFSET
+** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
** (2) All terms are UNION ALL
** (3) There is no ORDER BY clause
+**
+** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
+** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
+** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
+** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
*/
static int multiSelectValues(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
SelectDest *pDest /* What to do with query results */
){
- Select *pPrior;
int nRow = 1;
int rc = 0;
+ int bShowAll = p->pLimit==0;
assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
- assert( p->pLimit==0 );
- assert( p->pOffset==0 );
assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
if( p->pPrior==0 ) break;
assert( p->pPrior->pNext==p );
p = p->pPrior;
- nRow++;
+ nRow += bShowAll;
}while(1);
+ ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
+ nRow==1 ? "" : "S"));
while( p ){
- pPrior = p->pPrior;
- p->pPrior = 0;
- rc = sqlite3Select(pParse, p, pDest);
- p->pPrior = pPrior;
- if( rc ) break;
+ selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
+ if( !bShowAll ) break;
p->nSelectRow = nRow;
p = p->pNext;
}
@@ -120203,10 +125939,6 @@ static int multiSelect(
SelectDest dest; /* Alternative data destination */
Select *pDelete = 0; /* Chain of simple selects to delete */
sqlite3 *db; /* Database connection */
-#ifndef SQLITE_OMIT_EXPLAIN
- int iSub1 = 0; /* EQP id of left-hand query */
- int iSub2 = 0; /* EQP id of right-hand query */
-#endif
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
@@ -120257,226 +125989,231 @@ static int multiSelect(
*/
if( p->pOrderBy ){
return multiSelectOrderBy(pParse, p, pDest);
- }else
+ }else{
- /* Generate code for the left and right SELECT statements.
- */
- switch( p->op ){
- case TK_ALL: {
- int addr = 0;
- int nLimit;
- assert( !pPrior->pLimit );
- pPrior->iLimit = p->iLimit;
- pPrior->iOffset = p->iOffset;
- pPrior->pLimit = p->pLimit;
- pPrior->pOffset = p->pOffset;
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &dest);
- p->pLimit = 0;
- p->pOffset = 0;
- if( rc ){
- goto multi_select_end;
- }
- p->pPrior = 0;
- p->iLimit = pPrior->iLimit;
- p->iOffset = pPrior->iOffset;
- if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
- VdbeComment((v, "Jump ahead if LIMIT reached"));
- if( p->iOffset ){
- sqlite3VdbeAddOp3(v, OP_OffsetLimit,
- p->iLimit, p->iOffset+1, p->iOffset);
+#ifndef SQLITE_OMIT_EXPLAIN
+ if( pPrior->pPrior==0 ){
+ ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
+ ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
+ }
+#endif
+
+ /* Generate code for the left and right SELECT statements.
+ */
+ switch( p->op ){
+ case TK_ALL: {
+ int addr = 0;
+ int nLimit;
+ assert( !pPrior->pLimit );
+ pPrior->iLimit = p->iLimit;
+ pPrior->iOffset = p->iOffset;
+ pPrior->pLimit = p->pLimit;
+ rc = sqlite3Select(pParse, pPrior, &dest);
+ p->pLimit = 0;
+ if( rc ){
+ goto multi_select_end;
+ }
+ p->pPrior = 0;
+ p->iLimit = pPrior->iLimit;
+ p->iOffset = pPrior->iOffset;
+ if( p->iLimit ){
+ addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+ VdbeComment((v, "Jump ahead if LIMIT reached"));
+ if( p->iOffset ){
+ sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+ p->iLimit, p->iOffset+1, p->iOffset);
+ }
}
+ ExplainQueryPlan((pParse, 1, "UNION ALL"));
+ rc = sqlite3Select(pParse, p, &dest);
+ testcase( rc!=SQLITE_OK );
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ if( pPrior->pLimit
+ && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
+ ){
+ p->nSelectRow = sqlite3LogEst((u64)nLimit);
+ }
+ if( addr ){
+ sqlite3VdbeJumpHere(v, addr);
+ }
+ break;
}
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &dest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
- if( pPrior->pLimit
- && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
- ){
- p->nSelectRow = sqlite3LogEst((u64)nLimit);
- }
- if( addr ){
- sqlite3VdbeJumpHere(v, addr);
- }
- break;
- }
- case TK_EXCEPT:
- case TK_UNION: {
- int unionTab; /* Cursor number of the temporary table holding result */
- u8 op = 0; /* One of the SRT_ operations to apply to self */
- int priorOp; /* The SRT_ operation to apply to prior selects */
- Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
- int addr;
- SelectDest uniondest;
-
- testcase( p->op==TK_EXCEPT );
- testcase( p->op==TK_UNION );
- priorOp = SRT_Union;
- if( dest.eDest==priorOp ){
- /* We can reuse a temporary table generated by a SELECT to our
- ** right.
+ case TK_EXCEPT:
+ case TK_UNION: {
+ int unionTab; /* Cursor number of the temp table holding result */
+ u8 op = 0; /* One of the SRT_ operations to apply to self */
+ int priorOp; /* The SRT_ operation to apply to prior selects */
+ Expr *pLimit; /* Saved values of p->nLimit */
+ int addr;
+ SelectDest uniondest;
+
+ testcase( p->op==TK_EXCEPT );
+ testcase( p->op==TK_UNION );
+ priorOp = SRT_Union;
+ if( dest.eDest==priorOp ){
+ /* We can reuse a temporary table generated by a SELECT to our
+ ** right.
+ */
+ assert( p->pLimit==0 ); /* Not allowed on leftward elements */
+ unionTab = dest.iSDParm;
+ }else{
+ /* We will need to create our own temporary table to hold the
+ ** intermediate results.
+ */
+ unionTab = pParse->nTab++;
+ assert( p->pOrderBy==0 );
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
+ assert( p->addrOpenEphm[0] == -1 );
+ p->addrOpenEphm[0] = addr;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
+ assert( p->pEList );
+ }
+
+ /* Code the SELECT statements to our left
*/
- assert( p->pLimit==0 ); /* Not allowed on leftward elements */
- assert( p->pOffset==0 ); /* Not allowed on leftward elements */
- unionTab = dest.iSDParm;
- }else{
- /* We will need to create our own temporary table to hold the
- ** intermediate results.
+ assert( !pPrior->pOrderBy );
+ sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
+ rc = sqlite3Select(pParse, pPrior, &uniondest);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT statement
+ */
+ if( p->op==TK_EXCEPT ){
+ op = SRT_Except;
+ }else{
+ assert( p->op==TK_UNION );
+ op = SRT_Union;
+ }
+ p->pPrior = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ uniondest.eDest = op;
+ ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
+ selectOpName(p->op)));
+ rc = sqlite3Select(pParse, p, &uniondest);
+ testcase( rc!=SQLITE_OK );
+ /* Query flattening in sqlite3Select() might refill p->pOrderBy.
+ ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ p->pOrderBy = 0;
+ if( p->op==TK_UNION ){
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
+ sqlite3ExprDelete(db, p->pLimit);
+ p->pLimit = pLimit;
+ p->iLimit = 0;
+ p->iOffset = 0;
+
+ /* Convert the data in the temporary table into whatever form
+ ** it is that we currently need.
+ */
+ assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
+ if( dest.eDest!=priorOp ){
+ int iCont, iBreak, iStart;
+ assert( p->pEList );
+ iBreak = sqlite3VdbeMakeLabel(v);
+ iCont = sqlite3VdbeMakeLabel(v);
+ computeLimitRegisters(pParse, p, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
+ iStart = sqlite3VdbeCurrentAddr(v);
+ selectInnerLoop(pParse, p, unionTab,
+ 0, 0, &dest, iCont, iBreak);
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
+ sqlite3VdbeResolveLabel(v, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
+ }
+ break;
+ }
+ default: assert( p->op==TK_INTERSECT ); {
+ int tab1, tab2;
+ int iCont, iBreak, iStart;
+ Expr *pLimit;
+ int addr;
+ SelectDest intersectdest;
+ int r1;
+
+ /* INTERSECT is different from the others since it requires
+ ** two temporary tables. Hence it has its own case. Begin
+ ** by allocating the tables we will need.
*/
- unionTab = pParse->nTab++;
+ tab1 = pParse->nTab++;
+ tab2 = pParse->nTab++;
assert( p->pOrderBy==0 );
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
+
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
- }
-
- /* Code the SELECT statements to our left
- */
- assert( !pPrior->pOrderBy );
- sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &uniondest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT statement
- */
- if( p->op==TK_EXCEPT ){
- op = SRT_Except;
- }else{
- assert( p->op==TK_UNION );
- op = SRT_Union;
- }
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- uniondest.eDest = op;
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &uniondest);
- testcase( rc!=SQLITE_OK );
- /* Query flattening in sqlite3Select() might refill p->pOrderBy.
- ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
- sqlite3ExprListDelete(db, p->pOrderBy);
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- p->pOrderBy = 0;
- if( p->op==TK_UNION ){
- p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
- }
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
- p->iLimit = 0;
- p->iOffset = 0;
-
- /* Convert the data in the temporary table into whatever form
- ** it is that we currently need.
- */
- assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
- if( dest.eDest!=priorOp ){
- int iCont, iBreak, iStart;
+
+ /* Code the SELECTs to our left into temporary table "tab1".
+ */
+ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
+ rc = sqlite3Select(pParse, pPrior, &intersectdest);
+ if( rc ){
+ goto multi_select_end;
+ }
+
+ /* Code the current SELECT into temporary table "tab2"
+ */
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
+ assert( p->addrOpenEphm[1] == -1 );
+ p->addrOpenEphm[1] = addr;
+ p->pPrior = 0;
+ pLimit = p->pLimit;
+ p->pLimit = 0;
+ intersectdest.iSDParm = tab2;
+ ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
+ selectOpName(p->op)));
+ rc = sqlite3Select(pParse, p, &intersectdest);
+ testcase( rc!=SQLITE_OK );
+ pDelete = p->pPrior;
+ p->pPrior = pPrior;
+ if( p->nSelectRow>pPrior->nSelectRow ){
+ p->nSelectRow = pPrior->nSelectRow;
+ }
+ sqlite3ExprDelete(db, p->pLimit);
+ p->pLimit = pLimit;
+
+ /* Generate code to take the intersection of the two temporary
+ ** tables.
+ */
assert( p->pEList );
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
- iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, unionTab,
+ sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
+ r1 = sqlite3GetTempReg(pParse);
+ iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
+ VdbeCoverage(v);
+ sqlite3ReleaseTempReg(pParse, r1);
+ selectInnerLoop(pParse, p, tab1,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
+ break;
}
- break;
}
- default: assert( p->op==TK_INTERSECT ); {
- int tab1, tab2;
- int iCont, iBreak, iStart;
- Expr *pLimit, *pOffset;
- int addr;
- SelectDest intersectdest;
- int r1;
-
- /* INTERSECT is different from the others since it requires
- ** two temporary tables. Hence it has its own case. Begin
- ** by allocating the tables we will need.
- */
- tab1 = pParse->nTab++;
- tab2 = pParse->nTab++;
- assert( p->pOrderBy==0 );
-
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
- assert( p->addrOpenEphm[0] == -1 );
- p->addrOpenEphm[0] = addr;
- findRightmost(p)->selFlags |= SF_UsesEphemeral;
- assert( p->pEList );
-
- /* Code the SELECTs to our left into temporary table "tab1".
- */
- sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &intersectdest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT into temporary table "tab2"
- */
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
- assert( p->addrOpenEphm[1] == -1 );
- p->addrOpenEphm[1] = addr;
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- intersectdest.iSDParm = tab2;
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &intersectdest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
-
- /* Generate code to take the intersection of the two temporary
- ** tables.
- */
- assert( p->pEList );
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
- r1 = sqlite3GetTempReg(pParse);
- iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
- sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
- sqlite3ReleaseTempReg(pParse, r1);
- selectInnerLoop(pParse, p, tab1,
- 0, 0, &dest, iCont, iBreak);
- sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
- sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
- sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
- break;
+
+ #ifndef SQLITE_OMIT_EXPLAIN
+ if( p->pNext==0 ){
+ ExplainQueryPlanPop(pParse);
}
+ #endif
}
-
- explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
-
+
/* Compute collating sequences used by
** temporary tables needed to implement the compound select.
** Attach the KeyInfo structure to all temporary tables.
@@ -120627,7 +126364,6 @@ static int generateOutputSubroutine(
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst,
r1, pDest->zAffSdst, pIn->nSdst);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
pIn->iSdst, pIn->nSdst);
sqlite3ReleaseTempReg(pParse, r1);
@@ -120670,7 +126406,6 @@ static int generateOutputSubroutine(
default: {
assert( pDest->eDest==SRT_Output );
sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
break;
}
}
@@ -120814,10 +126549,6 @@ static int multiSelectOrderBy(
ExprList *pOrderBy; /* The ORDER BY clause */
int nOrderBy; /* Number of terms in the ORDER BY clause */
int *aPermute; /* Mapping from ORDER BY terms to result set columns */
-#ifndef SQLITE_OMIT_EXPLAIN
- int iSub1; /* EQP id of left-hand query */
- int iSub2; /* EQP id of right-hand query */
-#endif
assert( p->pOrderBy!=0 );
assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
@@ -120929,8 +126660,6 @@ static int multiSelectOrderBy(
}
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = 0;
- sqlite3ExprDelete(db, p->pOffset);
- p->pOffset = 0;
regAddrA = ++pParse->nMem;
regAddrB = ++pParse->nMem;
@@ -120939,6 +126668,8 @@ static int multiSelectOrderBy(
sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
+ ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
+
/* Generate a coroutine to evaluate the SELECT statement to the
** left of the compound operator - the "A" select.
*/
@@ -120946,7 +126677,7 @@ static int multiSelectOrderBy(
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
VdbeComment((v, "left SELECT"));
pPrior->iLimit = regLimitA;
- explainSetInteger(iSub1, pParse->iNextSelectId);
+ ExplainQueryPlan((pParse, 1, "LEFT"));
sqlite3Select(pParse, pPrior, &destA);
sqlite3VdbeEndCoroutine(v, regAddrA);
sqlite3VdbeJumpHere(v, addr1);
@@ -120961,7 +126692,7 @@ static int multiSelectOrderBy(
savedOffset = p->iOffset;
p->iLimit = regLimitB;
p->iOffset = 0;
- explainSetInteger(iSub2, pParse->iNextSelectId);
+ ExplainQueryPlan((pParse, 1, "RIGHT"));
sqlite3Select(pParse, p, &destB);
p->iLimit = savedLimit;
p->iOffset = savedOffset;
@@ -121073,7 +126804,7 @@ static int multiSelectOrderBy(
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
- explainComposite(pParse, p->op, iSub1, iSub2, 0);
+ ExplainQueryPlanPop(pParse);
return pParse->nErr!=0;
}
#endif
@@ -121129,7 +126860,7 @@ static Expr *substExpr(
Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
Expr ifNullRow;
assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ assert( pExpr->pRight==0 );
if( sqlite3ExprIsVector(pCopy) ){
sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
}else{
@@ -121320,12 +127051,11 @@ static void substSelect(
** (19) If the subquery uses LIMIT then the outer query may not
** have a WHERE clause.
**
-** (**) Subsumed into (17d3). Was: If the sub-query is a compound select,
-** then it must not use an ORDER BY clause - Ticket #3773. Because
-** of (17d3), then only way to have a compound subquery is if it is
-** the only term in the FROM clause of the outer query. But if the
-** only term in the FROM clause has an ORDER BY, then it will be
-** implemented as a co-routine and the flattener will never be called.
+** (20) If the sub-query is a compound select, then it must not use
+** an ORDER BY clause. Ticket #3773. We could relax this constraint
+** somewhat by saying that the terms of the ORDER BY clause must
+** appear as unmodified result columns in the outer query. But we
+** have other optimizations in mind to deal with that case.
**
** (21) If the subquery uses LIMIT then the outer query may not be
** DISTINCT. (See ticket [752e1646fc]).
@@ -121344,6 +127074,10 @@ static void substSelect(
** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
** return the value X for which Y was maximal.)
**
+** (25) If either the subquery or the parent query contains a window
+** function in the select list or ORDER BY clause, flattening
+** is not attempted.
+**
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
@@ -121387,6 +127121,10 @@ static int flattenSubquery(
pSub = pSubitem->pSelect;
assert( pSub!=0 );
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */
+#endif
+
pSubSrc = pSub->pSrc;
assert( pSubSrc );
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
@@ -121395,7 +127133,7 @@ static int flattenSubquery(
** became arbitrary expressions, we were forced to add restrictions (13)
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
- if( pSub->pOffset ) return 0; /* Restriction (14) */
+ if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */
if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
return 0; /* Restriction (15) */
}
@@ -121459,6 +127197,9 @@ static int flattenSubquery(
** queries.
*/
if( pSub->pPrior ){
+ if( pSub->pOrderBy ){
+ return 0; /* Restriction (20) */
+ }
if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
return 0; /* (17d1), (17d2), or (17d3) */
}
@@ -121493,18 +127234,9 @@ static int flattenSubquery(
*/
assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );
- /* Ex-restriction (20):
- ** A compound subquery must be the only term in the FROM clause of the
- ** outer query by restriction (17d3). But if that term also has an
- ** ORDER BY clause, then the subquery will be implemented by co-routine
- ** and so the flattener will never be invoked. Hence, it is not possible
- ** for the subquery to be a compound and have an ORDER BY clause.
- */
- assert( pSub->pPrior==0 || pSub->pOrderBy==0 );
-
/***** If we reach this point, flattening is permitted. *****/
- SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
- pSub->zSelName, pSub, iFrom));
+ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
+ pSub->selId, pSub, iFrom));
/* Authorize the subquery */
pParse->zAuthContext = pSubitem->zName;
@@ -121549,16 +127281,12 @@ static int flattenSubquery(
Select *pNew;
ExprList *pOrderBy = p->pOrderBy;
Expr *pLimit = p->pLimit;
- Expr *pOffset = p->pOffset;
Select *pPrior = p->pPrior;
p->pOrderBy = 0;
p->pSrc = 0;
p->pPrior = 0;
p->pLimit = 0;
- p->pOffset = 0;
pNew = sqlite3SelectDup(db, p, 0);
- sqlite3SelectSetName(pNew, pSub->zSelName);
- p->pOffset = pOffset;
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
@@ -121570,9 +127298,8 @@ static int flattenSubquery(
if( pPrior ) pPrior->pNext = pNew;
pNew->pNext = p;
p->pPrior = pNew;
- SELECTTRACE(2,pParse,p,
- ("compound-subquery flattener creates %s.%p as peer\n",
- pNew->zSelName, pNew));
+ SELECTTRACE(2,pParse,p,("compound-subquery flattener"
+ " creates %u as peer\n",pNew->selId));
}
if( db->mallocFailed ) return 1;
}
@@ -121706,7 +127433,6 @@ static int flattenSubquery(
pOrderBy->a[i].u.x.iOrderByCol = 0;
}
assert( pParent->pOrderBy==0 );
- assert( pSub->pPrior==0 );
pParent->pOrderBy = pOrderBy;
pSub->pOrderBy = 0;
}
@@ -121758,7 +127484,183 @@ static int flattenSubquery(
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+/*
+** A structure to keep track of all of the column values that are fixed to
+** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
+*/
+typedef struct WhereConst WhereConst;
+struct WhereConst {
+ Parse *pParse; /* Parsing context */
+ int nConst; /* Number for COLUMN=CONSTANT terms */
+ int nChng; /* Number of times a constant is propagated */
+ Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
+};
+
+/*
+** Add a new entry to the pConst object. Except, do not add duplicate
+** pColumn entires.
+*/
+static void constInsert(
+ WhereConst *pConst, /* The WhereConst into which we are inserting */
+ Expr *pColumn, /* The COLUMN part of the constraint */
+ Expr *pValue /* The VALUE part of the constraint */
+){
+ int i;
+ assert( pColumn->op==TK_COLUMN );
+
+ /* 2018-10-25 ticket [cf5ed20f]
+ ** Make sure the same pColumn is not inserted more than once */
+ for(i=0; i<pConst->nConst; i++){
+ const Expr *pExpr = pConst->apExpr[i*2];
+ assert( pExpr->op==TK_COLUMN );
+ if( pExpr->iTable==pColumn->iTable
+ && pExpr->iColumn==pColumn->iColumn
+ ){
+ return; /* Already present. Return without doing anything. */
+ }
+ }
+
+ pConst->nConst++;
+ pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
+ pConst->nConst*2*sizeof(Expr*));
+ if( pConst->apExpr==0 ){
+ pConst->nConst = 0;
+ }else{
+ if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft;
+ pConst->apExpr[pConst->nConst*2-2] = pColumn;
+ pConst->apExpr[pConst->nConst*2-1] = pValue;
+ }
+}
+
+/*
+** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE
+** is a constant expression and where the term must be true because it
+** is part of the AND-connected terms of the expression. For each term
+** found, add it to the pConst structure.
+*/
+static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
+ Expr *pRight, *pLeft;
+ if( pExpr==0 ) return;
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
+ if( pExpr->op==TK_AND ){
+ findConstInWhere(pConst, pExpr->pRight);
+ findConstInWhere(pConst, pExpr->pLeft);
+ return;
+ }
+ if( pExpr->op!=TK_EQ ) return;
+ pRight = pExpr->pRight;
+ pLeft = pExpr->pLeft;
+ assert( pRight!=0 );
+ assert( pLeft!=0 );
+ if( pRight->op==TK_COLUMN
+ && !ExprHasProperty(pRight, EP_FixedCol)
+ && sqlite3ExprIsConstant(pLeft)
+ && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
+ ){
+ constInsert(pConst, pRight, pLeft);
+ }else
+ if( pLeft->op==TK_COLUMN
+ && !ExprHasProperty(pLeft, EP_FixedCol)
+ && sqlite3ExprIsConstant(pRight)
+ && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
+ ){
+ constInsert(pConst, pLeft, pRight);
+ }
+}
+
+/*
+** This is a Walker expression callback. pExpr is a candidate expression
+** to be replaced by a value. If pExpr is equivalent to one of the
+** columns named in pWalker->u.pConst, then overwrite it with its
+** corresponding value.
+*/
+static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
+ int i;
+ WhereConst *pConst;
+ if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
+ if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue;
+ pConst = pWalker->u.pConst;
+ for(i=0; i<pConst->nConst; i++){
+ Expr *pColumn = pConst->apExpr[i*2];
+ if( pColumn==pExpr ) continue;
+ if( pColumn->iTable!=pExpr->iTable ) continue;
+ if( pColumn->iColumn!=pExpr->iColumn ) continue;
+ /* A match is found. Add the EP_FixedCol property */
+ pConst->nChng++;
+ ExprClearProperty(pExpr, EP_Leaf);
+ ExprSetProperty(pExpr, EP_FixedCol);
+ assert( pExpr->pLeft==0 );
+ pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0);
+ break;
+ }
+ return WRC_Prune;
+}
+/*
+** The WHERE-clause constant propagation optimization.
+**
+** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
+** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level
+** AND-connected terms that are not part of a ON clause from a LEFT JOIN)
+** then throughout the query replace all other occurrences of COLUMN
+** with CONSTANT within the WHERE clause.
+**
+** For example, the query:
+**
+** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b
+**
+** Is transformed into
+**
+** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39
+**
+** Return true if any transformations where made and false if not.
+**
+** Implementation note: Constant propagation is tricky due to affinity
+** and collating sequence interactions. Consider this example:
+**
+** CREATE TABLE t1(a INT,b TEXT);
+** INSERT INTO t1 VALUES(123,'0123');
+** SELECT * FROM t1 WHERE a=123 AND b=a;
+** SELECT * FROM t1 WHERE a=123 AND b=123;
+**
+** The two SELECT statements above should return different answers. b=a
+** is alway true because the comparison uses numeric affinity, but b=123
+** is false because it uses text affinity and '0123' is not the same as '123'.
+** To work around this, the expression tree is not actually changed from
+** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol
+** and the "123" value is hung off of the pLeft pointer. Code generator
+** routines know to generate the constant "123" instead of looking up the
+** column value. Also, to avoid collation problems, this optimization is
+** only attempted if the "a=123" term uses the default BINARY collation.
+*/
+static int propagateConstants(
+ Parse *pParse, /* The parsing context */
+ Select *p /* The query in which to propagate constants */
+){
+ WhereConst x;
+ Walker w;
+ int nChng = 0;
+ x.pParse = pParse;
+ do{
+ x.nConst = 0;
+ x.nChng = 0;
+ x.apExpr = 0;
+ findConstInWhere(&x, p->pWhere);
+ if( x.nConst ){
+ memset(&w, 0, sizeof(w));
+ w.pParse = pParse;
+ w.xExprCallback = propagateConstantExprRewrite;
+ w.xSelectCallback = sqlite3SelectWalkNoop;
+ w.xSelectCallback2 = 0;
+ w.walkerDepth = 0;
+ w.u.pConst = &x;
+ sqlite3WalkExpr(&w, p->pWhere);
+ sqlite3DbFree(x.pParse->db, x.apExpr);
+ nChng += x.nChng;
+ }
+ }while( x.nChng );
+ return nChng;
+}
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
@@ -121788,14 +127690,28 @@ static int flattenSubquery(
** (2) The inner query is the recursive part of a common table expression.
**
** (3) The inner query has a LIMIT clause (since the changes to the WHERE
-** close would change the meaning of the LIMIT).
+** clause would change the meaning of the LIMIT).
**
-** (4) The inner query is the right operand of a LEFT JOIN. (The caller
-** enforces this restriction since this routine does not have enough
-** information to know.)
+** (4) The inner query is the right operand of a LEFT JOIN and the
+** expression to be pushed down does not come from the ON clause
+** on that LEFT JOIN.
**
** (5) The WHERE clause expression originates in the ON or USING clause
-** of a LEFT JOIN.
+** of a LEFT JOIN where iCursor is not the right-hand table of that
+** left join. An example:
+**
+** SELECT *
+** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa
+** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
+** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
+**
+** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9).
+** But if the (b2=2) term were to be pushed down into the bb subquery,
+** then the (1,1,NULL) row would be suppressed.
+**
+** (6) The inner query features one or more window-functions (since
+** changes to the WHERE clause of the inner query could change the
+** window over which window functions are calculated).
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
@@ -121804,13 +127720,18 @@ static int pushDownWhereTerms(
Parse *pParse, /* Parse context (for malloc() and error reporting) */
Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
Expr *pWhere, /* The WHERE clause of the outer query */
- int iCursor /* Cursor number of the subquery */
+ int iCursor, /* Cursor number of the subquery */
+ int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */
){
Expr *pNew;
int nChng = 0;
if( pWhere==0 ) return 0;
if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pSubq->pWin ) return 0; /* restriction (6) */
+#endif
+
#ifdef SQLITE_DEBUG
/* Only the first term of a compound can have a WITH clause. But make
** sure no other terms are marked SF_Recursive in case something changes
@@ -121828,15 +127749,25 @@ static int pushDownWhereTerms(
return 0; /* restriction (3) */
}
while( pWhere->op==TK_AND ){
- nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
+ nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight,
+ iCursor, isLeftJoin);
pWhere = pWhere->pLeft;
}
- if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction (5) */
+ if( isLeftJoin
+ && (ExprHasProperty(pWhere,EP_FromJoin)==0
+ || pWhere->iRightJoinTable!=iCursor)
+ ){
+ return 0; /* restriction (4) */
+ }
+ if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
+ return 0; /* restriction (5) */
+ }
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
SubstContext x;
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
+ unsetJoinExpr(pNew, -1);
x.pParse = pParse;
x.iTable = iCursor;
x.iNewTable = iCursor;
@@ -121856,42 +127787,44 @@ static int pushDownWhereTerms(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
-** Based on the contents of the AggInfo structure indicated by the first
-** argument, this function checks if the following are true:
+** The pFunc is the only aggregate function in the query. Check to see
+** if the query is a candidate for the min/max optimization.
**
-** * the query contains just a single aggregate function,
-** * the aggregate function is either min() or max(), and
-** * the argument to the aggregate function is a column value.
+** If the query is a candidate for the min/max optimization, then set
+** *ppMinMax to be an ORDER BY clause to be used for the optimization
+** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
+** whether pFunc is a min() or max() function.
**
-** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
-** is returned as appropriate. Also, *ppMinMax is set to point to the
-** list of arguments passed to the aggregate before returning.
+** If the query is not a candidate for the min/max optimization, return
+** WHERE_ORDERBY_NORMAL (which must be zero).
**
-** Or, if the conditions above are not met, *ppMinMax is set to 0 and
-** WHERE_ORDERBY_NORMAL is returned.
+** This routine must be called after aggregate functions have been
+** located but before their arguments have been subjected to aggregate
+** analysis.
*/
-static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
- int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
-
- *ppMinMax = 0;
- if( pAggInfo->nFunc==1 ){
- Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
- ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
-
- assert( pExpr->op==TK_AGG_FUNCTION );
- if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
- const char *zFunc = pExpr->u.zToken;
- if( sqlite3StrICmp(zFunc, "min")==0 ){
- eRet = WHERE_ORDERBY_MIN;
- *ppMinMax = pEList;
- }else if( sqlite3StrICmp(zFunc, "max")==0 ){
- eRet = WHERE_ORDERBY_MAX;
- *ppMinMax = pEList;
- }
- }
- }
-
- assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
+static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
+ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
+ const char *zFunc; /* Name of aggregate function pFunc */
+ ExprList *pOrderBy;
+ u8 sortOrder;
+
+ assert( *ppMinMax==0 );
+ assert( pFunc->op==TK_AGG_FUNCTION );
+ if( pEList==0 || pEList->nExpr!=1 ) return eRet;
+ zFunc = pFunc->u.zToken;
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
+ eRet = WHERE_ORDERBY_MIN;
+ sortOrder = SQLITE_SO_ASC;
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+ eRet = WHERE_ORDERBY_MAX;
+ sortOrder = SQLITE_SO_DESC;
+ }else{
+ return eRet;
+ }
+ *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
+ assert( pOrderBy!=0 || db->mallocFailed );
+ if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
return eRet;
}
@@ -122022,7 +127955,6 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
assert( pNew->pPrior!=0 );
pNew->pPrior->pNext = pNew;
pNew->pLimit = 0;
- pNew->pOffset = 0;
return WRC_Continue;
}
@@ -122246,6 +128178,35 @@ static void selectPopWith(Walker *pWalker, Select *p){
#endif
/*
+** The SrcList_item structure passed as the second argument represents a
+** sub-query in the FROM clause of a SELECT statement. This function
+** allocates and populates the SrcList_item.pTab object. If successful,
+** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
+** SQLITE_NOMEM.
+*/
+SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
+ Select *pSel = pFrom->pSelect;
+ Table *pTab;
+
+ assert( pSel );
+ pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
+ if( pTab==0 ) return SQLITE_NOMEM;
+ pTab->nTabRef = 1;
+ if( pFrom->zAlias ){
+ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
+ }else{
+ pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId);
+ }
+ while( pSel->pPrior ){ pSel = pSel->pPrior; }
+ sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
+ pTab->iPKey = -1;
+ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+ pTab->tabFlags |= TF_Ephemeral;
+
+ return SQLITE_OK;
+}
+
+/*
** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following:
**
@@ -122278,19 +128239,19 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3 *db = pParse->db;
Expr *pE, *pRight, *pExpr;
u16 selFlags = p->selFlags;
+ u32 elistFlags = 0;
p->selFlags |= SF_Expanded;
if( db->mallocFailed ){
return WRC_Abort;
}
- if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
+ assert( p->pSrc!=0 );
+ if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
pTabList = p->pSrc;
pEList = p->pEList;
- if( OK_IF_ALWAYS_TRUE(p->pWith) ){
- sqlite3WithPush(pParse, p->pWith, 0);
- }
+ sqlite3WithPush(pParse, p->pWith, 0);
/* Make sure cursor numbers have been assigned to all entries in
** the FROM clause of the SELECT statement.
@@ -122317,19 +128278,7 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pSel!=0 );
assert( pFrom->pTab==0 );
if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
- pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTab==0 ) return WRC_Abort;
- pTab->nTabRef = 1;
- if( pFrom->zAlias ){
- pTab->zName = sqlite3DbStrDup(db, pFrom->zAlias);
- }else{
- pTab->zName = sqlite3MPrintf(db, "subquery_%p", (void*)pTab);
- }
- while( pSel->pPrior ){ pSel = pSel->pPrior; }
- sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
- pTab->iPKey = -1;
- pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
- pTab->tabFlags |= TF_Ephemeral;
+ if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
#endif
}else{
/* An ordinary table or view name in the FROM clause */
@@ -122352,7 +128301,6 @@ static int selectExpander(Walker *pWalker, Select *p){
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
- sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
nCol = pTab->nCol;
pTab->nCol = -1;
sqlite3WalkSelect(pWalker, pFrom->pSelect);
@@ -122390,6 +128338,7 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pE->op!=TK_DOT || pE->pRight!=0 );
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
+ elistFlags |= pE->flags;
}
if( k<pEList->nExpr ){
/*
@@ -122405,6 +128354,7 @@ static int selectExpander(Walker *pWalker, Select *p){
for(k=0; k<pEList->nExpr; k++){
pE = a[k].pExpr;
+ elistFlags |= pE->flags;
pRight = pE->pRight;
assert( pE->op!=TK_DOT || pRight!=0 );
if( pE->op!=TK_ASTERISK
@@ -122534,9 +128484,14 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3ExprListDelete(db, pEList);
p->pEList = pNew;
}
- if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns in result set");
- return WRC_Abort;
+ if( p->pEList ){
+ if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+ sqlite3ErrorMsg(pParse, "too many columns in result set");
+ return WRC_Abort;
+ }
+ if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
+ p->selFlags |= SF_ComplexResult;
+ }
}
return WRC_Continue;
}
@@ -122623,7 +128578,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
struct SrcList_item *pFrom;
assert( p->selFlags & SF_Resolved );
- assert( (p->selFlags & SF_HasTypeInfo)==0 );
+ if( p->selFlags & SF_HasTypeInfo ) return;
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
pTabList = p->pSrc;
@@ -122726,7 +128681,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
"argument");
pFunc->iDistinct = -1;
}else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO);
}
@@ -122750,11 +128705,17 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
}
}
+
/*
** Update the accumulator memory cells for an aggregate based on
** the current cursor position.
+**
+** If regAcc is non-zero and there are no min() or max() aggregates
+** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator
+** registers i register regAcc contains 0. The caller will take care
+** of setting and clearing regAcc.
*/
-static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
+static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
int regHit = 0;
@@ -122797,36 +128758,24 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
}
- sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
+ sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
- sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
- sqlite3ExprCacheClear(pParse);
}
}
-
- /* Before populating the accumulator registers, clear the column cache.
- ** Otherwise, if any of the required column values are already present
- ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
- ** to pC->iMem. But by the time the value is used, the original register
- ** may have been used, invalidating the underlying buffer holding the
- ** text or blob value. See ticket [883034dcb5].
- **
- ** Another solution would be to change the OP_SCopy used to copy cached
- ** values to an OP_Copy.
- */
+ if( regHit==0 && pAggInfo->nAccumulator ){
+ regHit = regAcc;
+ }
if( regHit ){
addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
}
- sqlite3ExprCacheClear(pParse);
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
}
pAggInfo->directMode = 0;
- sqlite3ExprCacheClear(pParse);
if( addrHitTest ){
sqlite3VdbeJumpHere(v, addrHitTest);
}
@@ -122844,14 +128793,11 @@ static void explainSimpleCount(
){
if( pParse->explain==2 ){
int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
- char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
+ sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
pTab->zName,
bCover ? " USING COVERING INDEX " : "",
bCover ? pIdx->zName : ""
);
- sqlite3VdbeAddOp4(
- pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
- );
}
}
#else
@@ -122859,14 +128805,6 @@ static void explainSimpleCount(
#endif
/*
-** Context object for havingToWhereExprCb().
-*/
-struct HavingToWhereCtx {
- Expr **ppWhere;
- ExprList *pGroupBy;
-};
-
-/*
** sqlite3WalkExpr() callback used by havingToWhere().
**
** If the node passed to the callback is a TK_AND node, return
@@ -122879,15 +128817,16 @@ struct HavingToWhereCtx {
*/
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op!=TK_AND ){
- struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
- if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
+ Select *pS = pWalker->u.pSelect;
+ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
sqlite3 *db = pWalker->pParse->db;
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
if( pNew ){
- Expr *pWhere = *(p->ppWhere);
+ Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr);
pNew = sqlite3ExprAnd(db, pWhere, pNew);
- *(p->ppWhere) = pNew;
+ pS->pWhere = pNew;
+ pWalker->eCode = 1;
}
}
return WRC_Prune;
@@ -122910,23 +128849,19 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
** entirely of constants and expressions that are also GROUP BY terms that
** use the "BINARY" collation sequence.
*/
-static void havingToWhere(
- Parse *pParse,
- ExprList *pGroupBy,
- Expr *pHaving,
- Expr **ppWhere
-){
- struct HavingToWhereCtx sCtx;
+static void havingToWhere(Parse *pParse, Select *p){
Walker sWalker;
-
- sCtx.ppWhere = ppWhere;
- sCtx.pGroupBy = pGroupBy;
-
memset(&sWalker, 0, sizeof(sWalker));
sWalker.pParse = pParse;
sWalker.xExprCallback = havingToWhereExprCb;
- sWalker.u.pHavingCtx = &sCtx;
- sqlite3WalkExpr(&sWalker, pHaving);
+ sWalker.u.pSelect = p;
+ sqlite3WalkExpr(&sWalker, p->pHaving);
+#if SELECTTRACE_ENABLED
+ if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
+ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
}
/*
@@ -122970,6 +128905,7 @@ static struct SrcList_item *isSelfJoinView(
** The transformation only works if all of the following are true:
**
** * The subquery is a UNION ALL of two or more terms
+** * The subquery does not have a LIMIT clause
** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
** * The outer query is a simple count(*)
**
@@ -122993,6 +128929,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
do{
if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
if( pSub->pWhere ) return 0; /* No WHERE clause */
+ if( pSub->pLimit ) return 0; /* No LIMIT clause */
if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
pSub = pSub->pPrior; /* Repeat over compound */
}while( pSub );
@@ -123072,21 +129009,18 @@ SQLITE_PRIVATE int sqlite3Select(
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
-
-#ifndef SQLITE_OMIT_EXPLAIN
- int iRestoreSelectId = pParse->iSelectId;
- pParse->iSelectId = pParse->iNextSelectId++;
-#endif
+ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
+ u8 minMaxFlag; /* Flag for min/max queries */
db = pParse->db;
+ v = sqlite3GetVdbe(pParse);
if( p==0 || db->mallocFailed || pParse->nErr ){
return 1;
}
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
#if SELECTTRACE_ENABLED
- pParse->nSelectIndent++;
- SELECTTRACE(1,pParse,p, ("begin processing:\n"));
+ SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
if( sqlite3SelectTrace & 0x100 ){
sqlite3TreeViewSelect(0, p, 0);
}
@@ -123108,36 +129042,60 @@ SQLITE_PRIVATE int sqlite3Select(
p->selFlags &= ~SF_Distinct;
}
sqlite3SelectPrep(pParse, p, 0);
- memset(&sSort, 0, sizeof(sSort));
- sSort.pOrderBy = p->pOrderBy;
- pTabList = p->pSrc;
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
assert( p->pEList!=0 );
- isAgg = (p->selFlags & SF_Aggregate)!=0;
#if SELECTTRACE_ENABLED
- if( sqlite3SelectTrace & 0x100 ){
- SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
+ if( sqlite3SelectTrace & 0x104 ){
+ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
- /* Get a pointer the VDBE under construction, allocating a new VDBE if one
- ** does not already exist */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto select_end;
if( pDest->eDest==SRT_Output ){
generateColumnNames(pParse, p);
}
- /* Try to flatten subqueries in the FROM clause up into the main query
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( sqlite3WindowRewrite(pParse, p) ){
+ goto select_end;
+ }
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x108 ){
+ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+ pTabList = p->pSrc;
+ isAgg = (p->selFlags & SF_Aggregate)!=0;
+ memset(&sSort, 0, sizeof(sSort));
+ sSort.pOrderBy = p->pOrderBy;
+
+ /* Try to various optimizations (flattening subqueries, and strength
+ ** reduction of join operators) in the FROM clause up into the main query
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
Select *pSub = pItem->pSelect;
Table *pTab = pItem->pTab;
+
+ /* Convert LEFT JOIN into JOIN if there are terms of the right table
+ ** of the LEFT JOIN used in the WHERE clause.
+ */
+ if( (pItem->fg.jointype & JT_LEFT)!=0
+ && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
+ && OptimizationEnabled(db, SQLITE_SimplifyJoin)
+ ){
+ SELECTTRACE(0x100,pParse,p,
+ ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
+ pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
+ unsetJoinExpr(p->pWhere, pItem->iCursor);
+ }
+
+ /* No futher action if this term of the FROM clause is no a subquery */
if( pSub==0 ) continue;
/* Catch mismatch in the declared columns of a view and the number of
@@ -123158,7 +129116,9 @@ SQLITE_PRIVATE int sqlite3Select(
if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
assert( pSub->pGroupBy==0 );
- /* If the subquery contains an ORDER BY clause and if
+ /* If the outer query contains a "complex" result set (that is,
+ ** if the result set of the outer query uses functions or subqueries)
+ ** and if the subquery contains an ORDER BY clause and if
** it will be implemented as a co-routine, then do not flatten. This
** restriction allows SQL constructs like this:
**
@@ -123167,9 +129127,16 @@ SQLITE_PRIVATE int sqlite3Select(
**
** The expensive_function() is only computed on the 10 rows that
** are output, rather than every row of the table.
+ **
+ ** The requirement that the outer query have a complex result set
+ ** means that flattening does occur on simpler SQL constraints without
+ ** the expensive_function() like:
+ **
+ ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
*/
if( pSub->pOrderBy!=0
&& i==0
+ && (p->selFlags & SF_ComplexResult)!=0
&& (pTabList->nSrc==1
|| (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
){
@@ -123194,15 +129161,46 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( p->pPrior ){
rc = multiSelect(pParse, p, pDest);
- explainSetInteger(pParse->iSelectId, iRestoreSelectId);
#if SELECTTRACE_ENABLED
- SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
- pParse->nSelectIndent--;
+ SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
+ if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+ sqlite3TreeViewSelect(0, p, 0);
+ }
#endif
+ if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
return rc;
}
#endif
+ /* Do the WHERE-clause constant propagation optimization if this is
+ ** a join. No need to speed time on this operation for non-join queries
+ ** as the equivalent optimization will be handled by query planner in
+ ** sqlite3WhereBegin().
+ */
+ if( pTabList->nSrc>1
+ && OptimizationEnabled(db, SQLITE_PropagateConst)
+ && propagateConstants(pParse, p)
+ ){
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x100 ){
+ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ }
+#endif
+ }else{
+ SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
+ }
+
+#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
+ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
+ && countOfViewOptimization(pParse, p)
+ ){
+ if( db->mallocFailed ) goto select_end;
+ pEList = p->pEList;
+ pTabList = p->pSrc;
+ }
+#endif
+
/* For each term in the FROM clause, do two things:
** (1) Authorized unreferenced tables
** (2) Generate code for all sub-queries
@@ -123270,15 +129268,19 @@ SQLITE_PRIVATE int sqlite3Select(
/* Make copies of constant WHERE-clause terms in the outer query down
** inside the subquery. This can help the subquery to run more efficiently.
*/
- if( (pItem->fg.jointype & JT_OUTER)==0
- && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
+ if( OptimizationEnabled(db, SQLITE_PushDown)
+ && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
+ (pItem->fg.jointype & JT_OUTER)!=0)
){
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){
- SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
+ SELECTTRACE(0x100,pParse,p,
+ ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
+ }else{
+ SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
}
zSavedAuthContext = pParse->zAuthContext;
@@ -123307,7 +129309,7 @@ SQLITE_PRIVATE int sqlite3Select(
VdbeComment((v, "%s", pItem->pTab->zName));
pItem->addrFillSub = addrTop;
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId));
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
@@ -123342,12 +129344,11 @@ SQLITE_PRIVATE int sqlite3Select(
pPrior = isSelfJoinView(pTabList, pItem);
if( pPrior ){
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
- explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
assert( pPrior->pSelect!=0 );
pSub->nSelectRow = pPrior->pSelect->nSelectRow;
}else{
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+ ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId));
sqlite3Select(pParse, pSub, &dest);
}
pItem->pTab->nRowLogEst = pSub->nSelectRow;
@@ -123378,16 +129379,6 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
-#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
- if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
- && countOfViewOptimization(pParse, p)
- ){
- if( db->mallocFailed ) goto select_end;
- pEList = p->pEList;
- pTabList = p->pSrc;
- }
-#endif
-
/* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
** if the select-list is the same as the ORDER BY list, then this query
** can be rewritten as a GROUP BY. In other words, this:
@@ -123431,7 +129422,8 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( sSort.pOrderBy ){
KeyInfo *pKeyInfo;
- pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
+ pKeyInfo = sqlite3KeyInfoFromExprList(
+ pParse, sSort.pOrderBy, 0, pEList->nExpr);
sSort.iECursor = pParse->nTab++;
sSort.addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -123465,9 +129457,9 @@ SQLITE_PRIVATE int sqlite3Select(
if( p->selFlags & SF_Distinct ){
sDistinct.tabTnct = pParse->nTab++;
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- sDistinct.tabTnct, 0, 0,
- (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
- P4_KEYINFO);
+ sDistinct.tabTnct, 0, 0,
+ (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0),
+ P4_KEYINFO);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
@@ -123476,11 +129468,19 @@ SQLITE_PRIVATE int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
- u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
+ | (p->selFlags & SF_FixedLimit);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ Window *pWin = p->pWin; /* Master window object (or NULL) */
+ if( pWin ){
+ sqlite3WindowCodeInit(pParse, pWin);
+ }
+#endif
assert( WHERE_USE_LIMIT==SF_FixedLimit );
- wctrlFlags |= p->selFlags & SF_FixedLimit;
+
/* Begin the database scan. */
+ SELECTTRACE(1,pParse,p,("WhereBegin\n"));
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
p->pEList, wctrlFlags, p->nSelectRow);
if( pWInfo==0 ) goto select_end;
@@ -123492,7 +129492,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( sSort.pOrderBy ){
sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
- sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
+ sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
sSort.pOrderBy = 0;
}
@@ -123506,15 +129506,37 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
}
- /* Use the standard inner loop. */
assert( p->pEList==pEList );
- selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
- sqlite3WhereContinueLabel(pWInfo),
- sqlite3WhereBreakLabel(pWInfo));
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( pWin ){
+ int addrGosub = sqlite3VdbeMakeLabel(v);
+ int iCont = sqlite3VdbeMakeLabel(v);
+ int iBreak = sqlite3VdbeMakeLabel(v);
+ int regGosub = ++pParse->nMem;
+
+ sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
+
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
+ sqlite3VdbeResolveLabel(v, addrGosub);
+ VdbeNoopComment((v, "inner-loop subroutine"));
+ sSort.labelOBLopt = 0;
+ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak);
+ sqlite3VdbeResolveLabel(v, iCont);
+ sqlite3VdbeAddOp1(v, OP_Return, regGosub);
+ VdbeComment((v, "end inner-loop subroutine"));
+ sqlite3VdbeResolveLabel(v, iBreak);
+ }else
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+ {
+ /* Use the standard inner loop. */
+ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
+ sqlite3WhereContinueLabel(pWInfo),
+ sqlite3WhereBreakLabel(pWInfo));
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+ }
}else{
/* This case when there exist aggregate functions or a GROUP BY clause
** or both */
@@ -123573,7 +129595,8 @@ SQLITE_PRIVATE int sqlite3Select(
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
- sNC.pAggInfo = &sAggInfo;
+ sNC.uNC.pAggInfo = &sAggInfo;
+ VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
@@ -123582,12 +129605,19 @@ SQLITE_PRIVATE int sqlite3Select(
if( pHaving ){
if( pGroupBy ){
assert( pWhere==p->pWhere );
- havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
+ assert( pHaving==p->pHaving );
+ assert( pGroupBy==p->pGroupBy );
+ havingToWhere(pParse, p);
pWhere = p->pWhere;
}
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
+ if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){
+ minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy);
+ }else{
+ minMaxFlag = WHERE_ORDERBY_NORMAL;
+ }
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
@@ -123596,6 +129626,24 @@ SQLITE_PRIVATE int sqlite3Select(
}
sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x400 ){
+ int ii;
+ SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ for(ii=0; ii<sAggInfo.nColumn; ii++){
+ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
+ ii, sAggInfo.aCol[ii].iMem);
+ sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
+ }
+ for(ii=0; ii<sAggInfo.nFunc; ii++){
+ sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
+ ii, sAggInfo.aFunc[ii].iMem);
+ sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0);
+ }
+ }
+#endif
+
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
@@ -123617,7 +129665,7 @@ SQLITE_PRIVATE int sqlite3Select(
** will be converted into a Noop.
*/
sAggInfo.sortingIdx = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
+ pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
0, (char*)pKeyInfo, P4_KEYINFO);
@@ -123636,8 +129684,6 @@ SQLITE_PRIVATE int sqlite3Select(
pParse->nMem += pGroupBy->nExpr;
sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
VdbeComment((v, "clear abort flag"));
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
- VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
/* Begin a loop that will extract all source rows in GROUP BY order.
@@ -123646,6 +129692,7 @@ SQLITE_PRIVATE int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
+ SELECTTRACE(1,pParse,p,("WhereBegin\n"));
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
);
@@ -123682,15 +129729,14 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
regBase = sqlite3GetTempRange(pParse, nCol);
- sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
int r1 = j + regBase;
- sqlite3ExprCodeGetColumnToReg(pParse,
- pCol->pTab, pCol->iColumn, pCol->iTable, r1);
+ sqlite3ExprCodeGetColumnOfTable(v,
+ pCol->pTab, pCol->iTable, pCol->iColumn, r1);
j++;
}
}
@@ -123706,8 +129752,6 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
sAggInfo.useSortingIdx = 1;
- sqlite3ExprCacheClear(pParse);
-
}
/* If the index or temporary table used by the GROUP BY sort
@@ -123730,7 +129774,6 @@ SQLITE_PRIVATE int sqlite3Select(
** from the previous row currently stored in a0, a1, a2...
*/
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3ExprCacheClear(pParse);
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
sortOut, sortPTab);
@@ -123769,7 +129812,7 @@ SQLITE_PRIVATE int sqlite3Select(
** the current row
*/
sqlite3VdbeJumpHere(v, addr1);
- updateAccumulator(pParse, &sAggInfo);
+ updateAccumulator(pParse, iUseFlag, &sAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
@@ -123821,11 +129864,12 @@ SQLITE_PRIVATE int sqlite3Select(
*/
sqlite3VdbeResolveLabel(v, addrReset);
resetAccumulator(pParse, &sAggInfo);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
+ VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp1(v, OP_Return, regReset);
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
- ExprList *pDel = 0;
#ifndef SQLITE_OMIT_BTREECOUNT
Table *pTab;
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
@@ -123887,67 +129931,50 @@ SQLITE_PRIVATE int sqlite3Select(
}else
#endif /* SQLITE_OMIT_BTREECOUNT */
{
- /* Check if the query is of one of the following forms:
- **
- ** SELECT min(x) FROM ...
- ** SELECT max(x) FROM ...
- **
- ** If it is, then ask the code in where.c to attempt to sort results
- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
- ** If where.c is able to produce results sorted in this order, then
- ** add vdbe code to break out of the processing loop after the
- ** first iteration (since the first iteration of the loop is
- ** guaranteed to operate on the row with the minimum or maximum
- ** value of x, the only row required).
- **
- ** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behavior as follows:
- **
- ** + If the query is a "SELECT min(x)", then the loop coded by
- ** where.c should not iterate over any values with a NULL value
- ** for x.
- **
- ** + The optimizer code in where.c (the thing that decides which
- ** index or indices to use) should place a different priority on
- ** satisfying the 'ORDER BY' clause than it does in other cases.
- ** Refer to code and comments in where.c for details.
- */
- ExprList *pMinMax = 0;
- u8 flag = WHERE_ORDERBY_NORMAL;
-
- assert( p->pGroupBy==0 );
- assert( flag==0 );
- if( p->pHaving==0 ){
- flag = minMaxQuery(&sAggInfo, &pMinMax);
- }
- assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
-
- if( flag ){
- pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
- pDel = pMinMax;
- assert( db->mallocFailed || pMinMax!=0 );
- if( !db->mallocFailed ){
- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
- pMinMax->a[0].pExpr->op = TK_COLUMN;
+ int regAcc = 0; /* "populate accumulators" flag */
+
+ /* If there are accumulator registers but no min() or max() functions,
+ ** allocate register regAcc. Register regAcc will contain 0 the first
+ ** time the inner loop runs, and 1 thereafter. The code generated
+ ** by updateAccumulator() only updates the accumulator registers if
+ ** regAcc contains 0. */
+ if( sAggInfo.nAccumulator ){
+ for(i=0; i<sAggInfo.nFunc; i++){
+ if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
+ }
+ if( i==sAggInfo.nFunc ){
+ regAcc = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
}
}
-
+
/* This case runs if the aggregate has no GROUP BY clause. The
** processing is much simpler since there is only a single row
** of output.
*/
+ assert( p->pGroupBy==0 );
resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
+
+ /* If this query is a candidate for the min/max optimization, then
+ ** minMaxFlag will have been previously set to either
+ ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
+ ** be an appropriate ORDER BY expression for the optimization.
+ */
+ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
+ assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
+
+ SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
+ 0, minMaxFlag, 0);
if( pWInfo==0 ){
- sqlite3ExprListDelete(db, pDel);
goto select_end;
}
- updateAccumulator(pParse, &sAggInfo);
- assert( pMinMax==0 || pMinMax->nExpr==1 );
+ updateAccumulator(pParse, regAcc, &sAggInfo);
+ if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
if( sqlite3WhereIsOrdered(pWInfo)>0 ){
sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index",
- (flag==WHERE_ORDERBY_MIN?"min":"max")));
+ (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max")));
}
sqlite3WhereEnd(pWInfo);
finalizeAggFunctions(pParse, &sAggInfo);
@@ -123957,7 +129984,6 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, -1, 0, 0,
pDest, addrEnd, addrEnd);
- sqlite3ExprListDelete(db, pDel);
}
sqlite3VdbeResolveLabel(v, addrEnd);
@@ -123973,6 +129999,7 @@ SQLITE_PRIVATE int sqlite3Select(
if( sSort.pOrderBy ){
explainTempTable(pParse,
sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
+ assert( p->pEList==pEList );
generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
}
@@ -123988,14 +130015,16 @@ SQLITE_PRIVATE int sqlite3Select(
** successful coding of the SELECT.
*/
select_end:
- explainSetInteger(pParse->iSelectId, iRestoreSelectId);
-
+ sqlite3ExprListDelete(db, pMinMaxOrderBy);
sqlite3DbFree(db, sAggInfo.aCol);
sqlite3DbFree(db, sAggInfo.aFunc);
#if SELECTTRACE_ENABLED
- SELECTTRACE(1,pParse,p,("end processing\n"));
- pParse->nSelectIndent--;
+ SELECTTRACE(0x1,pParse,p,("end processing\n"));
+ if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+ sqlite3TreeViewSelect(0, p, 0);
+ }
#endif
+ ExplainQueryPlanPop(pParse);
return rc;
}
@@ -124229,6 +130258,8 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS
sqlite3ExprListDelete(db, pTmp->pExprList);
sqlite3SelectDelete(db, pTmp->pSelect);
sqlite3IdListDelete(db, pTmp->pIdList);
+ sqlite3UpsertDelete(db, pTmp->pUpsert);
+ sqlite3DbFree(db, pTmp->zSpan);
sqlite3DbFree(db, pTmp);
}
@@ -124383,14 +130414,16 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
goto trigger_cleanup;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
- }else{
- assert( !db->init.busy );
- sqlite3CodeVerifySchema(pParse, iDb);
+ if( !IN_RENAME_OBJECT ){
+ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
+ if( !noErr ){
+ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+ }else{
+ assert( !db->init.busy );
+ sqlite3CodeVerifySchema(pParse, iDb);
+ }
+ goto trigger_cleanup;
}
- goto trigger_cleanup;
}
/* Do not create a trigger on a system table */
@@ -124414,7 +130447,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
}
#ifndef SQLITE_OMIT_AUTHORIZATION
- {
+ if( !IN_RENAME_OBJECT ){
int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int code = SQLITE_CREATE_TRIGGER;
const char *zDb = db->aDb[iTabDb].zDbSName;
@@ -124448,8 +130481,15 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
pTrigger->pTabSchema = pTab->pSchema;
pTrigger->op = (u8)op;
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
- pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
- pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName);
+ pTrigger->pWhen = pWhen;
+ pWhen = 0;
+ }else{
+ pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+ }
+ pTrigger->pColumns = pColumns;
+ pColumns = 0;
assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger;
@@ -124498,6 +130538,14 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
goto triggerfinish_cleanup;
}
+#ifndef SQLITE_OMIT_ALTERTABLE
+ if( IN_RENAME_OBJECT ){
+ assert( !db->init.busy );
+ pParse->pNewTrigger = pTrig;
+ pTrig = 0;
+ }else
+#endif
+
/* if we are not initializing,
** build the sqlite_master entry
*/
@@ -124539,18 +130587,34 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
triggerfinish_cleanup:
sqlite3DeleteTrigger(db, pTrig);
- assert( !pParse->pNewTrigger );
+ assert( IN_RENAME_OBJECT || !pParse->pNewTrigger );
sqlite3DeleteTriggerStep(db, pStepList);
}
/*
+** Duplicate a range of text from an SQL statement, then convert all
+** whitespace characters into ordinary space characters.
+*/
+static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ char *z = sqlite3DbSpanDup(db, zStart, zEnd);
+ int i;
+ if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
+ return z;
+}
+
+/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step. Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.
*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
+ sqlite3 *db, /* Database connection */
+ Select *pSelect, /* The SELECT statement */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
+){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ) {
sqlite3SelectDelete(db, pSelect);
@@ -124559,6 +130623,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
return pTriggerStep;
}
@@ -124569,10 +130634,13 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec
** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
*/
static TriggerStep *triggerStepAllocate(
- sqlite3 *db, /* Database connection */
+ Parse *pParse, /* Parser context */
u8 op, /* Trigger opcode */
- Token *pName /* The target name */
+ Token *pName, /* The target name */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
+ sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
@@ -124582,6 +130650,10 @@ static TriggerStep *triggerStepAllocate(
sqlite3Dequote(z);
pTriggerStep->zTarget = z;
pTriggerStep->op = op;
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName);
+ }
}
return pTriggerStep;
}
@@ -124594,23 +130666,36 @@ static TriggerStep *triggerStepAllocate(
** body of a trigger.
*/
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
- sqlite3 *db, /* The database connection */
+ Parse *pParse, /* Parser */
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
Select *pSelect, /* A SELECT statement that supplies values */
- u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+ u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+ Upsert *pUpsert, /* ON CONFLICT clauses for upsert */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
+ sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
assert(pSelect != 0 || db->mallocFailed);
- pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
+ pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd);
if( pTriggerStep ){
- pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ if( IN_RENAME_OBJECT ){
+ pTriggerStep->pSelect = pSelect;
+ pSelect = 0;
+ }else{
+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
+ }
pTriggerStep->pIdList = pColumn;
+ pTriggerStep->pUpsert = pUpsert;
pTriggerStep->orconf = orconf;
}else{
+ testcase( pColumn );
sqlite3IdListDelete(db, pColumn);
+ testcase( pUpsert );
+ sqlite3UpsertDelete(db, pUpsert);
}
sqlite3SelectDelete(db, pSelect);
@@ -124623,18 +130708,28 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
** sees an UPDATE statement inside the body of a CREATE TRIGGER.
*/
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
- sqlite3 *db, /* The database connection */
+ Parse *pParse, /* Parser */
Token *pTableName, /* Name of the table to be updated */
ExprList *pEList, /* The SET clause: list of column and new values */
Expr *pWhere, /* The WHERE clause */
- u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+ u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
+ sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
- pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
+ pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd);
if( pTriggerStep ){
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ if( IN_RENAME_OBJECT ){
+ pTriggerStep->pExprList = pEList;
+ pTriggerStep->pWhere = pWhere;
+ pEList = 0;
+ pWhere = 0;
+ }else{
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ }
pTriggerStep->orconf = orconf;
}
sqlite3ExprListDelete(db, pEList);
@@ -124648,15 +130743,23 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
** sees a DELETE statement inside the body of a CREATE TRIGGER.
*/
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
- sqlite3 *db, /* Database connection */
+ Parse *pParse, /* Parser */
Token *pTableName, /* The table from which rows are deleted */
- Expr *pWhere /* The WHERE clause */
+ Expr *pWhere, /* The WHERE clause */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
+ sqlite3 *db = pParse->db;
TriggerStep *pTriggerStep;
- pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
+ pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd);
if( pTriggerStep ){
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ if( IN_RENAME_OBJECT ){
+ pTriggerStep->pWhere = pWhere;
+ pWhere = 0;
+ }else{
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ }
pTriggerStep->orconf = OE_Default;
}
sqlite3ExprDelete(db, pWhere);
@@ -124909,13 +131012,21 @@ static int codeTriggerProgram(
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
assert( pParse->okConstFactor==0 );
+#ifndef SQLITE_OMIT_TRACE
+ if( pStep->zSpan ){
+ sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
+ sqlite3MPrintf(db, "-- %s", pStep->zSpan),
+ P4_DYNAMIC);
+ }
+#endif
+
switch( pStep->op ){
case TK_UPDATE: {
sqlite3Update(pParse,
targetSrcList(pParse, pStep),
sqlite3ExprListDup(db, pStep->pExprList, 0),
sqlite3ExprDup(db, pStep->pWhere, 0),
- pParse->eOrconf
+ pParse->eOrconf, 0, 0, 0
);
break;
}
@@ -124924,14 +131035,15 @@ static int codeTriggerProgram(
targetSrcList(pParse, pStep),
sqlite3SelectDup(db, pStep->pSelect, 0),
sqlite3IdListDup(db, pStep->pIdList),
- pParse->eOrconf
+ pParse->eOrconf,
+ sqlite3UpsertDup(db, pStep->pUpsert)
);
break;
}
case TK_DELETE: {
sqlite3DeleteFrom(pParse,
targetSrcList(pParse, pStep),
- sqlite3ExprDup(db, pStep->pWhere, 0)
+ sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
);
break;
}
@@ -125049,9 +131161,11 @@ static TriggerPrg *codeRowTrigger(
pTab->zName
));
#ifndef SQLITE_OMIT_TRACE
- sqlite3VdbeChangeP4(v, -1,
- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
- );
+ if( pTrigger->zName ){
+ sqlite3VdbeChangeP4(v, -1,
+ sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
+ );
+ }
#endif
/* If one was specified, code the WHEN clause. If it evaluates to false
@@ -125079,7 +131193,7 @@ static TriggerPrg *codeRowTrigger(
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
transferParseError(pParse, pSubParse);
- if( db->mallocFailed==0 ){
+ if( db->mallocFailed==0 && pParse->nErr==0 ){
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
}
pProgram->nMem = pSubParse->nMem;
@@ -125387,6 +131501,57 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
}
/*
+** Check to see if column iCol of index pIdx references any of the
+** columns defined by aXRef and chngRowid. Return true if it does
+** and false if not. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexColumnIsBeingUpdated(
+ Index *pIdx, /* The index to check */
+ int iCol, /* Which column of the index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ i16 iIdxCol = pIdx->aiColumn[iCol];
+ assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
+ if( iIdxCol>=0 ){
+ return aXRef[iIdxCol]>=0;
+ }
+ assert( iIdxCol==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
+ aXRef,chngRowid);
+}
+
+/*
+** Check to see if index pIdx is a partial index whose conditional
+** expression might change values due to an UPDATE. Return true if
+** the index is subject to change and false if the index is guaranteed
+** to be unchanged. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexWhereClauseMightChange(
+ Index *pIdx, /* The index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ if( pIdx->pPartIdxWhere==0 ) return 0;
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
+ aXRef, chngRowid);
+}
+
+/*
** Process an UPDATE statement.
**
** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -125398,7 +131563,10 @@ SQLITE_PRIVATE void sqlite3Update(
SrcList *pTabList, /* The table in which we should change things */
ExprList *pChanges, /* Things to be changed */
Expr *pWhere, /* The WHERE clause. May be null */
- int onError /* How to handle constraint errors */
+ int onError, /* How to handle constraint errors */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ Expr *pLimit, /* LIMIT clause. May be null */
+ Upsert *pUpsert /* ON CONFLICT clause, or null */
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
@@ -125483,6 +131651,21 @@ SQLITE_PRIVATE void sqlite3Update(
# define isView 0
#endif
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ if( !isView ){
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#else
+ if( pOrderBy || pLimit ){
+ sqlite3ErrorMsg(pParse, "%s on UPDATE not supported", pOrderBy?"ORDER BY":"LIMIT");
+ goto update_cleanup;
+ }
+#endif
+
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto update_cleanup;
}
@@ -125495,16 +131678,23 @@ SQLITE_PRIVATE void sqlite3Update(
** need to occur right after the database cursor. So go ahead and
** allocate enough space, just in case.
*/
- pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
+ iBaseCur = iDataCur = pParse->nTab++;
iIdxCur = iDataCur+1;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ testcase( pPk!=0 && pPk!=pTab->pIndex );
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
- if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){
+ if( pPk==pIdx ){
iDataCur = pParse->nTab;
- pTabList->a[0].iCursor = iDataCur;
}
pParse->nTab++;
}
+ if( pUpsert ){
+ /* On an UPSERT, reuse the same cursors already opened by INSERT */
+ iDataCur = pUpsert->iDataCur;
+ iIdxCur = pUpsert->iIdxCur;
+ pParse->nTab = iBaseCur;
+ }
+ pTabList->a[0].iCursor = iDataCur;
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
** Initialize aXRef[] and aToOpen[] to their default values.
@@ -125521,6 +131711,8 @@ SQLITE_PRIVATE void sqlite3Update(
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
+ sNC.uNC.pUpsert = pUpsert;
+ sNC.ncFlags = NC_UUpsert;
/* Resolve the column names in all the expressions of the
** of the UPDATE statement. Also find the column index
@@ -125587,19 +131779,18 @@ SQLITE_PRIVATE void sqlite3Update(
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
- **
- ** FIXME: Be smarter about omitting indexes that use expressions.
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
+ if( chngKey || hasFK>1 || pIdx==pPk
+ || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
+ ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; i<pIdx->nKeyCol; i++){
- i16 iIdxCol = pIdx->aiColumn[i];
- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+ if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
if( (onError==OE_Replace)
@@ -125624,7 +131815,7 @@ SQLITE_PRIVATE void sqlite3Update(
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto update_cleanup;
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1, iDb);
+ sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
/* Allocate required registers. */
if( !IsVirtual(pTab) ){
@@ -125651,7 +131842,11 @@ SQLITE_PRIVATE void sqlite3Update(
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
+ sqlite3MaterializeView(pParse, pTab,
+ pWhere, pOrderBy, pLimit, iDataCur
+ );
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -125671,8 +131866,16 @@ SQLITE_PRIVATE void sqlite3Update(
}
#endif
- /* Initialize the count of updated rows */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
+ /* Jump to labelBreak to abandon further processing of this UPDATE */
+ labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
+
+ /* Not an UPSERT. Normal processing. Begin by
+ ** initialize the count of updated rows */
+ if( (db->flags&SQLITE_CountRows)!=0
+ && !pParse->pTriggerTab
+ && !pParse->nested
+ && pUpsert==0
+ ){
regRowCount = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
}
@@ -125685,46 +131888,61 @@ SQLITE_PRIVATE void sqlite3Update(
iPk = pParse->nMem+1;
pParse->nMem += nPk;
regKey = ++pParse->nMem;
- iEph = pParse->nTab++;
-
- sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
- addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
- sqlite3VdbeSetP4KeyInfo(pParse, pPk);
- }
-
- /* Begin the database scan.
- **
- ** Do not consider a single-pass strategy for a multi-row update if
- ** there are any triggers or foreign keys to process, or rows may
- ** be deleted as a result of REPLACE conflict handling. Any of these
- ** things might disturb a cursor being used to scan through the table
- ** or index, causing a single-pass approach to malfunction. */
- flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
- if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
- flags |= WHERE_ONEPASS_MULTIROW;
- }
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
- if( pWInfo==0 ) goto update_cleanup;
-
- /* A one-pass strategy that might update more than one row may not
- ** be used if any column of the index used for the scan is being
- ** updated. Otherwise, if there is an index on "b", statements like
- ** the following could create an infinite loop:
- **
- ** UPDATE t1 SET b=b+1 WHERE b>?
- **
- ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
- ** strategy that uses an index for which one or more columns are being
- ** updated. */
- eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
- if( eOnePass==ONEPASS_MULTI ){
- int iCur = aiCurOnePass[1];
- if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
- eOnePass = ONEPASS_OFF;
+ if( pUpsert==0 ){
+ iEph = pParse->nTab++;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
}
- assert( iCur!=iDataCur || !HasRowid(pTab) );
}
+ if( pUpsert ){
+ /* If this is an UPSERT, then all cursors have already been opened by
+ ** the outer INSERT and the data cursor should be pointing at the row
+ ** that is to be updated. So bypass the code that searches for the
+ ** row(s) to be updated.
+ */
+ pWInfo = 0;
+ eOnePass = ONEPASS_SINGLE;
+ sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
+ }else{
+ /* Begin the database scan.
+ **
+ ** Do not consider a single-pass strategy for a multi-row update if
+ ** there are any triggers or foreign keys to process, or rows may
+ ** be deleted as a result of REPLACE conflict handling. Any of these
+ ** things might disturb a cursor being used to scan through the table
+ ** or index, causing a single-pass approach to malfunction. */
+ flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
+ if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+ flags |= WHERE_ONEPASS_MULTIROW;
+ }
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+
+ /* A one-pass strategy that might update more than one row may not
+ ** be used if any column of the index used for the scan is being
+ ** updated. Otherwise, if there is an index on "b", statements like
+ ** the following could create an infinite loop:
+ **
+ ** UPDATE t1 SET b=b+1 WHERE b>?
+ **
+ ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
+ ** strategy that uses an index for which one or more columns are being
+ ** updated. */
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ if( eOnePass!=ONEPASS_SINGLE ){
+ sqlite3MultiWrite(pParse);
+ if( eOnePass==ONEPASS_MULTI ){
+ int iCur = aiCurOnePass[1];
+ if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
+ eOnePass = ONEPASS_OFF;
+ }
+ assert( iCur!=iDataCur || !HasRowid(pTab) );
+ }
+ }
+ }
+
if( HasRowid(pTab) ){
/* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
** mode, write the rowid into the FIFO. In either of the one-pass modes,
@@ -125744,7 +131962,7 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
}
if( eOnePass ){
- sqlite3VdbeChangeToNoop(v, addrOpen);
+ if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
nKey = nPk;
regKey = iPk;
}else{
@@ -125754,59 +131972,58 @@ SQLITE_PRIVATE void sqlite3Update(
}
}
- if( eOnePass!=ONEPASS_MULTI ){
- sqlite3WhereEnd(pWInfo);
- }
-
- labelBreak = sqlite3VdbeMakeLabel(v);
- if( !isView ){
- int addrOnce = 0;
-
- /* Open every index that needs updating. */
- if( eOnePass!=ONEPASS_OFF ){
- if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
- if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
- }
-
- if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
- addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ if( pUpsert==0 ){
+ if( eOnePass!=ONEPASS_MULTI ){
+ sqlite3WhereEnd(pWInfo);
}
- sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
- 0, 0);
- if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
- }
-
- /* Top of the update loop */
- if( eOnePass!=ONEPASS_OFF ){
- if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
- assert( pPk );
- sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
- VdbeCoverageNeverTaken(v);
+
+ if( !isView ){
+ int addrOnce = 0;
+
+ /* Open every index that needs updating. */
+ if( eOnePass!=ONEPASS_OFF ){
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
+ }
+
+ if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
+ aToOpen, 0, 0);
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
}
- if( eOnePass==ONEPASS_SINGLE ){
- labelContinue = labelBreak;
- }else{
+
+ /* Top of the update loop */
+ if( eOnePass!=ONEPASS_OFF ){
+ if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
+ assert( pPk );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
+ VdbeCoverage(v);
+ }
+ if( eOnePass!=ONEPASS_SINGLE ){
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ VdbeCoverageIf(v, pPk==0);
+ VdbeCoverageIf(v, pPk!=0);
+ }else if( pPk ){
labelContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+ VdbeCoverage(v);
+ }else{
+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
+ regOldRowid);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
}
- sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
- VdbeCoverageIf(v, pPk==0);
- VdbeCoverageIf(v, pPk!=0);
- }else if( pPk ){
- labelContinue = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
- addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
- sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
- VdbeCoverage(v);
- }else{
- labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
- regOldRowid);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
- VdbeCoverage(v);
}
- /* If the record number will change, set register regNewRowid to
- ** contain the new value. If the record number is not being modified,
+ /* If the rowid value will change, set register regNewRowid to
+ ** contain the new value. If the rowid is not being modified,
** then regNewRowid is the same register as regOldRowid, which is
** already populated. */
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
@@ -125869,7 +132086,7 @@ SQLITE_PRIVATE void sqlite3Update(
*/
testcase( i==31 );
testcase( i==32 );
- sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
@@ -125898,10 +132115,14 @@ SQLITE_PRIVATE void sqlite3Update(
VdbeCoverage(v);
}
- /* If it did not delete it, the row-trigger may still have modified
+ /* After-BEFORE-trigger-reload-loop:
+ ** If it did not delete it, the BEFORE trigger may still have modified
** some of the columns of the row being updated. Load the values for
- ** all columns not modified by the update statement into their
- ** registers in case this has happened.
+ ** all columns not modified by the update statement into their registers
+ ** in case this has happened. Only unmodified columns are reloaded.
+ ** The values computed for modified columns use the values before the
+ ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26)
+ ** for an example.
*/
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]<0 && i!=pTab->iPKey ){
@@ -125917,7 +132138,7 @@ SQLITE_PRIVATE void sqlite3Update(
assert( regOldRowid>0 );
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
- aXRef);
+ aXRef, 0);
/* Do FK constraint checks. */
if( hasFK ){
@@ -125987,7 +132208,7 @@ SQLITE_PRIVATE void sqlite3Update(
/* Increment the row counter
*/
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
+ if( regRowCount ){
sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
}
@@ -126014,16 +132235,15 @@ SQLITE_PRIVATE void sqlite3Update(
** maximum rowid counter values recorded while inserting into
** autoincrement tables.
*/
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
+ if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){
sqlite3AutoincrementEnd(pParse);
}
/*
- ** Return the number of rows that were changed. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
+ ** Return the number of rows that were changed, if we are tracking
+ ** that information.
*/
- if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
+ if( regRowCount ){
sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
@@ -126035,6 +132255,8 @@ update_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pChanges);
sqlite3ExprDelete(db, pWhere);
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
@@ -126091,10 +132313,10 @@ static void updateVirtualTable(
int regRowid; /* Register for ephem table rowid */
int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
- int bOnePass; /* True to use onepass strategy */
+ int eOnePass; /* True to use onepass strategy */
int addr; /* Address of OP_OpenEphemeral */
- /* Allocate nArg registers to martial the arguments to VUpdate. Then
+ /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
** create and open the ephemeral table in which the records created from
** these arguments will be temporarily stored. */
assert( v );
@@ -126115,6 +132337,7 @@ static void updateVirtualTable(
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
}
}
if( HasRowid(pTab) ){
@@ -126135,26 +132358,32 @@ static void updateVirtualTable(
sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
}
- bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+
+ /* There is no ONEPASS_MULTI on virtual tables */
+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
- if( bOnePass ){
+ if( eOnePass ){
/* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
- ** above. Also, if this is a top-level parse (not a trigger), clear the
- ** multi-write flag so that the VM does not open a statement journal */
+ ** above. */
sqlite3VdbeChangeToNoop(v, addr);
- if( sqlite3IsToplevel(pParse) ){
- pParse->isMultiWrite = 0;
- }
+ sqlite3VdbeAddOp1(v, OP_Close, iCsr);
}else{
/* Create a record from the argument register contents and insert it into
** the ephemeral table. */
+ sqlite3MultiWrite(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
+#ifdef SQLITE_DEBUG
+ /* Signal an assert() within OP_MakeRecord that it is allowed to
+ ** accept no-change records with serial_type 10 */
+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
+#endif
sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
}
- if( bOnePass==0 ){
+ if( eOnePass==ONEPASS_OFF ){
/* End the virtual table scan */
sqlite3WhereEnd(pWInfo);
@@ -126174,7 +132403,7 @@ static void updateVirtualTable(
/* End of the ephemeral table scan. Or, if using the onepass strategy,
** jump to here if the scan visited zero rows. */
- if( bOnePass==0 ){
+ if( eOnePass==ONEPASS_OFF ){
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr);
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
@@ -126185,6 +132414,261 @@ static void updateVirtualTable(
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/************** End of update.c **********************************************/
+/************** Begin file upsert.c ******************************************/
+/*
+** 2018-04-12
+**
+** 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 contains code to implement various aspects of UPSERT
+** processing and handling of the Upsert object.
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_UPSERT
+/*
+** Free a list of Upsert objects
+*/
+SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){
+ if( p ){
+ sqlite3ExprListDelete(db, p->pUpsertTarget);
+ sqlite3ExprDelete(db, p->pUpsertTargetWhere);
+ sqlite3ExprListDelete(db, p->pUpsertSet);
+ sqlite3ExprDelete(db, p->pUpsertWhere);
+ sqlite3DbFree(db, p);
+ }
+}
+
+/*
+** Duplicate an Upsert object.
+*/
+SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){
+ if( p==0 ) return 0;
+ return sqlite3UpsertNew(db,
+ sqlite3ExprListDup(db, p->pUpsertTarget, 0),
+ sqlite3ExprDup(db, p->pUpsertTargetWhere, 0),
+ sqlite3ExprListDup(db, p->pUpsertSet, 0),
+ sqlite3ExprDup(db, p->pUpsertWhere, 0)
+ );
+}
+
+/*
+** Create a new Upsert object.
+*/
+SQLITE_PRIVATE Upsert *sqlite3UpsertNew(
+ sqlite3 *db, /* Determines which memory allocator to use */
+ ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */
+ Expr *pTargetWhere, /* Optional WHERE clause on the target */
+ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */
+ Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */
+){
+ Upsert *pNew;
+ pNew = sqlite3DbMallocRaw(db, sizeof(Upsert));
+ if( pNew==0 ){
+ sqlite3ExprListDelete(db, pTarget);
+ sqlite3ExprDelete(db, pTargetWhere);
+ sqlite3ExprListDelete(db, pSet);
+ sqlite3ExprDelete(db, pWhere);
+ return 0;
+ }else{
+ pNew->pUpsertTarget = pTarget;
+ pNew->pUpsertTargetWhere = pTargetWhere;
+ pNew->pUpsertSet = pSet;
+ pNew->pUpsertWhere = pWhere;
+ pNew->pUpsertIdx = 0;
+ }
+ return pNew;
+}
+
+/*
+** Analyze the ON CONFLICT clause described by pUpsert. Resolve all
+** symbols in the conflict-target.
+**
+** Return SQLITE_OK if everything works, or an error code is something
+** is wrong.
+*/
+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
+ Parse *pParse, /* The parsing context */
+ SrcList *pTabList, /* Table into which we are inserting */
+ Upsert *pUpsert /* The ON CONFLICT clauses */
+){
+ Table *pTab; /* That table into which we are inserting */
+ int rc; /* Result code */
+ int iCursor; /* Cursor used by pTab */
+ Index *pIdx; /* One of the indexes of pTab */
+ ExprList *pTarget; /* The conflict-target clause */
+ Expr *pTerm; /* One term of the conflict-target clause */
+ NameContext sNC; /* Context for resolving symbolic names */
+ Expr sCol[2]; /* Index column converted into an Expr */
+
+ assert( pTabList->nSrc==1 );
+ assert( pTabList->a[0].pTab!=0 );
+ assert( pUpsert!=0 );
+ assert( pUpsert->pUpsertTarget!=0 );
+
+ /* Resolve all symbolic names in the conflict-target clause, which
+ ** includes both the list of columns and the optional partial-index
+ ** WHERE clause.
+ */
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pParse;
+ sNC.pSrcList = pTabList;
+ rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
+ if( rc ) return rc;
+ rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
+ if( rc ) return rc;
+
+ /* Check to see if the conflict target matches the rowid. */
+ pTab = pTabList->a[0].pTab;
+ pTarget = pUpsert->pUpsertTarget;
+ iCursor = pTabList->a[0].iCursor;
+ if( HasRowid(pTab)
+ && pTarget->nExpr==1
+ && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
+ && pTerm->iColumn==XN_ROWID
+ ){
+ /* The conflict-target is the rowid of the primary table */
+ assert( pUpsert->pUpsertIdx==0 );
+ return SQLITE_OK;
+ }
+
+ /* Initialize sCol[0..1] to be an expression parse tree for a
+ ** single column of an index. The sCol[0] node will be the TK_COLLATE
+ ** operator and sCol[1] will be the TK_COLUMN operator. Code below
+ ** will populate the specific collation and column number values
+ ** prior to comparing against the conflict-target expression.
+ */
+ memset(sCol, 0, sizeof(sCol));
+ sCol[0].op = TK_COLLATE;
+ sCol[0].pLeft = &sCol[1];
+ sCol[1].op = TK_COLUMN;
+ sCol[1].iTable = pTabList->a[0].iCursor;
+
+ /* Check for matches against other indexes */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int ii, jj, nn;
+ if( !IsUniqueIndex(pIdx) ) continue;
+ if( pTarget->nExpr!=pIdx->nKeyCol ) continue;
+ if( pIdx->pPartIdxWhere ){
+ if( pUpsert->pUpsertTargetWhere==0 ) continue;
+ if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere,
+ pIdx->pPartIdxWhere, iCursor)!=0 ){
+ continue;
+ }
+ }
+ nn = pIdx->nKeyCol;
+ for(ii=0; ii<nn; ii++){
+ Expr *pExpr;
+ sCol[0].u.zToken = (char*)pIdx->azColl[ii];
+ if( pIdx->aiColumn[ii]==XN_EXPR ){
+ assert( pIdx->aColExpr!=0 );
+ assert( pIdx->aColExpr->nExpr>ii );
+ pExpr = pIdx->aColExpr->a[ii].pExpr;
+ if( pExpr->op!=TK_COLLATE ){
+ sCol[0].pLeft = pExpr;
+ pExpr = &sCol[0];
+ }
+ }else{
+ sCol[0].pLeft = &sCol[1];
+ sCol[1].iColumn = pIdx->aiColumn[ii];
+ pExpr = &sCol[0];
+ }
+ for(jj=0; jj<nn; jj++){
+ if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){
+ break; /* Column ii of the index matches column jj of target */
+ }
+ }
+ if( jj>=nn ){
+ /* The target contains no match for column jj of the index */
+ break;
+ }
+ }
+ if( ii<nn ){
+ /* Column ii of the index did not match any term of the conflict target.
+ ** Continue the search with the next index. */
+ continue;
+ }
+ pUpsert->pUpsertIdx = pIdx;
+ return SQLITE_OK;
+ }
+ sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any "
+ "PRIMARY KEY or UNIQUE constraint");
+ return SQLITE_ERROR;
+}
+
+/*
+** Generate bytecode that does an UPDATE as part of an upsert.
+**
+** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
+** In this case parameter iCur is a cursor open on the table b-tree that
+** currently points to the conflicting table row. Otherwise, if pIdx
+** is not NULL, then pIdx is the constraint that failed and iCur is a
+** cursor points to the conflicting row.
+*/
+SQLITE_PRIVATE void sqlite3UpsertDoUpdate(
+ Parse *pParse, /* The parsing and code-generating context */
+ Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */
+ Table *pTab, /* The table being updated */
+ Index *pIdx, /* The UNIQUE constraint that failed */
+ int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */
+){
+ Vdbe *v = pParse->pVdbe;
+ sqlite3 *db = pParse->db;
+ SrcList *pSrc; /* FROM clause for the UPDATE */
+ int iDataCur;
+
+ assert( v!=0 );
+ assert( pUpsert!=0 );
+ VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
+ iDataCur = pUpsert->iDataCur;
+ if( pIdx && iCur!=iDataCur ){
+ if( HasRowid(pTab) ){
+ int regRowid = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid);
+ VdbeCoverage(v);
+ sqlite3ReleaseTempReg(pParse, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ int nPk = pPk->nKeyCol;
+ int iPk = pParse->nMem+1;
+ int i;
+ pParse->nMem += nPk;
+ for(i=0; i<nPk; i++){
+ int k;
+ assert( pPk->aiColumn[i]>=0 );
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
+ VdbeComment((v, "%s.%s", pIdx->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ sqlite3VdbeVerifyAbortable(v, OE_Abort);
+ i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0,
+ "corrupt database", P4_STATIC);
+ sqlite3VdbeJumpHere(v, i);
+ }
+ }
+ /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So
+ ** we have to make a copy before passing it down into sqlite3Update() */
+ pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0);
+ sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet,
+ pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert);
+ pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */
+ pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */
+ VdbeNoopComment((v, "End DO UPDATE of UPSERT"));
+}
+
+#endif /* SQLITE_OMIT_UPSERT */
+
+/************** End of upsert.c **********************************************/
/************** Begin file vacuum.c ******************************************/
/*
** 2003 April 6
@@ -126227,8 +132711,14 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
- if( zSubSql ){
- assert( zSubSql[0]!='S' );
+ /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
+ ** or INSERT. Historically there have been attacks that first
+ ** corrupt the sqlite_master.sql field with other kinds of statements
+ ** then run VACUUM to get those statements to execute at inappropriate
+ ** times. */
+ if( zSubSql
+ && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
+ ){
rc = execSql(db, pzErrMsg, zSubSql);
if( rc!=SQLITE_OK ) break;
}
@@ -126406,7 +132896,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
*/
rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeBeginTrans(pMain, 2);
+ rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
@@ -126441,7 +132931,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_master"
- " WHERE type='index' AND length(sql)>10",
+ " WHERE type='index'",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -126825,7 +133315,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){
assert( sqlite3_mutex_held(db->mutex) );
if( p ){
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
do {
VTable *pNext = p->pNext;
sqlite3VtabUnlock(p);
@@ -127321,7 +133811,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
assert( IsVirtual(pTab) );
memset(&sParse, 0, sizeof(sParse));
- sParse.declareVtab = 1;
+ sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
sParse.db = db;
sParse.nQueryLoop = 1;
if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr)
@@ -127362,7 +133852,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
- sParse.declareVtab = 0;
+ sParse.eParseMode = PARSE_MODE_NORMAL;
if( sParse.pVdbe ){
sqlite3VdbeFinalize(sParse.pVdbe);
@@ -127612,9 +134102,6 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
void *pArg = 0;
FuncDef *pNew;
int rc = 0;
- char *zLowerName;
- unsigned char *z;
-
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
@@ -127629,16 +134116,22 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
if( pMod->xFindFunction==0 ) return pDef;
/* Call the xFindFunction method on the virtual table implementation
- ** to see if the implementation wants to overload this function
+ ** to see if the implementation wants to overload this function.
+ **
+ ** Though undocumented, we have historically always invoked xFindFunction
+ ** with an all lower-case function name. Continue in this tradition to
+ ** avoid any chance of an incompatibility.
*/
- zLowerName = sqlite3DbStrDup(db, pDef->zName);
- if( zLowerName ){
- for(z=(unsigned char*)zLowerName; *z; z++){
- *z = sqlite3UpperToLower[*z];
+#ifdef SQLITE_DEBUG
+ {
+ int i;
+ for(i=0; pDef->zName[i]; i++){
+ unsigned char x = (unsigned char)pDef->zName[i];
+ assert( x==sqlite3UpperToLower[x] );
}
- rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
- sqlite3DbFree(db, zLowerName);
}
+#endif
+ rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg);
if( rc==0 ){
return pDef;
}
@@ -127850,7 +134343,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-/***/ int sqlite3WhereTrace;
+/***/ extern int sqlite3WhereTrace;
#endif
#if defined(SQLITE_DEBUG) \
&& (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
@@ -127913,6 +134406,8 @@ struct WhereLevel {
struct InLoop {
int iCur; /* The VDBE cursor used by this IN operator */
int addrInTop; /* Top of the IN loop */
+ int iBase; /* Base register of multi-key index record */
+ int nPrefix; /* Number of prior entires in the key */
u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
} *aInLoop; /* Information about each nested IN operator */
} in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
@@ -128151,6 +134646,7 @@ struct WhereClause {
WhereInfo *pWInfo; /* WHERE clause processing context */
WhereClause *pOuter; /* Outer conjunction */
u8 op; /* Split operator. TK_AND or TK_OR */
+ u8 hasOr; /* True if any a[].eOperator is WO_OR */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
@@ -128298,12 +134794,10 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
Parse *pParse, /* Parse context */
SrcList *pTabList, /* Table list this loop refers to */
WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
- int iLevel, /* Value for "level" column of output */
- int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
);
#else
-# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
+# define sqlite3WhereExplainOneScan(u,v,w,x) 0
#endif /* SQLITE_OMIT_EXPLAIN */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
@@ -128326,6 +134820,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
@@ -128388,6 +134883,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
+#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in wherecode.c ******************/
@@ -128423,23 +134919,23 @@ static void explainAppendTerm(
int i;
assert( nTerm>=1 );
- if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+ if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
+ if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
for(i=0; i<nTerm; i++){
- if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
- sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
+ if( i ) sqlite3_str_append(pStr, ",", 1);
+ sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
}
- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
+ if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
- sqlite3StrAccumAppend(pStr, zOp, 1);
+ sqlite3_str_append(pStr, zOp, 1);
- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
+ if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
for(i=0; i<nTerm; i++){
- if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
- sqlite3StrAccumAppend(pStr, "?", 1);
+ if( i ) sqlite3_str_append(pStr, ",", 1);
+ sqlite3_str_append(pStr, "?", 1);
}
- if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
+ if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
}
/*
@@ -128463,11 +134959,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
int i, j;
if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
- sqlite3StrAccumAppend(pStr, " (", 2);
+ sqlite3_str_append(pStr, " (", 2);
for(i=0; i<nEq; i++){
const char *z = explainIndexColumnName(pIndex, i);
- if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
- sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
+ if( i ) sqlite3_str_append(pStr, " AND ", 5);
+ sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
}
j = i;
@@ -128478,7 +134974,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
}
- sqlite3StrAccumAppend(pStr, ")", 1);
+ sqlite3_str_append(pStr, ")", 1);
}
/*
@@ -128494,19 +134990,16 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
Parse *pParse, /* Parse context */
SrcList *pTabList, /* Table list this loop refers to */
WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
- int iLevel, /* Value for "level" column of output */
- int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
- if( pParse->explain==2 )
+ if( sqlite3ParseToplevel(pParse)->explain==2 )
#endif
{
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
Vdbe *v = pParse->pVdbe; /* VM being constructed */
sqlite3 *db = pParse->db; /* Database handle */
- int iId = pParse->iSelectId; /* Select id (left-most output column) */
int isSearch; /* True for a SEARCH. False for SCAN. */
WhereLoop *pLoop; /* The controlling WhereLoop object */
u32 flags; /* Flags that describe this loop */
@@ -128523,15 +135016,15 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
- sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
+ sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
if( pItem->pSelect ){
- sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
+ sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId);
}else{
- sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
+ sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
}
if( pItem->zAlias ){
- sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
+ sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
}
if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
const char *zFmt = 0;
@@ -128554,8 +135047,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
zFmt = "INDEX %s";
}
if( zFmt ){
- sqlite3StrAccumAppend(&str, " USING ", 7);
- sqlite3XPrintf(&str, zFmt, pIdx->zName);
+ sqlite3_str_append(&str, " USING ", 7);
+ sqlite3_str_appendf(&str, zFmt, pIdx->zName);
explainIndexRange(&str, pLoop);
}
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
@@ -128570,23 +135063,26 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
assert( flags&WHERE_TOP_LIMIT);
zRangeOp = "<";
}
- sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
+ sqlite3_str_appendf(&str,
+ " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
- sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
+ sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
}
#endif
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
if( pLoop->nOut>=10 ){
- sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
+ sqlite3_str_appendf(&str, " (~%llu rows)",
+ sqlite3LogEstToInt(pLoop->nOut));
}else{
- sqlite3StrAccumAppend(&str, " (~1 row)", 9);
+ sqlite3_str_append(&str, " (~1 row)", 9);
}
#endif
zMsg = sqlite3StrAccumFinish(&str);
- ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
+ ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
+ pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
}
return ret;
}
@@ -128666,8 +135162,8 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
int nLoop = 0;
- while( ALWAYS(pTerm!=0)
- && (pTerm->wtFlags & TERM_CODED)==0
+ assert( pTerm!=0 );
+ while( (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
&& (pLevel->notReady & pTerm->prereqAll)==0
){
@@ -128678,6 +135174,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
}
if( pTerm->iParent<0 ) break;
pTerm = &pTerm->pWC->a[pTerm->iParent];
+ assert( pTerm!=0 );
pTerm->nChild--;
if( pTerm->nChild!=0 ) break;
nLoop++;
@@ -128718,7 +135215,6 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
/* Code the OP_Affinity opcode if there is anything left to do. */
if( n>0 ){
sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
- sqlite3ExprCacheAffinityChange(pParse, base, n);
}
}
@@ -128748,6 +135244,102 @@ static void updateRangeAffinityStr(
}
}
+
+/*
+** pX is an expression of the form: (vector) IN (SELECT ...)
+** In other words, it is a vector IN operator with a SELECT clause on the
+** LHS. But not all terms in the vector are indexable and the terms might
+** not be in the correct order for indexing.
+**
+** This routine makes a copy of the input pX expression and then adjusts
+** the vector on the LHS with corresponding changes to the SELECT so that
+** the vector contains only index terms and those terms are in the correct
+** order. The modified IN expression is returned. The caller is responsible
+** for deleting the returned expression.
+**
+** Example:
+**
+** CREATE TABLE t1(a,b,c,d,e,f);
+** CREATE INDEX t1x1 ON t1(e,c);
+** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2)
+** \_______________________________________/
+** The pX expression
+**
+** Since only columns e and c can be used with the index, in that order,
+** the modified IN expression that is returned will be:
+**
+** (e,c) IN (SELECT z,x FROM t2)
+**
+** The reduced pX is different from the original (obviously) and thus is
+** only used for indexing, to improve performance. The original unaltered
+** IN expression must also be run on each output row for correctness.
+*/
+static Expr *removeUnindexableInClauseTerms(
+ Parse *pParse, /* The parsing context */
+ int iEq, /* Look at loop terms starting here */
+ WhereLoop *pLoop, /* The current loop */
+ Expr *pX /* The IN expression to be reduced */
+){
+ sqlite3 *db = pParse->db;
+ Expr *pNew = sqlite3ExprDup(db, pX, 0);
+ if( db->mallocFailed==0 ){
+ ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */
+ ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */
+ ExprList *pRhs = 0; /* New RHS after modifications */
+ ExprList *pLhs = 0; /* New LHS after mods */
+ int i; /* Loop counter */
+ Select *pSelect; /* Pointer to the SELECT on the RHS */
+
+ for(i=iEq; i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iField = pLoop->aLTerm[i]->iField - 1;
+ if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
+ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
+ pOrigRhs->a[iField].pExpr = 0;
+ assert( pOrigLhs->a[iField].pExpr!=0 );
+ pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
+ pOrigLhs->a[iField].pExpr = 0;
+ }
+ }
+ sqlite3ExprListDelete(db, pOrigRhs);
+ sqlite3ExprListDelete(db, pOrigLhs);
+ pNew->pLeft->x.pList = pLhs;
+ pNew->x.pSelect->pEList = pRhs;
+ if( pLhs && pLhs->nExpr==1 ){
+ /* Take care here not to generate a TK_VECTOR containing only a
+ ** single value. Since the parser never creates such a vector, some
+ ** of the subroutines do not handle this case. */
+ Expr *p = pLhs->a[0].pExpr;
+ pLhs->a[0].pExpr = 0;
+ sqlite3ExprDelete(db, pNew->pLeft);
+ pNew->pLeft = p;
+ }
+ pSelect = pNew->x.pSelect;
+ if( pSelect->pOrderBy ){
+ /* If the SELECT statement has an ORDER BY clause, zero the
+ ** iOrderByCol variables. These are set to non-zero when an
+ ** ORDER BY term exactly matches one of the terms of the
+ ** result-set. Since the result-set of the SELECT statement may
+ ** have been modified or reordered, these variables are no longer
+ ** set correctly. Since setting them is just an optimization,
+ ** it's easiest just to zero them here. */
+ ExprList *pOrderBy = pSelect->pOrderBy;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
+ }
+
+#if 0
+ printf("For indexing, change the IN expr:\n");
+ sqlite3TreeViewExpr(0, pX, 0);
+ printf("Into:\n");
+ sqlite3TreeViewExpr(0, pNew, 0);
+#endif
+ }
+ return pNew;
+}
+
+
/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
@@ -128810,68 +135402,23 @@ static int codeEqualityTerm(
}
}
for(i=iEq;i<pLoop->nLTerm; i++){
- if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+ assert( pLoop->aLTerm[i]!=0 );
+ if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
}
if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
}else{
- Select *pSelect = pX->x.pSelect;
sqlite3 *db = pParse->db;
- u16 savedDbOptFlags = db->dbOptFlags;
- ExprList *pOrigRhs = pSelect->pEList;
- ExprList *pOrigLhs = pX->pLeft->x.pList;
- ExprList *pRhs = 0; /* New Select.pEList for RHS */
- ExprList *pLhs = 0; /* New pX->pLeft vector */
-
- for(i=iEq;i<pLoop->nLTerm; i++){
- if( pLoop->aLTerm[i]->pExpr==pX ){
- int iField = pLoop->aLTerm[i]->iField - 1;
- Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0);
- Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0);
+ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
- pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs);
- pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs);
- }
- }
if( !db->mallocFailed ){
- Expr *pLeft = pX->pLeft;
-
- if( pSelect->pOrderBy ){
- /* If the SELECT statement has an ORDER BY clause, zero the
- ** iOrderByCol variables. These are set to non-zero when an
- ** ORDER BY term exactly matches one of the terms of the
- ** result-set. Since the result-set of the SELECT statement may
- ** have been modified or reordered, these variables are no longer
- ** set correctly. Since setting them is just an optimization,
- ** it's easiest just to zero them here. */
- ExprList *pOrderBy = pSelect->pOrderBy;
- for(i=0; i<pOrderBy->nExpr; i++){
- pOrderBy->a[i].u.x.iOrderByCol = 0;
- }
- }
-
- /* Take care here not to generate a TK_VECTOR containing only a
- ** single value. Since the parser never creates such a vector, some
- ** of the subroutines do not handle this case. */
- if( pLhs->nExpr==1 ){
- pX->pLeft = pLhs->a[0].pExpr;
- }else{
- pLeft->x.pList = pLhs;
- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq);
- testcase( aiMap==0 );
- }
- pSelect->pEList = pRhs;
- db->dbOptFlags |= SQLITE_QueryFlattener;
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
- db->dbOptFlags = savedDbOptFlags;
- testcase( aiMap!=0 && aiMap[0]!=0 );
- pSelect->pEList = pOrigRhs;
- pLeft->x.pList = pOrigLhs;
- pX->pLeft = pLeft;
+ pTerm->pExpr->iTable = pX->iTable;
}
- sqlite3ExprListDelete(pParse->db, pLhs);
- sqlite3ExprListDelete(pParse->db, pRhs);
+ sqlite3ExprDelete(db, pX);
+ pX = pTerm->pExpr;
}
if( eType==IN_INDEX_INDEX_DESC ){
@@ -128911,7 +135458,14 @@ static int codeEqualityTerm(
sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
if( i==iEq ){
pIn->iCur = iTab;
- pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
+ pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
+ if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ pIn->iBase = iReg - i;
+ pIn->nPrefix = i;
+ pLoop->wsFlags |= WHERE_IN_EARLYOUT;
+ }else{
+ pIn->nPrefix = 0;
+ }
}else{
pIn->eEndLoopOp = OP_Noop;
}
@@ -129198,11 +135752,8 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
struct CCurHint *pHint = pWalker->u.pCCurHint;
if( pExpr->op==TK_COLUMN ){
if( pExpr->iTable!=pHint->iTabCur ){
- Vdbe *v = pWalker->pParse->pVdbe;
int reg = ++pWalker->pParse->nMem; /* Register for column value */
- sqlite3ExprCodeGetColumnOfTable(
- v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
- );
+ sqlite3ExprCode(pWalker->pParse, pExpr, reg);
pExpr->op = TK_REGISTER;
pExpr->iTable = reg;
}else if( pHint->pIdx!=0 ){
@@ -129535,6 +136086,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
+ assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+ || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
+ );
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
@@ -129552,7 +136106,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
VdbeCoverage(v);
- VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+ VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
pLevel->op = OP_Goto;
}else
@@ -129566,7 +136120,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int nConstraint = pLoop->nLTerm;
int iIn; /* Counter for IN constraints */
- sqlite3ExprCachePush(pParse);
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
addrNotFound = pLevel->addrBrk;
for(j=0; j<nConstraint; j++){
@@ -129639,7 +136192,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
**
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
*/
- sqlite3ExprCachePop(pParse);
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -129663,9 +136215,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
VdbeCoverage(v);
- sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- VdbeComment((v, "pk"));
pLevel->op = OP_Noop;
}else if( (pLoop->wsFlags & WHERE_IPK)!=0
&& (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
@@ -129715,7 +136264,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( sqlite3ExprIsVector(pX->pRight) ){
r1 = rTemp = sqlite3GetTempReg(pParse);
codeExprOrVector(pParse, pX->pRight, r1, 1);
- op = aMoveOp[(pX->op - TK_GT) | 0x0001];
+ testcase( pX->op==TK_GT );
+ testcase( pX->op==TK_GE );
+ testcase( pX->op==TK_LT );
+ testcase( pX->op==TK_LE );
+ op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1];
+ assert( pX->op!=TK_GT || op==OP_SeekGE );
+ assert( pX->op!=TK_GE || op==OP_SeekGE );
+ assert( pX->op!=TK_LT || op==OP_SeekLE );
+ assert( pX->op!=TK_LE || op==OP_SeekLE );
}else{
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
disableTerm(pLevel, pStart);
@@ -129727,7 +136284,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverageIf(v, pX->op==TK_LE);
VdbeCoverageIf(v, pX->op==TK_LT);
VdbeCoverageIf(v, pX->op==TK_GE);
- sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
@@ -129762,7 +136318,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( testOp!=OP_Noop ){
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
VdbeCoverageIf(v, testOp==OP_Le);
VdbeCoverageIf(v, testOp==OP_Lt);
@@ -129967,6 +136522,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** above has already left the cursor sitting on the correct row,
** so no further seeking is needed */
}else{
+ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
+ sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
+ }
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
assert( op!=0 );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
@@ -129985,7 +136543,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
nConstraint = nEq;
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
- sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
@@ -130029,6 +136586,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
}
+ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
+ sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
+ }
+
/* Seek the table cursor, if required */
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
@@ -130039,7 +136600,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
)){
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
VdbeCoverage(v);
}else{
@@ -130059,9 +136619,16 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* If pIdx is an index on one or more expressions, then look through
** all the expressions in pWInfo and try to transform matching expressions
** into reference to index columns.
+ **
+ ** Do not do this for the RHS of a LEFT JOIN. This is because the
+ ** expression may be evaluated after OP_NullRow has been executed on
+ ** the cursor. In this case it is important to do the full evaluation,
+ ** as the result of the expression may not be NULL, even if all table
+ ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a
*/
- whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
-
+ if( pLevel->iLeftJoin==0 ){
+ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
+ }
/* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
@@ -130217,7 +136784,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
Expr *pExpr = pWC->a[iTerm].pExpr;
if( &pWC->a[iTerm] == pTerm ) continue;
- if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
@@ -130236,13 +136802,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** sub-WHERE clause is to to invoke the main loop body as a subroutine.
*/
wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
+ ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
int jmp1 = 0; /* Address of jump operation */
- if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
+ assert( (pTabItem[0].fg.jointype & JT_LEFT)==0
+ || ExprHasProperty(pOrExpr, EP_FromJoin)
+ );
+ if( pAndExpr ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
}
@@ -130254,7 +136824,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( pSubWInfo ){
WhereLoop *pSubLoop;
int addrExplain = sqlite3WhereExplainOneScan(
- pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
+ pParse, pOrTab, &pSubWInfo->a[0], 0
);
sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
@@ -130264,23 +136834,23 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** row will be skipped in subsequent sub-WHERE clauses.
*/
if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
- int r;
int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
if( HasRowid(pTab) ){
- r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid);
jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
- r,iSet);
+ regRowid, iSet);
VdbeCoverage(v);
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
int nPk = pPk->nKeyCol;
int iPk;
+ int r;
/* Read the PK into an array of temp registers. */
r = sqlite3GetTempRange(pParse, nPk);
for(iPk=0; iPk<nPk; iPk++){
int iCol = pPk->aiColumn[iPk];
- sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk);
}
/* Check if the temp table already contains this key. If so,
@@ -130353,6 +136923,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
}
}
+ ExplainQueryPlanPop(pParse);
pLevel->u.pCovidx = pCov;
if( pCov ) pLevel->iIdxCur = iCovCur;
if( pAndExpr ){
@@ -130425,7 +136996,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
pE = pTerm->pExpr;
assert( pE!=0 );
- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
+ if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
continue;
}
@@ -130438,7 +137009,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
continue;
}
- if( pTerm->wtFlags & TERM_LIKECOND ){
+ if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){
/* 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
@@ -130448,8 +137019,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
continue;
#else
u32 x = pLevel->iLikeRepCntr;
- assert( x>0 );
- skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
+ if( x>0 ){
+ skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
+ }
VdbeCoverage(v);
#endif
}
@@ -130489,6 +137061,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
WO_EQ|WO_IN|WO_IS, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
+ if( (pAlt->eOperator & WO_IN)
+ && (pAlt->pExpr->flags & EP_xIsSelect)
+ && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
+ ){
+ continue;
+ }
testcase( pAlt->eOperator & WO_EQ );
testcase( pAlt->eOperator & WO_IS );
testcase( pAlt->eOperator & WO_IN );
@@ -130505,7 +137083,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
VdbeComment((v, "record LEFT JOIN hit"));
- sqlite3ExprCacheClear(pParse);
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
@@ -130721,18 +137298,18 @@ static int isLikeOrGlob(
int *pisComplete, /* True if the only wildcard is % in the last character */
int *pnoCase /* True if uppercase is equivalent to lowercase */
){
- const u8 *z = 0; /* String on RHS of LIKE operator */
+ const u8 *z = 0; /* String on RHS of LIKE operator */
Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
ExprList *pList; /* List of operands to the LIKE operator */
- int c; /* One character in z[] */
+ u8 c; /* One character in z[] */
int cnt; /* Number of non-wildcard prefix characters */
- char wc[4]; /* Wildcard characters */
+ u8 wc[4]; /* Wildcard characters */
sqlite3 *db = pParse->db; /* Database connection */
sqlite3_value *pVal = 0;
int op; /* Opcode of pRight */
int rc; /* Result code to return */
- if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
+ if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){
return 0;
}
#ifdef SQLITE_EBCDIC
@@ -130757,23 +137334,6 @@ static int isLikeOrGlob(
}
if( z ){
- /* If the RHS begins with a digit or a minus sign, then the LHS must
- ** be an ordinary column (not a virtual table column) with TEXT affinity.
- ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
- ** even though "lhs LIKE rhs" is true. But if the RHS does not start
- ** with a digit or '-', then "lhs LIKE rhs" will always be false if
- ** the LHS is numeric and so the optimization still works.
- */
- if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
- ){
- sqlite3ValueFree(pVal);
- return 0;
- }
- }
-
/* Count the number of prefix characters prior to the first wildcard */
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
@@ -130783,11 +137343,13 @@ static int isLikeOrGlob(
/* The optimization is possible only if (1) the pattern does not begin
** with a wildcard and if (2) the non-wildcard prefix does not end with
- ** an (illegal 0xff) character. The second condition is necessary so
+ ** an (illegal 0xff) character, or (3) the pattern does not consist of
+ ** a single escape character. The second condition is necessary so
** that we can increment the prefix key to find an upper bound for the
- ** range search.
- */
- if( cnt!=0 && 255!=(u8)z[cnt-1] ){
+ ** range search. The third is because the caller assumes that the pattern
+ ** consists of at least one character after all escapes have been
+ ** removed. */
+ if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){
Expr *pPrefix;
/* A "complete" match if the pattern ends with "*" or "%" */
@@ -130804,6 +137366,32 @@ static int isLikeOrGlob(
zNew[iTo++] = zNew[iFrom];
}
zNew[iTo] = 0;
+
+ /* If the RHS begins with a digit or a minus sign, then the LHS must be
+ ** an ordinary column (not a virtual table column) with TEXT affinity.
+ ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
+ ** even though "lhs LIKE rhs" is true. But if the RHS does not start
+ ** with a digit or '-', then "lhs LIKE rhs" will always be false if
+ ** the LHS is numeric and so the optimization still works.
+ **
+ ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
+ ** The RHS pattern must not be '/%' because the termination condition
+ ** will then become "x<'0'" and if the affinity is numeric, will then
+ ** be converted into "x<0", which is incorrect.
+ */
+ if( sqlite3Isdigit(zNew[0])
+ || zNew[0]=='-'
+ || (zNew[0]+1=='0' && iTo==1)
+ ){
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ ){
+ sqlite3ExprDelete(db, pPrefix);
+ sqlite3ValueFree(pVal);
+ return 0;
+ }
+ }
}
*ppPrefix = pPrefix;
@@ -130865,6 +137453,7 @@ static int isLikeOrGlob(
** If the expression matches none of the patterns above, return 0.
*/
static int isAuxiliaryVtabOperator(
+ sqlite3 *db, /* Parsing context */
Expr *pExpr, /* Test this expression */
unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */
Expr **ppLeft, /* Column expression to left of MATCH/op2 */
@@ -130888,16 +137477,54 @@ static int isAuxiliaryVtabOperator(
if( pList==0 || pList->nExpr!=2 ){
return 0;
}
+
+ /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
+ ** virtual table on their second argument, which is the same as
+ ** the left-hand side operand in their in-fix form.
+ **
+ ** vtab_column MATCH expression
+ ** MATCH(expression,vtab_column)
+ */
pCol = pList->a[1].pExpr;
- if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
- return 0;
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ for(i=0; i<ArraySize(aOp); i++){
+ if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+ *peOp2 = aOp[i].eOp2;
+ *ppRight = pList->a[0].pExpr;
+ *ppLeft = pCol;
+ return 1;
+ }
+ }
}
- for(i=0; i<ArraySize(aOp); i++){
- if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
- *peOp2 = aOp[i].eOp2;
- *ppRight = pList->a[0].pExpr;
- *ppLeft = pCol;
- return 1;
+
+ /* We can also match against the first column of overloaded
+ ** functions where xFindFunction returns a value of at least
+ ** SQLITE_INDEX_CONSTRAINT_FUNCTION.
+ **
+ ** OVERLOADED(vtab_column,expression)
+ **
+ ** Historically, xFindFunction expected to see lower-case function
+ ** names. But for this use case, xFindFunction is expected to deal
+ ** with function names in an arbitrary case.
+ */
+ pCol = pList->a[0].pExpr;
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pMod;
+ void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
+ void *pNotUsed;
+ pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+ assert( pVtab!=0 );
+ assert( pVtab->pModule!=0 );
+ pMod = (sqlite3_module *)pVtab->pModule;
+ if( pMod->xFindFunction!=0 ){
+ i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
+ if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
+ *peOp2 = i;
+ *ppRight = pList->a[1].pExpr;
+ *ppLeft = pCol;
+ return 1;
+ }
}
}
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
@@ -131199,7 +137826,12 @@ static void exprAnalyzeOrTerm(
** empty.
*/
pOrInfo->indexable = indexable;
- pTerm->eOperator = indexable==0 ? 0 : WO_OR;
+ if( indexable ){
+ pTerm->eOperator = WO_OR;
+ pWC->hasOr = 1;
+ }else{
+ pTerm->eOperator = WO_OR;
+ }
/* For a two-way OR, attempt to implementation case 2.
*/
@@ -131340,12 +137972,11 @@ static void exprAnalyzeOrTerm(
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
- pTerm = &pWC->a[idxTerm];
+ /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
markTermAsChild(pWC, idxNew, idxTerm);
}else{
sqlite3ExprListDelete(db, pList);
}
- pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
}
}
}
@@ -131380,7 +138011,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
return 0;
}
pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
- if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
+ if( sqlite3IsBinary(pColl) ) return 1;
return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
}
@@ -131403,6 +138034,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
for(i=0; i<pSrc->nSrc; i++){
mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
+ if( pSrc->a[i].fg.isTabFunc ){
+ mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
+ }
}
}
pS = pS->pPrior;
@@ -131510,7 +138144,7 @@ static void exprAnalyze(
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
- unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
+ unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */
int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
@@ -131536,7 +138170,7 @@ static void exprAnalyze(
pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
}
pMaskSet->bVarSelect = 0;
- prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
+ prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
if( ExprHasProperty(pExpr, EP_FromJoin) ){
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
@@ -131718,7 +138352,7 @@ static void exprAnalyze(
}
*pC = c + 1;
}
- zCollSeqName = noCase ? "NOCASE" : "BINARY";
+ zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY;
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
@@ -131754,8 +138388,8 @@ static void exprAnalyze(
** to do anything with MATCH functions.
*/
if( pWC->op==TK_AND ){
- Expr *pRight, *pLeft;
- int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight);
+ Expr *pRight = 0, *pLeft = 0;
+ int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
while( res-- > 0 ){
int idxNew;
WhereTerm *pNewTerm;
@@ -131815,7 +138449,7 @@ static void exprAnalyze(
exprAnalyze(pSrc, pWC, idxNew);
}
pTerm = &pWC->a[idxTerm];
- pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
+ pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
pTerm->eOperator = 0;
}
@@ -131852,6 +138486,7 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
+ && !ExprHasProperty(pExpr, EP_FromJoin)
&& OptimizationEnabled(db, SQLITE_Stat34)
){
Expr *pNewExpr;
@@ -131929,6 +138564,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit(
WhereInfo *pWInfo /* The WHERE processing context */
){
pWC->pWInfo = pWInfo;
+ pWC->hasOr = 0;
pWC->pOuter = 0;
pWC->nTerm = 0;
pWC->nSlot = ArraySize(pWC->aStatic);
@@ -131965,17 +138601,18 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
** a bitmask indicating which tables are used in that expression
** tree.
*/
-SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask;
- if( p==0 ) return 0;
- if( p->op==TK_COLUMN ){
+ if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
return sqlite3WhereGetMask(pMaskSet, p->iTable);
+ }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
+ assert( p->op!=TK_IF_NULL_ROW );
+ return 0;
}
mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
- assert( !ExprHasProperty(p, EP_TokenOnly) );
- if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
+ if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
if( p->pRight ){
- mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
+ mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
assert( p->x.pList==0 );
}else if( ExprHasProperty(p, EP_xIsSelect) ){
if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
@@ -131985,6 +138622,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
}
return mask;
}
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
+ return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
+}
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
int i;
Bitmask mask = 0;
@@ -132078,6 +138718,21 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
/* #include "sqliteInt.h" */
/* #include "whereInt.h" */
+/*
+** Extra information appended to the end of sqlite3_index_info but not
+** visible to the xBestIndex function, at least not directly. The
+** sqlite3_vtab_collation() interface knows how to reach it, however.
+**
+** This object is not an API and can be changed from one release to the
+** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
+** agree on the structure, all will be well.
+*/
+typedef struct HiddenIndexInfo HiddenIndexInfo;
+struct HiddenIndexInfo {
+ WhereClause *pWC; /* The Where clause being analyzed */
+ Parse *pParse; /* The parsing context */
+};
+
/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);
@@ -132111,15 +138766,38 @@ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
}
/*
-** Return TRUE if the innermost loop of the WHERE clause implementation
-** returns rows in ORDER BY order for complete run of the inner loop.
+** In the ORDER BY LIMIT optimization, if the inner-most loop is known
+** to emit rows in increasing order, and if the last row emitted by the
+** inner-most loop did not fit within the sorter, then we can skip all
+** subsequent rows for the current iteration of the inner loop (because they
+** will not fit in the sorter either) and continue with the second inner
+** loop - the loop immediately outside the inner-most.
+**
+** When a row does not fit in the sorter (because the sorter already
+** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
+** label returned by this function.
**
-** Across multiple iterations of outer loops, the output rows need not be
-** sorted. As long as rows are sorted for just the innermost loop, this
-** routine can return TRUE.
+** If the ORDER BY LIMIT optimization applies, the jump destination should
+** be the continuation for the second-inner-most loop. If the ORDER BY
+** LIMIT optimization does not apply, then the jump destination should
+** be the continuation for the inner-most loop.
+**
+** It is always safe for this routine to return the continuation of the
+** inner-most loop, in the sense that a correct answer will result.
+** Returning the continuation the second inner loop is an optimization
+** that might make the code run a little faster, but should not change
+** the final answer.
*/
-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){
- return pWInfo->bOrderedInnerLoop;
+SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
+ WhereLevel *pInner;
+ if( !pWInfo->bOrderedInnerLoop ){
+ /* The ORDER BY LIMIT optimization does not apply. Jump to the
+ ** continuation of the inner-most loop. */
+ return pWInfo->iContinue;
+ }
+ pInner = &pWInfo->a[pWInfo->nLevel-1];
+ assert( pInner->addrNxt!=0 );
+ return pInner->addrNxt;
}
/*
@@ -132846,7 +139524,6 @@ static void constructAutomaticIndex(
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
- sqlite3ExprCachePush(pParse);
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
@@ -132854,7 +139531,7 @@ static void constructAutomaticIndex(
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
- VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+ VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
}else{
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
}
@@ -132883,7 +139560,6 @@ static void constructAutomaticIndex(
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ExprCachePop(pParse);
/* Jump here when skipping the initialization */
sqlite3VdbeJumpHere(v, addrInit);
@@ -132900,11 +139576,11 @@ end_auto_index_create:
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
- Parse *pParse,
- WhereClause *pWC,
+ Parse *pParse, /* The parsing context */
+ WhereClause *pWC, /* The WHERE clause being analyzed */
Bitmask mUnusable, /* Ignore terms with these prereqs */
- struct SrcList_item *pSrc,
- ExprList *pOrderBy,
+ struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */
+ ExprList *pOrderBy, /* The ORDER BY clause */
u16 *pmNoOmit /* Mask of terms not to omit */
){
int i, j;
@@ -132912,6 +139588,7 @@ static sqlite3_index_info *allocateIndexInfo(
struct sqlite3_index_constraint *pIdxCons;
struct sqlite3_index_orderby *pIdxOrderBy;
struct sqlite3_index_constraint_usage *pUsage;
+ struct HiddenIndexInfo *pHidden;
WhereTerm *pTerm;
int nOrderBy;
sqlite3_index_info *pIdxInfo;
@@ -132953,7 +139630,7 @@ static sqlite3_index_info *allocateIndexInfo(
*/
pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
- + sizeof(*pIdxOrderBy)*nOrderBy );
+ + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
return 0;
@@ -132964,7 +139641,8 @@ static sqlite3_index_info *allocateIndexInfo(
** changing them. We have to do some funky casting in order to
** initialize those fields.
*/
- pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];
+ pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
+ pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
*(int*)&pIdxInfo->nConstraint = nTerm;
@@ -132974,6 +139652,8 @@ static sqlite3_index_info *allocateIndexInfo(
*(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
pUsage;
+ pHidden->pWC = pWC;
+ pHidden->pParse = pParse;
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
u16 op;
if( pTerm->leftCursor != pSrc->iCursor ) continue;
@@ -132985,6 +139665,20 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_ALL );
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
+ if( (pSrc->fg.jointype & JT_LEFT)!=0
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ && (pTerm->eOperator & (WO_IS|WO_ISNULL))
+ ){
+ /* An "IS" term in the WHERE clause where the virtual table is the rhs
+ ** of a LEFT JOIN. Do not pass this term to the virtual table
+ ** implementation, as this can lead to incorrect results from SQL such
+ ** as:
+ **
+ ** "LEFT JOIN vtab WHERE vtab.col IS NULL" */
+ testcase( pTerm->eOperator & WO_ISNULL );
+ testcase( pTerm->eOperator & WO_IS );
+ continue;
+ }
assert( pTerm->u.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
@@ -133476,7 +140170,9 @@ static int whereRangeScanEst(
Index *p = pLoop->u.btree.pIndex;
int nEq = pLoop->u.btree.nEq;
- if( p->nSample>0 && nEq<p->nSampleCol ){
+ if( p->nSample>0 && nEq<p->nSampleCol
+ && OptimizationEnabled(pParse->db, SQLITE_Stat34)
+ ){
if( nEq==pBuilder->nRecValid ){
UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
@@ -133922,22 +140618,21 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
- if( ALWAYS(pWInfo) ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- WhereLevel *pLevel = &pWInfo->a[i];
- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
- }
- }
- sqlite3WhereClauseClear(&pWInfo->sWC);
- while( pWInfo->pLoops ){
- WhereLoop *p = pWInfo->pLoops;
- pWInfo->pLoops = p->pNextLoop;
- whereLoopDelete(db, p);
+ int i;
+ assert( pWInfo!=0 );
+ for(i=0; i<pWInfo->nLevel; i++){
+ WhereLevel *pLevel = &pWInfo->a[i];
+ if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
+ sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
- sqlite3DbFreeNN(db, pWInfo);
}
+ sqlite3WhereClauseClear(&pWInfo->sWC);
+ while( pWInfo->pLoops ){
+ WhereLoop *p = pWInfo->pLoops;
+ pWInfo->pLoops = p->pNextLoop;
+ whereLoopDelete(db, p);
+ }
+ sqlite3DbFreeNN(db, pWInfo);
}
/*
@@ -134414,8 +141109,8 @@ static int whereLoopAddBtreeIndex(
pNew = pBuilder->pNew;
if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
- WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n",
- pProbe->zName, pNew->u.btree.nEq));
+ WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n",
+ pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq));
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
@@ -134461,15 +141156,12 @@ 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
+ /* Do not allow 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;
}
@@ -134495,7 +141187,6 @@ static int whereLoopAddBtreeIndex(
if( eOp & WO_IN ){
Expr *pExpr = pTerm->pExpr;
- pNew->wsFlags |= WHERE_COLUMN_IN;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
int i;
@@ -134515,17 +141206,55 @@ static int whereLoopAddBtreeIndex(
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
** changes "x IN (?)" into "x=?". */
}
+ if( pProbe->hasStat1 ){
+ LogEst M, logK, safetyMargin;
+ /* Let:
+ ** N = the total number of rows in the table
+ ** K = the number of entries on the RHS of the IN operator
+ ** M = the number of rows in the table that match terms to the
+ ** to the left in the same index. If the IN operator is on
+ ** the left-most index column, M==N.
+ **
+ ** Given the definitions above, it is better to omit the IN operator
+ ** from the index lookup and instead do a scan of the M elements,
+ ** testing each scanned row against the IN operator separately, if:
+ **
+ ** M*log(K) < K*log(N)
+ **
+ ** Our estimates for M, K, and N might be inaccurate, so we build in
+ ** a safety margin of 2 (LogEst: 10) that favors using the IN operator
+ ** with the index, as using an index has better worst-case behavior.
+ ** If we do not have real sqlite_stat1 data, always prefer to use
+ ** the index.
+ */
+ M = pProbe->aiRowLogEst[saved_nEq];
+ logK = estLog(nIn);
+ safetyMargin = 10; /* TUNING: extra weight for indexed IN */
+ if( M + logK + safetyMargin < nIn + rLogSize ){
+ WHERETRACE(0x40,
+ ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
+ saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
+ continue;
+ }else{
+ WHERETRACE(0x40,
+ ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
+ saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
+ }
+ }
+ pNew->wsFlags |= WHERE_COLUMN_IN;
}else if( eOp & (WO_EQ|WO_IS) ){
int iCol = pProbe->aiColumn[saved_nEq];
pNew->wsFlags |= WHERE_COLUMN_EQ;
assert( saved_nEq==pNew->u.btree.nEq );
if( iCol==XN_ROWID
- || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
+ || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
- if( iCol>=0 && pProbe->uniqNotNull==0 ){
- pNew->wsFlags |= WHERE_UNQ_WANTED;
- }else{
+ if( iCol==XN_ROWID || pProbe->uniqNotNull
+ || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
+ ){
pNew->wsFlags |= WHERE_ONEROW;
+ }else{
+ pNew->wsFlags |= WHERE_UNQ_WANTED;
}
}
}else if( eOp & WO_ISNULL ){
@@ -134591,6 +141320,7 @@ static int whereLoopAddBtreeIndex(
&& pProbe->nSample
&& pNew->u.btree.nEq<=pProbe->nSampleCol
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
+ && OptimizationEnabled(db, SQLITE_Stat34)
){
Expr *pExpr = pTerm->pExpr;
if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
@@ -134679,6 +141409,7 @@ static int whereLoopAddBtreeIndex(
if( saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->noSkipScan==0
+ && OptimizationEnabled(db, SQLITE_SkipScan)
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
@@ -134699,8 +141430,8 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags = saved_wsFlags;
}
- WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n",
- pProbe->zName, saved_nEq, rc));
+ WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n",
+ pProbe->pTable->zName, pProbe->zName, saved_nEq, rc));
return rc;
}
@@ -134742,24 +141473,6 @@ static int indexMightHelpWithOrderBy(
return 0;
}
-/*
-** Return a bitmask where 1s indicate that the corresponding column of
-** the table is used by an index. Only the first 63 columns are considered.
-*/
-static Bitmask columnsInIndex(Index *pIdx){
- Bitmask m = 0;
- int j;
- for(j=pIdx->nColumn-1; j>=0; j--){
- int x = pIdx->aiColumn[j];
- if( x>=0 ){
- testcase( x==BMS-1 );
- testcase( x==BMS-2 );
- if( x<BMS-1 ) m |= MASKBIT(x);
- }
- }
- return m;
-}
-
/* Check to see if a partial index with pPartIndexWhere can be used
** in the current query. Return true if it can be and false if not.
*/
@@ -134904,14 +141617,16 @@ static int whereLoopAddBtree(
/* TUNING: One-time cost for computing the automatic index is
** estimated to be X*N*log2(N) where N is the number of rows in
** the table being indexed and where X is 7 (LogEst=28) for normal
- ** tables or 1.375 (LogEst=4) for views and subqueries. The value
+ ** tables or 0.5 (LogEst=-10) for views and subqueries. The value
** of X is smaller for views and subqueries so that the query planner
** will be more aggressive about generating automatic indexes for
** those objects, since there is no opportunity to add schema
** indexes on subqueries and views. */
- pNew->rSetup = rLogSize + rSize + 4;
+ pNew->rSetup = rLogSize + rSize;
if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
- pNew->rSetup += 24;
+ pNew->rSetup += 28;
+ }else{
+ pNew->rSetup -= 10;
}
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
if( pNew->rSetup<0 ) pNew->rSetup = 0;
@@ -134929,14 +141644,17 @@ static int whereLoopAddBtree(
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
- /* Loop over all indices
- */
- for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+ /* Loop over all indices. If there was an INDEXED BY clause, then only
+ ** consider index pProbe. */
+ for(; rc==SQLITE_OK && pProbe;
+ pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
+ ){
if( pProbe->pPartIdxWhere!=0
&& !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
continue; /* Partial index inappropriate for this query */
}
+ if( pProbe->bNoQuery ) continue;
rSize = pProbe->aiRowLogEst[0];
pNew->u.btree.nEq = 0;
pNew->u.btree.nBtm = 0;
@@ -134970,7 +141688,7 @@ static int whereLoopAddBtree(
pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
m = 0;
}else{
- m = pSrc->colUsed & ~columnsInIndex(pProbe);
+ m = pSrc->colUsed & pProbe->colNotIdxed;
pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
}
@@ -135041,10 +141759,6 @@ static int whereLoopAddBtree(
pBuilder->nRecValid = 0;
pBuilder->pRec = 0;
#endif
-
- /* If there was an INDEXED BY clause, then only that one index is
- ** considered. */
- if( pSrc->pIBIndex ) break;
}
return rc;
}
@@ -135139,9 +141853,9 @@ static int whereLoopAddVirtualOne(
|| pNew->aLTerm[iTerm]!=0
|| pIdxCons->usable==0
){
- rc = SQLITE_ERROR;
sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
- return rc;
+ testcase( pIdxInfo->needToFreeIdxStr );
+ return SQLITE_ERROR;
}
testcase( iTerm==nConstraint-1 );
testcase( j==0 );
@@ -135169,6 +141883,15 @@ static int whereLoopAddVirtualOne(
pNew->u.vtab.omitMask &= ~mNoOmit;
pNew->nLTerm = mxTerm+1;
+ for(i=0; i<=mxTerm; i++){
+ if( pNew->aLTerm[i]==0 ){
+ /* The non-zero argvIdx values must be contiguous. Raise an
+ ** error if they are not */
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
+ testcase( pIdxInfo->needToFreeIdxStr );
+ return SQLITE_ERROR;
+ }
+ }
assert( pNew->nLTerm<=pNew->nLSlot );
pNew->u.vtab.idxNum = pIdxInfo->idxNum;
pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
@@ -135199,6 +141922,27 @@ static int whereLoopAddVirtualOne(
return rc;
}
+/*
+** If this function is invoked from within an xBestIndex() callback, it
+** returns a pointer to a buffer containing the name of the collation
+** sequence associated with element iCons of the sqlite3_index_info.aConstraint
+** array. Or, if iCons is out of range or there is no active xBestIndex
+** call, return NULL.
+*/
+SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
+ const char *zRet = 0;
+ if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
+ CollSeq *pC = 0;
+ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
+ Expr *pX = pHidden->pWC->a[iTerm].pExpr;
+ if( pX->pLeft ){
+ pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight);
+ }
+ zRet = (pC ? pC->zName : sqlite3StrBINARY);
+ }
+ return zRet;
+}
/*
** Add all WhereLoop objects for a table of the join identified by
@@ -135263,6 +142007,7 @@ static int whereLoopAddVirtual(
}
/* First call xBestIndex() with all constraints usable. */
+ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
@@ -135338,6 +142083,7 @@ static int whereLoopAddVirtual(
if( p->needToFreeIdxStr ) sqlite3_free((char *)p->idxStr);
sqlite3DbFreeNN(pParse->db, p);
+ WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -135509,7 +142255,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
{
rc = whereLoopAddBtree(pBuilder, mPrereq);
}
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
}
mPrior |= pNew->maskSelf;
@@ -136016,12 +142762,15 @@ 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 ){
+ if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
/* Do not use an automatic index if the this loop is expected
- ** to run less than 2 times. */
+ ** to run less than 1.25 times. It is tempting to also exclude
+ ** automatic index usage on an outer loop, but sometimes an automatic
+ ** index is useful in the outer loop of a correlated subquery. */
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);
@@ -136041,7 +142790,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
- rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
+ /* TUNING: Add a small extra penalty (5) to sorting as an
+ ** extra encouragment to the query planner to select a plan
+ ** where the rows emerge in the correct order without any sorting
+ ** required. */
+ rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
WHERETRACE(0x002,
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
@@ -136231,6 +142984,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
}
+ pWInfo->bOrderedInnerLoop = 0;
if( pWInfo->pOrderBy ){
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
@@ -136342,7 +143096,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
}
if( j!=pIdx->nKeyCol ) continue;
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
- if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
+ if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){
pLoop->wsFlags |= WHERE_IDX_ONLY;
}
pLoop->nLTerm = j;
@@ -136603,6 +143357,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( wctrlFlags & WHERE_WANT_DISTINCT ){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
+ ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
}else{
/* Assign a bit from the bitmask to every term in the FROM clause.
**
@@ -136652,6 +143407,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
*/
for(ii=0; ii<sWLB.pWC->nTerm; ii++){
WhereTerm *pT = &sWLB.pWC->a[ii];
+ if( pT->wtFlags & TERM_VIRTUAL ) continue;
if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
pT->wtFlags |= TERM_CODED;
@@ -136739,35 +143495,80 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
}
#endif
- /* Attempt to omit tables from the join that do not effect the result */
+
+ /* Attempt to omit tables from the join that do not affect the result.
+ ** For a table to not affect the result, the following must be true:
+ **
+ ** 1) The query must not be an aggregate.
+ ** 2) The table must be the RHS of a LEFT JOIN.
+ ** 3) Either the query must be DISTINCT, or else the ON or USING clause
+ ** must contain a constraint that limits the scan of the table to
+ ** at most a single row.
+ ** 4) The table must not be referenced by any part of the query apart
+ ** from its own USING or ON clause.
+ **
+ ** For example, given:
+ **
+ ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
+ ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
+ ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
+ **
+ ** then table t2 can be omitted from the following:
+ **
+ ** SELECT v1, v3 FROM t1
+ ** LEFT JOIN t2 USING (t1.ipk=t2.ipk)
+ ** LEFT JOIN t3 USING (t1.ipk=t3.ipk)
+ **
+ ** or from:
+ **
+ ** SELECT DISTINCT v1, v3 FROM t1
+ ** LEFT JOIN t2
+ ** LEFT JOIN t3 USING (t1.ipk=t3.ipk)
+ */
+ notReady = ~(Bitmask)0;
if( pWInfo->nLevel>=2
- && pResultSet!=0
+ && pResultSet!=0 /* guarantees condition (1) above */
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
+ int i;
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
- while( pWInfo->nLevel>=2 ){
+ for(i=pWInfo->nLevel-1; i>=1; i--){
WhereTerm *pTerm, *pEnd;
- pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
- if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
+ struct SrcList_item *pItem;
+ pLoop = pWInfo->a[i].pWLoop;
+ pItem = &pWInfo->pTabList->a[pLoop->iTab];
+ if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
&& (pLoop->wsFlags & WHERE_ONEROW)==0
){
- break;
+ continue;
}
- if( (tabUsed & pLoop->maskSelf)!=0 ) break;
+ if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
- ){
- break;
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
+ ){
+ break;
+ }
}
}
- if( pTerm<pEnd ) break;
+ if( pTerm<pEnd ) continue;
WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+ notReady &= ~pLoop->maskSelf;
+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+ if( i!=pWInfo->nLevel-1 ){
+ int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
+ memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
+ }
pWInfo->nLevel--;
nTabList--;
}
@@ -136777,15 +143578,32 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
+ **
+ ** A one-pass approach can be used if the caller has requested one
+ ** and either (a) the scan visits at most one row or (b) each
+ ** of the following are true:
+ **
+ ** * the caller has indicated that a one-pass approach can be used
+ ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
+ ** * the table is not a virtual table, and
+ ** * either the scan does not use the OR optimization or the caller
+ ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified
+ ** for DELETE).
+ **
+ ** The last qualification is because an UPDATE statement uses
+ ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
+ ** use a one-pass approach, and this is not set accurately for scans
+ ** that use the OR optimization.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
- if( bOnerow
- || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
- && 0==(wsFlags & WHERE_VIRTUALTABLE))
- ){
+ if( bOnerow || (
+ 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
+ && 0==(wsFlags & WHERE_VIRTUALTABLE)
+ && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
+ )){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
@@ -136922,7 +143740,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** loop below generates code for a single nested loop of the VM
** program.
*/
- notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
int addrExplain;
int wsFlags;
@@ -136936,7 +143753,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
#endif
addrExplain = sqlite3WhereExplainOneScan(
- pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
+ pParse, pTabList, pLevel, wctrlFlags
);
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
@@ -136960,6 +143777,26 @@ whereBeginError:
}
/*
+** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
+** index rather than the main table. In SQLITE_DEBUG mode, we want
+** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine
+** does that.
+*/
+#ifndef SQLITE_DEBUG
+# define OpcodeRewriteTrace(D,K,P) /* no-op */
+#else
+# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P)
+ static void sqlite3WhereOpcodeRewriteTrace(
+ sqlite3 *db,
+ int pc,
+ VdbeOp *pOp
+ ){
+ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
+ sqlite3VdbePrintOp(0, pc, pOp);
+ }
+#endif
+
+/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
*/
@@ -136975,7 +143812,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
/* Generate loop termination code.
*/
VdbeModuleComment((v, "End WHERE-core"));
- sqlite3ExprCacheClear(pParse);
for(i=pWInfo->nLevel-1; i>=0; i--){
int addr;
pLevel = &pWInfo->a[i];
@@ -136986,6 +143822,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
Index *pIdx;
int n;
if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
+ && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */
&& (pLoop->wsFlags & WHERE_INDEXED)!=0
&& (pIdx = pLoop->u.btree.pIndex)->hasStat1
&& (n = pLoop->u.btree.nIdxCol)>0
@@ -137025,10 +143862,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
if( pIn->eEndLoopOp!=OP_Noop ){
+ if( pIn->nPrefix ){
+ assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
+ sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
+ sqlite3VdbeCurrentAddr(v)+2,
+ pIn->iBase, pIn->nPrefix);
+ VdbeCoverage(v);
+ }
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
}
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
@@ -137052,7 +143896,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
if( (ws & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
+ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
+ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
}
if( (ws & WHERE_INDEXED)
|| ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
@@ -137118,10 +143963,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
){
last = sqlite3VdbeCurrentAddr(v);
k = pLevel->addrBody;
+#ifdef SQLITE_DEBUG
+ if( db->flags & SQLITE_VdbeAddopTrace ){
+ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1);
+ }
+#endif
pOp = sqlite3VdbeGetOp(v, k);
for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue;
- if( pOp->opcode==OP_Column ){
+ if( pOp->opcode==OP_Column
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ || pOp->opcode==OP_Offset
+#endif
+ ){
int x = pOp->p2;
assert( pIdx->pTable==pTab );
if( !HasRowid(pTab) ){
@@ -137133,16 +143987,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
if( x>=0 ){
pOp->p2 = x;
pOp->p1 = pLevel->iIdxCur;
+ OpcodeRewriteTrace(db, k, pOp);
}
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
|| pWInfo->eOnePass );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
+ OpcodeRewriteTrace(db, k, pOp);
}else if( pOp->opcode==OP_IfNullRow ){
pOp->p1 = pLevel->iIdxCur;
+ OpcodeRewriteTrace(db, k, pOp);
}
}
+#ifdef SQLITE_DEBUG
+ if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
+#endif
}
}
@@ -137154,6 +144014,2261 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
}
/************** End of where.c ***********************************************/
+/************** Begin file window.c ******************************************/
+/*
+** 2018 May 08
+**
+** 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.
+**
+*************************************************************************
+*/
+/* #include "sqliteInt.h" */
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+
+/*
+** SELECT REWRITING
+**
+** Any SELECT statement that contains one or more window functions in
+** either the select list or ORDER BY clause (the only two places window
+** functions may be used) is transformed by function sqlite3WindowRewrite()
+** in order to support window function processing. For example, with the
+** schema:
+**
+** CREATE TABLE t1(a, b, c, d, e, f, g);
+**
+** the statement:
+**
+** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
+**
+** is transformed to:
+**
+** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
+** SELECT a, e, c, d, b FROM t1 ORDER BY c, d
+** ) ORDER BY e;
+**
+** The flattening optimization is disabled when processing this transformed
+** SELECT statement. This allows the implementation of the window function
+** (in this case max()) to process rows sorted in order of (c, d), which
+** makes things easier for obvious reasons. More generally:
+**
+** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to
+** the sub-query.
+**
+** * ORDER BY, LIMIT and OFFSET remain part of the parent query.
+**
+** * Terminals from each of the expression trees that make up the
+** select-list and ORDER BY expressions in the parent query are
+** selected by the sub-query. For the purposes of the transformation,
+** terminals are column references and aggregate functions.
+**
+** If there is more than one window function in the SELECT that uses
+** the same window declaration (the OVER bit), then a single scan may
+** be used to process more than one window function. For example:
+**
+** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
+** min(e) OVER (PARTITION BY c ORDER BY d)
+** FROM t1;
+**
+** is transformed in the same way as the example above. However:
+**
+** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
+** min(e) OVER (PARTITION BY a ORDER BY b)
+** FROM t1;
+**
+** Must be transformed to:
+**
+** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
+** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
+** SELECT a, e, c, d, b FROM t1 ORDER BY a, b
+** ) ORDER BY c, d
+** ) ORDER BY e;
+**
+** so that both min() and max() may process rows in the order defined by
+** their respective window declarations.
+**
+** INTERFACE WITH SELECT.C
+**
+** When processing the rewritten SELECT statement, code in select.c calls
+** sqlite3WhereBegin() to begin iterating through the results of the
+** sub-query, which is always implemented as a co-routine. It then calls
+** sqlite3WindowCodeStep() to process rows and finish the scan by calling
+** sqlite3WhereEnd().
+**
+** sqlite3WindowCodeStep() generates VM code so that, for each row returned
+** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
+** When the sub-routine is invoked:
+**
+** * The results of all window-functions for the row are stored
+** in the associated Window.regResult registers.
+**
+** * The required terminal values are stored in the current row of
+** temp table Window.iEphCsr.
+**
+** In some cases, depending on the window frame and the specific window
+** functions invoked, sqlite3WindowCodeStep() caches each entire partition
+** in a temp table before returning any rows. In other cases it does not.
+** This detail is encapsulated within this file, the code generated by
+** select.c is the same in either case.
+**
+** BUILT-IN WINDOW FUNCTIONS
+**
+** This implementation features the following built-in window functions:
+**
+** row_number()
+** rank()
+** dense_rank()
+** percent_rank()
+** cume_dist()
+** ntile(N)
+** lead(expr [, offset [, default]])
+** lag(expr [, offset [, default]])
+** first_value(expr)
+** last_value(expr)
+** nth_value(expr, N)
+**
+** These are the same built-in window functions supported by Postgres.
+** Although the behaviour of aggregate window functions (functions that
+** can be used as either aggregates or window funtions) allows them to
+** be implemented using an API, built-in window functions are much more
+** esoteric. Additionally, some window functions (e.g. nth_value())
+** may only be implemented by caching the entire partition in memory.
+** As such, some built-in window functions use the same API as aggregate
+** window functions and some are implemented directly using VDBE
+** instructions. Additionally, for those functions that use the API, the
+** window frame is sometimes modified before the SELECT statement is
+** rewritten. For example, regardless of the specified window frame, the
+** row_number() function always uses:
+**
+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+**
+** See sqlite3WindowUpdate() for details.
+**
+** As well as some of the built-in window functions, aggregate window
+** functions min() and max() are implemented using VDBE instructions if
+** the start of the window frame is declared as anything other than
+** UNBOUNDED PRECEDING.
+*/
+
+/*
+** Implementation of built-in window function row_number(). Assumes that the
+** window frame has been coerced to:
+**
+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void row_numberStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ) (*p)++;
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+}
+static void row_numberValueFunc(sqlite3_context *pCtx){
+ i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ sqlite3_result_int64(pCtx, (p ? *p : 0));
+}
+
+/*
+** Context object type used by rank(), dense_rank(), percent_rank() and
+** cume_dist().
+*/
+struct CallCount {
+ i64 nValue;
+ i64 nStep;
+ i64 nTotal;
+};
+
+/*
+** Implementation of built-in window function dense_rank(). Assumes that
+** the window frame has been set to:
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void dense_rankStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ) p->nStep = 1;
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+}
+static void dense_rankValueFunc(sqlite3_context *pCtx){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ if( p->nStep ){
+ p->nValue++;
+ p->nStep = 0;
+ }
+ sqlite3_result_int64(pCtx, p->nValue);
+ }
+}
+
+/*
+** Implementation of built-in window function rank(). Assumes that
+** the window frame has been set to:
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void rankStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ p->nStep++;
+ if( p->nValue==0 ){
+ p->nValue = p->nStep;
+ }
+ }
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+}
+static void rankValueFunc(sqlite3_context *pCtx){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ sqlite3_result_int64(pCtx, p->nValue);
+ p->nValue = 0;
+ }
+}
+
+/*
+** Implementation of built-in window function percent_rank(). Assumes that
+** the window frame has been set to:
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void percent_rankStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ UNUSED_PARAMETER(nArg); assert( nArg==1 );
+
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ if( p->nTotal==0 ){
+ p->nTotal = sqlite3_value_int64(apArg[0]);
+ }
+ p->nStep++;
+ if( p->nValue==0 ){
+ p->nValue = p->nStep;
+ }
+ }
+}
+static void percent_rankValueFunc(sqlite3_context *pCtx){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ if( p->nTotal>1 ){
+ double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
+ sqlite3_result_double(pCtx, r);
+ }else{
+ sqlite3_result_double(pCtx, 0.0);
+ }
+ p->nValue = 0;
+ }
+}
+
+/*
+** Implementation of built-in window function cume_dist(). Assumes that
+** the window frame has been set to:
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void cume_distStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ assert( nArg==1 ); UNUSED_PARAMETER(nArg);
+
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ if( p->nTotal==0 ){
+ p->nTotal = sqlite3_value_int64(apArg[0]);
+ }
+ p->nStep++;
+ }
+}
+static void cume_distValueFunc(sqlite3_context *pCtx){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->nTotal ){
+ double r = (double)(p->nStep) / (double)(p->nTotal);
+ sqlite3_result_double(pCtx, r);
+ }
+}
+
+/*
+** Context object for ntile() window function.
+*/
+struct NtileCtx {
+ i64 nTotal; /* Total rows in partition */
+ i64 nParam; /* Parameter passed to ntile(N) */
+ i64 iRow; /* Current row */
+};
+
+/*
+** Implementation of ntile(). This assumes that the window frame has
+** been coerced to:
+**
+** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
+*/
+static void ntileStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NtileCtx *p;
+ assert( nArg==2 ); UNUSED_PARAMETER(nArg);
+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ if( p->nTotal==0 ){
+ p->nParam = sqlite3_value_int64(apArg[0]);
+ p->nTotal = sqlite3_value_int64(apArg[1]);
+ if( p->nParam<=0 ){
+ sqlite3_result_error(
+ pCtx, "argument of ntile must be a positive integer", -1
+ );
+ }
+ }
+ p->iRow++;
+ }
+}
+static void ntileValueFunc(sqlite3_context *pCtx){
+ struct NtileCtx *p;
+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->nParam>0 ){
+ int nSize = (p->nTotal / p->nParam);
+ if( nSize==0 ){
+ sqlite3_result_int64(pCtx, p->iRow);
+ }else{
+ i64 nLarge = p->nTotal - p->nParam*nSize;
+ i64 iSmall = nLarge*(nSize+1);
+ i64 iRow = p->iRow-1;
+
+ assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
+
+ if( iRow<iSmall ){
+ sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
+ }else{
+ sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
+ }
+ }
+ }
+}
+
+/*
+** Context object for last_value() window function.
+*/
+struct LastValueCtx {
+ sqlite3_value *pVal;
+ int nVal;
+};
+
+/*
+** Implementation of last_value().
+*/
+static void last_valueStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct LastValueCtx *p;
+ UNUSED_PARAMETER(nArg);
+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ sqlite3_value_free(p->pVal);
+ p->pVal = sqlite3_value_dup(apArg[0]);
+ if( p->pVal==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ p->nVal++;
+ }
+ }
+}
+static void last_valueInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct LastValueCtx *p;
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( ALWAYS(p) ){
+ p->nVal--;
+ if( p->nVal==0 ){
+ sqlite3_value_free(p->pVal);
+ p->pVal = 0;
+ }
+ }
+}
+static void last_valueValueFunc(sqlite3_context *pCtx){
+ struct LastValueCtx *p;
+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pVal ){
+ sqlite3_result_value(pCtx, p->pVal);
+ }
+}
+static void last_valueFinalizeFunc(sqlite3_context *pCtx){
+ struct LastValueCtx *p;
+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pVal ){
+ sqlite3_result_value(pCtx, p->pVal);
+ sqlite3_value_free(p->pVal);
+ p->pVal = 0;
+ }
+}
+
+/*
+** Static names for the built-in window function names. These static
+** names are used, rather than string literals, so that FuncDef objects
+** can be associated with a particular window function by direct
+** comparison of the zName pointer. Example:
+**
+** if( pFuncDef->zName==row_valueName ){ ... }
+*/
+static const char row_numberName[] = "row_number";
+static const char dense_rankName[] = "dense_rank";
+static const char rankName[] = "rank";
+static const char percent_rankName[] = "percent_rank";
+static const char cume_distName[] = "cume_dist";
+static const char ntileName[] = "ntile";
+static const char last_valueName[] = "last_value";
+static const char nth_valueName[] = "nth_value";
+static const char first_valueName[] = "first_value";
+static const char leadName[] = "lead";
+static const char lagName[] = "lag";
+
+/*
+** No-op implementations of xStep() and xFinalize(). Used as place-holders
+** for built-in window functions that never call those interfaces.
+**
+** The noopValueFunc() is called but is expected to do nothing. The
+** noopStepFunc() is never called, and so it is marked with NO_TEST to
+** let the test coverage routine know not to expect this function to be
+** invoked.
+*/
+static void noopStepFunc( /*NO_TEST*/
+ sqlite3_context *p, /*NO_TEST*/
+ int n, /*NO_TEST*/
+ sqlite3_value **a /*NO_TEST*/
+){ /*NO_TEST*/
+ UNUSED_PARAMETER(p); /*NO_TEST*/
+ UNUSED_PARAMETER(n); /*NO_TEST*/
+ UNUSED_PARAMETER(a); /*NO_TEST*/
+ assert(0); /*NO_TEST*/
+} /*NO_TEST*/
+static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
+
+/* Window functions that use all window interfaces: xStep, xFinal,
+** xValue, and xInverse */
+#define WINDOWFUNCALL(name,nArg,extra) { \
+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
+ name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
+ name ## InvFunc, name ## Name, {0} \
+}
+
+/* Window functions that are implemented using bytecode and thus have
+** no-op routines for their methods */
+#define WINDOWFUNCNOOP(name,nArg,extra) { \
+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
+ noopStepFunc, noopValueFunc, noopValueFunc, \
+ noopStepFunc, name ## Name, {0} \
+}
+
+/* Window functions that use all window interfaces: xStep, the
+** same routine for xFinalize and xValue and which never call
+** xInverse. */
+#define WINDOWFUNCX(name,nArg,extra) { \
+ nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
+ name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
+ noopStepFunc, name ## Name, {0} \
+}
+
+
+/*
+** Register those built-in window functions that are not also aggregates.
+*/
+SQLITE_PRIVATE void sqlite3WindowFunctions(void){
+ static FuncDef aWindowFuncs[] = {
+ WINDOWFUNCX(row_number, 0, 0),
+ WINDOWFUNCX(dense_rank, 0, 0),
+ WINDOWFUNCX(rank, 0, 0),
+ WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
+ WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
+ WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
+ WINDOWFUNCALL(last_value, 1, 0),
+ WINDOWFUNCNOOP(nth_value, 2, 0),
+ WINDOWFUNCNOOP(first_value, 1, 0),
+ WINDOWFUNCNOOP(lead, 1, 0),
+ WINDOWFUNCNOOP(lead, 2, 0),
+ WINDOWFUNCNOOP(lead, 3, 0),
+ WINDOWFUNCNOOP(lag, 1, 0),
+ WINDOWFUNCNOOP(lag, 2, 0),
+ WINDOWFUNCNOOP(lag, 3, 0),
+ };
+ sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
+}
+
+/*
+** This function is called immediately after resolving the function name
+** for a window function within a SELECT statement. Argument pList is a
+** linked list of WINDOW definitions for the current SELECT statement.
+** Argument pFunc is the function definition just resolved and pWin
+** is the Window object representing the associated OVER clause. This
+** function updates the contents of pWin as follows:
+**
+** * If the OVER clause refered to a named window (as in "max(x) OVER win"),
+** search list pList for a matching WINDOW definition, and update pWin
+** accordingly. If no such WINDOW clause can be found, leave an error
+** in pParse.
+**
+** * If the function is a built-in window function that requires the
+** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
+** of this file), pWin is updated here.
+*/
+SQLITE_PRIVATE void sqlite3WindowUpdate(
+ Parse *pParse,
+ Window *pList, /* List of named windows for this SELECT */
+ Window *pWin, /* Window frame to update */
+ FuncDef *pFunc /* Window function definition */
+){
+ if( pWin->zName && pWin->eType==0 ){
+ Window *p;
+ for(p=pList; p; p=p->pNextWin){
+ if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
+ }
+ if( p==0 ){
+ sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
+ return;
+ }
+ pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
+ pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
+ pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
+ pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
+ pWin->eStart = p->eStart;
+ pWin->eEnd = p->eEnd;
+ pWin->eType = p->eType;
+ }
+ if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
+ sqlite3 *db = pParse->db;
+ if( pWin->pFilter ){
+ sqlite3ErrorMsg(pParse,
+ "FILTER clause may only be used with aggregate window functions"
+ );
+ }else
+ if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
+ sqlite3ExprDelete(db, pWin->pStart);
+ sqlite3ExprDelete(db, pWin->pEnd);
+ pWin->pStart = pWin->pEnd = 0;
+ pWin->eType = TK_ROWS;
+ pWin->eStart = TK_UNBOUNDED;
+ pWin->eEnd = TK_CURRENT;
+ }else
+
+ if( pFunc->zName==dense_rankName || pFunc->zName==rankName
+ || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
+ ){
+ sqlite3ExprDelete(db, pWin->pStart);
+ sqlite3ExprDelete(db, pWin->pEnd);
+ pWin->pStart = pWin->pEnd = 0;
+ pWin->eType = TK_RANGE;
+ pWin->eStart = TK_UNBOUNDED;
+ pWin->eEnd = TK_CURRENT;
+ }
+ }
+ pWin->pFunc = pFunc;
+}
+
+/*
+** Context object passed through sqlite3WalkExprList() to
+** selectWindowRewriteExprCb() by selectWindowRewriteEList().
+*/
+typedef struct WindowRewrite WindowRewrite;
+struct WindowRewrite {
+ Window *pWin;
+ SrcList *pSrc;
+ ExprList *pSub;
+ Select *pSubSelect; /* Current sub-select, if any */
+};
+
+/*
+** Callback function used by selectWindowRewriteEList(). If necessary,
+** this function appends to the output expression-list and updates
+** expression (*ppExpr) in place.
+*/
+static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
+ struct WindowRewrite *p = pWalker->u.pRewrite;
+ Parse *pParse = pWalker->pParse;
+
+ /* If this function is being called from within a scalar sub-select
+ ** that used by the SELECT statement being processed, only process
+ ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
+ ** not process aggregates or window functions at all, as they belong
+ ** to the scalar sub-select. */
+ if( p->pSubSelect ){
+ if( pExpr->op!=TK_COLUMN ){
+ return WRC_Continue;
+ }else{
+ int nSrc = p->pSrc->nSrc;
+ int i;
+ for(i=0; i<nSrc; i++){
+ if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
+ }
+ if( i==nSrc ) return WRC_Continue;
+ }
+ }
+
+ switch( pExpr->op ){
+
+ case TK_FUNCTION:
+ if( pExpr->pWin==0 ){
+ break;
+ }else{
+ Window *pWin;
+ for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
+ if( pExpr->pWin==pWin ){
+ assert( pWin->pOwner==pExpr );
+ return WRC_Prune;
+ }
+ }
+ }
+ /* Fall through. */
+
+ case TK_AGG_FUNCTION:
+ case TK_COLUMN: {
+ Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
+ p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
+ if( p->pSub ){
+ assert( ExprHasProperty(pExpr, EP_Static)==0 );
+ ExprSetProperty(pExpr, EP_Static);
+ sqlite3ExprDelete(pParse->db, pExpr);
+ ExprClearProperty(pExpr, EP_Static);
+ memset(pExpr, 0, sizeof(Expr));
+
+ pExpr->op = TK_COLUMN;
+ pExpr->iColumn = p->pSub->nExpr-1;
+ pExpr->iTable = p->pWin->iEphCsr;
+ }
+
+ break;
+ }
+
+ default: /* no-op */
+ break;
+ }
+
+ return WRC_Continue;
+}
+static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
+ struct WindowRewrite *p = pWalker->u.pRewrite;
+ Select *pSave = p->pSubSelect;
+ if( pSave==pSelect ){
+ return WRC_Continue;
+ }else{
+ p->pSubSelect = pSelect;
+ sqlite3WalkSelect(pWalker, pSelect);
+ p->pSubSelect = pSave;
+ }
+ return WRC_Prune;
+}
+
+
+/*
+** Iterate through each expression in expression-list pEList. For each:
+**
+** * TK_COLUMN,
+** * aggregate function, or
+** * window function with a Window object that is not a member of the
+** Window list passed as the second argument (pWin).
+**
+** Append the node to output expression-list (*ppSub). And replace it
+** with a TK_COLUMN that reads the (N-1)th element of table
+** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
+** appending the new one.
+*/
+static void selectWindowRewriteEList(
+ Parse *pParse,
+ Window *pWin,
+ SrcList *pSrc,
+ ExprList *pEList, /* Rewrite expressions in this list */
+ ExprList **ppSub /* IN/OUT: Sub-select expression-list */
+){
+ Walker sWalker;
+ WindowRewrite sRewrite;
+
+ memset(&sWalker, 0, sizeof(Walker));
+ memset(&sRewrite, 0, sizeof(WindowRewrite));
+
+ sRewrite.pSub = *ppSub;
+ sRewrite.pWin = pWin;
+ sRewrite.pSrc = pSrc;
+
+ sWalker.pParse = pParse;
+ sWalker.xExprCallback = selectWindowRewriteExprCb;
+ sWalker.xSelectCallback = selectWindowRewriteSelectCb;
+ sWalker.u.pRewrite = &sRewrite;
+
+ (void)sqlite3WalkExprList(&sWalker, pEList);
+
+ *ppSub = sRewrite.pSub;
+}
+
+/*
+** Append a copy of each expression in expression-list pAppend to
+** expression list pList. Return a pointer to the result list.
+*/
+static ExprList *exprListAppendList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to append. Might be NULL */
+ ExprList *pAppend /* List of values to append. Might be NULL */
+){
+ if( pAppend ){
+ int i;
+ int nInit = pList ? pList->nExpr : 0;
+ for(i=0; i<pAppend->nExpr; i++){
+ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
+ pList = sqlite3ExprListAppend(pParse, pList, pDup);
+ if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
+ }
+ }
+ return pList;
+}
+
+/*
+** If the SELECT statement passed as the second argument does not invoke
+** any SQL window functions, this function is a no-op. Otherwise, it
+** rewrites the SELECT statement so that window function xStep functions
+** are invoked in the correct order as described under "SELECT REWRITING"
+** at the top of this file.
+*/
+SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
+ int rc = SQLITE_OK;
+ if( p->pWin ){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ sqlite3 *db = pParse->db;
+ Select *pSub = 0; /* The subquery */
+ SrcList *pSrc = p->pSrc;
+ Expr *pWhere = p->pWhere;
+ ExprList *pGroupBy = p->pGroupBy;
+ Expr *pHaving = p->pHaving;
+ ExprList *pSort = 0;
+
+ ExprList *pSublist = 0; /* Expression list for sub-query */
+ Window *pMWin = p->pWin; /* Master window object */
+ Window *pWin; /* Window object iterator */
+
+ p->pSrc = 0;
+ p->pWhere = 0;
+ p->pGroupBy = 0;
+ p->pHaving = 0;
+
+ /* Create the ORDER BY clause for the sub-select. This is the concatenation
+ ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
+ ** redundant, remove the ORDER BY from the parent SELECT. */
+ pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
+ pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
+ if( pSort && p->pOrderBy ){
+ if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ p->pOrderBy = 0;
+ }
+ }
+
+ /* Assign a cursor number for the ephemeral table used to buffer rows.
+ ** The OpenEphemeral instruction is coded later, after it is known how
+ ** many columns the table will have. */
+ pMWin->iEphCsr = pParse->nTab++;
+
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+ pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
+
+ /* Append the PARTITION BY and ORDER BY expressions to the to the
+ ** sub-select expression list. They are required to figure out where
+ ** boundaries for partitions and sets of peer rows lie. */
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
+
+ /* Append the arguments passed to each window function to the
+ ** sub-select expression list. Also allocate two registers for each
+ ** window function - one for the accumulator, another for interim
+ ** results. */
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
+ pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
+ if( pWin->pFilter ){
+ Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
+ pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
+ }
+ pWin->regAccum = ++pParse->nMem;
+ pWin->regResult = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+ }
+
+ /* If there is no ORDER BY or PARTITION BY clause, and the window
+ ** function accepts zero arguments, and there are no other columns
+ ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
+ ** that pSublist is still NULL here. Add a constant expression here to
+ ** keep everything legal in this case.
+ */
+ if( pSublist==0 ){
+ pSublist = sqlite3ExprListAppend(pParse, 0,
+ sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
+ );
+ }
+
+ pSub = sqlite3SelectNew(
+ pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
+ );
+ p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ assert( p->pSrc || db->mallocFailed );
+ if( p->pSrc ){
+ p->pSrc->a[0].pSelect = pSub;
+ sqlite3SrcListAssignCursors(pParse, p->pSrc);
+ if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pSub->selFlags |= SF_Expanded;
+ p->selFlags &= ~SF_Aggregate;
+ sqlite3SelectPrep(pParse, pSub, 0);
+ }
+
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
+ }else{
+ sqlite3SelectDelete(db, pSub);
+ }
+ if( db->mallocFailed ) rc = SQLITE_NOMEM;
+ }
+
+ return rc;
+}
+
+/*
+** Free the Window object passed as the second argument.
+*/
+SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){
+ if( p ){
+ sqlite3ExprDelete(db, p->pFilter);
+ sqlite3ExprListDelete(db, p->pPartition);
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ sqlite3ExprDelete(db, p->pEnd);
+ sqlite3ExprDelete(db, p->pStart);
+ sqlite3DbFree(db, p->zName);
+ sqlite3DbFree(db, p);
+ }
+}
+
+/*
+** Free the linked list of Window objects starting at the second argument.
+*/
+SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
+ while( p ){
+ Window *pNext = p->pNextWin;
+ sqlite3WindowDelete(db, p);
+ p = pNext;
+ }
+}
+
+/*
+** The argument expression is an PRECEDING or FOLLOWING offset. The
+** value should be a non-negative integer. If the value is not a
+** constant, change it to NULL. The fact that it is then a non-negative
+** integer will be caught later. But it is important not to leave
+** variable values in the expression tree.
+*/
+static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
+ if( 0==sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ExprDelete(pParse->db, pExpr);
+ pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
+ }
+ return pExpr;
+}
+
+/*
+** Allocate and return a new Window object describing a Window Definition.
+*/
+SQLITE_PRIVATE Window *sqlite3WindowAlloc(
+ Parse *pParse, /* Parsing context */
+ int eType, /* Frame type. TK_RANGE or TK_ROWS */
+ int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
+ Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
+ int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
+ Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */
+){
+ Window *pWin = 0;
+
+ /* Parser assures the following: */
+ assert( eType==TK_RANGE || eType==TK_ROWS );
+ assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
+ || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
+ assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
+ || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
+ assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
+ assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
+
+
+ /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
+ ** either "<expr> PRECEDING" or "<expr> FOLLOWING".
+ */
+ if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
+ sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
+ goto windowAllocErr;
+ }
+
+ /* Additionally, the
+ ** starting boundary type may not occur earlier in the following list than
+ ** the ending boundary type:
+ **
+ ** UNBOUNDED PRECEDING
+ ** <expr> PRECEDING
+ ** CURRENT ROW
+ ** <expr> FOLLOWING
+ ** UNBOUNDED FOLLOWING
+ **
+ ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
+ ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
+ ** frame boundary.
+ */
+ if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
+ || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
+ ){
+ sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
+ goto windowAllocErr;
+ }
+
+ pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( pWin==0 ) goto windowAllocErr;
+ pWin->eType = eType;
+ pWin->eStart = eStart;
+ pWin->eEnd = eEnd;
+ pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
+ pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
+ return pWin;
+
+windowAllocErr:
+ sqlite3ExprDelete(pParse->db, pEnd);
+ sqlite3ExprDelete(pParse->db, pStart);
+ return 0;
+}
+
+/*
+** Attach window object pWin to expression p.
+*/
+SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
+ if( p ){
+ /* This routine is only called for the parser. If pWin was not
+ ** allocated due to an OOM, then the parser would fail before ever
+ ** invoking this routine */
+ if( ALWAYS(pWin) ){
+ p->pWin = pWin;
+ pWin->pOwner = p;
+ if( p->flags & EP_Distinct ){
+ sqlite3ErrorMsg(pParse,
+ "DISTINCT is not supported for window functions");
+ }
+ }
+ }else{
+ sqlite3WindowDelete(pParse->db, pWin);
+ }
+}
+
+/*
+** Return 0 if the two window objects are identical, or non-zero otherwise.
+** Identical window objects can be processed in a single scan.
+*/
+SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
+ if( p1->eType!=p2->eType ) return 1;
+ if( p1->eStart!=p2->eStart ) return 1;
+ if( p1->eEnd!=p2->eEnd ) return 1;
+ if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
+ if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
+ if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
+ if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
+ return 0;
+}
+
+
+/*
+** This is called by code in select.c before it calls sqlite3WhereBegin()
+** to begin iterating through the sub-query results. It is used to allocate
+** and initialize registers and cursors used by sqlite3WindowCodeStep().
+*/
+SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
+ Window *pWin;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
+ nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+ if( nPart ){
+ pMWin->regPart = pParse->nMem+1;
+ pParse->nMem += nPart;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
+ }
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *p = pWin->pFunc;
+ if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
+ /* The inline versions of min() and max() require a single ephemeral
+ ** table and 3 registers. The registers are used as follows:
+ **
+ ** regApp+0: slot to copy min()/max() argument to for MakeRecord
+ ** regApp+1: integer value used to ensure keys are unique
+ ** regApp+2: output of MakeRecord
+ */
+ ExprList *pList = pWin->pOwner->x.pList;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
+ pWin->csrApp = pParse->nTab++;
+ pWin->regApp = pParse->nMem+1;
+ pParse->nMem += 3;
+ if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
+ assert( pKeyInfo->aSortOrder[0]==0 );
+ pKeyInfo->aSortOrder[0] = 1;
+ }
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
+ sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
+ else if( p->zName==nth_valueName || p->zName==first_valueName ){
+ /* Allocate two registers at pWin->regApp. These will be used to
+ ** store the start and end index of the current frame. */
+ assert( pMWin->iEphCsr );
+ pWin->regApp = pParse->nMem+1;
+ pWin->csrApp = pParse->nTab++;
+ pParse->nMem += 2;
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
+ }
+ else if( p->zName==leadName || p->zName==lagName ){
+ assert( pMWin->iEphCsr );
+ pWin->csrApp = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
+ }
+ }
+}
+
+/*
+** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
+** value of the second argument to nth_value() (eCond==2) has just been
+** evaluated and the result left in register reg. This function generates VM
+** code to check that the value is a non-negative integer and throws an
+** exception if it is not.
+*/
+static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
+ static const char *azErr[] = {
+ "frame starting offset must be a non-negative integer",
+ "frame ending offset must be a non-negative integer",
+ "second argument to nth_value must be a positive integer"
+ };
+ static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int regZero = sqlite3GetTempReg(pParse);
+ assert( eCond==0 || eCond==1 || eCond==2 );
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverageIf(v, eCond==0);
+ VdbeCoverageIf(v, eCond==1);
+ VdbeCoverageIf(v, eCond==2);
+ sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
+ VdbeCoverageNeverNullIf(v, eCond==0);
+ VdbeCoverageNeverNullIf(v, eCond==1);
+ VdbeCoverageNeverNullIf(v, eCond==2);
+ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
+ sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
+ sqlite3ReleaseTempReg(pParse, regZero);
+}
+
+/*
+** Return the number of arguments passed to the window-function associated
+** with the object passed as the only argument to this function.
+*/
+static int windowArgCount(Window *pWin){
+ ExprList *pList = pWin->pOwner->x.pList;
+ return (pList ? pList->nExpr : 0);
+}
+
+/*
+** Generate VM code to invoke either xStep() (if bInverse is 0) or
+** xInverse (if bInverse is non-zero) for each window function in the
+** linked list starting at pMWin. Or, for built-in window functions
+** that do not use the standard function API, generate the required
+** inline VM code.
+**
+** If argument csr is greater than or equal to 0, then argument reg is
+** the first register in an array of registers guaranteed to be large
+** enough to hold the array of arguments for each function. In this case
+** the arguments are extracted from the current row of csr into the
+** array of registers before invoking OP_AggStep or OP_AggInverse
+**
+** Or, if csr is less than zero, then the array of registers at reg is
+** already populated with all columns from the current row of the sub-query.
+**
+** If argument regPartSize is non-zero, then it is a register containing the
+** number of rows in the current partition.
+*/
+static void windowAggStep(
+ Parse *pParse,
+ Window *pMWin, /* Linked list of window functions */
+ int csr, /* Read arguments from this cursor */
+ int bInverse, /* True to invoke xInverse instead of xStep */
+ int reg, /* Array of registers */
+ int regPartSize /* Register containing size of partition */
+){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ Window *pWin;
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ int flags = pWin->pFunc->funcFlags;
+ int regArg;
+ int nArg = windowArgCount(pWin);
+
+ if( csr>=0 ){
+ int i;
+ for(i=0; i<nArg; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
+ }
+ regArg = reg;
+ if( flags & SQLITE_FUNC_WINDOW_SIZE ){
+ if( nArg==0 ){
+ regArg = regPartSize;
+ }else{
+ sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
+ }
+ nArg++;
+ }
+ }else{
+ assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
+ regArg = reg + pWin->iArgCol;
+ }
+
+ if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && pWin->eStart!=TK_UNBOUNDED
+ ){
+ int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
+ VdbeCoverage(v);
+ if( bInverse==0 ){
+ sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
+ sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
+ }else{
+ sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ }
+ sqlite3VdbeJumpHere(v, addrIsNull);
+ }else if( pWin->regApp ){
+ assert( pWin->pFunc->zName==nth_valueName
+ || pWin->pFunc->zName==first_valueName
+ );
+ assert( bInverse==0 || bInverse==1 );
+ sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
+ }else if( pWin->pFunc->zName==leadName
+ || pWin->pFunc->zName==lagName
+ ){
+ /* no-op */
+ }else{
+ int addrIf = 0;
+ if( pWin->pFilter ){
+ int regTmp;
+ assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
+ assert( nArg || pWin->pOwner->x.pList==0 );
+ if( csr>0 ){
+ regTmp = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
+ }else{
+ regTmp = regArg + nArg;
+ }
+ addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
+ VdbeCoverage(v);
+ if( csr>0 ){
+ sqlite3ReleaseTempReg(pParse, regTmp);
+ }
+ }
+ if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ CollSeq *pColl;
+ assert( nArg>0 );
+ pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
+ sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
+ }
+ sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
+ bInverse, regArg, pWin->regAccum);
+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, (u8)nArg);
+ if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
+ }
+ }
+}
+
+/*
+** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
+** (bFinal==1) for each window function in the linked list starting at
+** pMWin. Or, for built-in window-functions that do not use the standard
+** API, generate the equivalent VM code.
+*/
+static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ Window *pWin;
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && pWin->eStart!=TK_UNBOUNDED
+ ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+ sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
+ if( bFinal ){
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
+ }
+ }else if( pWin->regApp ){
+ }else{
+ if( bFinal ){
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
+ pWin->regResult);
+ sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+ }
+ }
+ }
+}
+
+/*
+** This function generates VM code to invoke the sub-routine at address
+** lblFlushPart once for each partition with the entire partition cached in
+** the Window.iEphCsr temp table.
+*/
+static void windowPartitionCache(
+ Parse *pParse,
+ Select *p, /* The rewritten SELECT statement */
+ WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */
+ int regFlushPart, /* Register to use with Gosub lblFlushPart */
+ int lblFlushPart, /* Subroutine to Gosub to */
+ int *pRegSize /* OUT: Register containing partition size */
+){
+ Window *pMWin = p->pWin;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int iSubCsr = p->pSrc->a[0].iCursor;
+ int nSub = p->pSrc->a[0].pTab->nCol;
+ int k;
+
+ int reg = pParse->nMem+1;
+ int regRecord = reg+nSub;
+ int regRowid = regRecord+1;
+
+ *pRegSize = regRowid;
+ pParse->nMem += nSub + 2;
+
+ /* Load the column values for the row returned by the sub-select
+ ** into an array of registers starting at reg. */
+ for(k=0; k<nSub; k++){
+ sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
+
+ /* Check if this is the start of a new partition. If so, call the
+ ** flush_partition sub-routine. */
+ if( pMWin->pPartition ){
+ int addr;
+ ExprList *pPart = pMWin->pPartition;
+ int nPart = pPart->nExpr;
+ int regNewPart = reg + pMWin->nBufferCol;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
+ VdbeCoverageEqNe(v);
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
+ sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
+ VdbeComment((v, "call flush_partition"));
+ }
+
+ /* Buffer the current row in the ephemeral table. */
+ sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
+
+ /* End of the input loop */
+ sqlite3WhereEnd(pWInfo);
+
+ /* Invoke "flush_partition" to deal with the final (or only) partition */
+ sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
+ VdbeComment((v, "call flush_partition"));
+}
+
+/*
+** Invoke the sub-routine at regGosub (generated by code in select.c) to
+** return the current row of Window.iEphCsr. If all window functions are
+** aggregate window functions that use the standard API, a single
+** OP_Gosub instruction is all that this routine generates. Extra VM code
+** for per-row processing is only generated for the following built-in window
+** functions:
+**
+** nth_value()
+** first_value()
+** lag()
+** lead()
+*/
+static void windowReturnOneRow(
+ Parse *pParse,
+ Window *pMWin,
+ int regGosub,
+ int addrGosub
+){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ Window *pWin;
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
+ ){
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(v);
+ int tmpReg = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+
+ if( pFunc->zName==nth_valueName ){
+ sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
+ windowCheckIntValue(pParse, tmpReg, 2);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
+ }
+ sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
+ sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
+ }
+ else if( pFunc->zName==leadName || pFunc->zName==lagName ){
+ int nArg = pWin->pOwner->x.pList->nExpr;
+ int iEph = pMWin->iEphCsr;
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(v);
+ int tmpReg = sqlite3GetTempReg(pParse);
+
+ if( nArg<3 ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
+ if( nArg<2 ){
+ int val = (pFunc->zName==leadName ? 1 : -1);
+ sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
+ }else{
+ int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
+ int tmpReg2 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
+ sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
+ sqlite3ReleaseTempReg(pParse, tmpReg2);
+ }
+
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
+}
+
+/*
+** Invoke the code generated by windowReturnOneRow() and, optionally, the
+** xInverse() function for each window function, for one or more rows
+** from the Window.iEphCsr temp table. This routine generates VM code
+** similar to:
+**
+** while( regCtr>0 ){
+** regCtr--;
+** windowReturnOneRow()
+** if( bInverse ){
+** AggInverse
+** }
+** Next (Window.iEphCsr)
+** }
+*/
+static void windowReturnRows(
+ Parse *pParse,
+ Window *pMWin, /* List of window functions */
+ int regCtr, /* Register containing number of rows */
+ int regGosub, /* Register for Gosub addrGosub */
+ int addrGosub, /* Address of sub-routine for ReturnOneRow */
+ int regInvArg, /* Array of registers for xInverse args */
+ int regInvSize /* Register containing size of partition */
+){
+ int addr;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ windowAggFinal(pParse, pMWin, 0);
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
+ windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
+ if( regInvArg ){
+ windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
+ VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */
+}
+
+/*
+** Generate code to set the accumulator register for each window function
+** in the linked list passed as the second argument to NULL. And perform
+** any equivalent initialization required by any built-in window functions
+** in the list.
+*/
+static int windowInitAccum(Parse *pParse, Window *pMWin){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int regArg;
+ int nArg = 0;
+ Window *pWin;
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+ nArg = MAX(nArg, windowArgCount(pWin));
+ if( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
+ ){
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
+
+ if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
+ assert( pWin->eStart!=TK_UNBOUNDED );
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
+ }
+ regArg = pParse->nMem+1;
+ pParse->nMem += nArg;
+ return regArg;
+}
+
+
+/*
+** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
+** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
+** ROW". Pseudo-code for each follows.
+**
+** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
+**
+** ...
+** if( new partition ){
+** Gosub flush_partition
+** }
+** Insert (record in eph-table)
+** sqlite3WhereEnd()
+** Gosub flush_partition
+**
+** flush_partition:
+** Once {
+** OpenDup (iEphCsr -> csrStart)
+** OpenDup (iEphCsr -> csrEnd)
+** }
+** regStart = <expr1> // PRECEDING expression
+** regEnd = <expr2> // FOLLOWING expression
+** if( regStart<0 || regEnd<0 ){ error! }
+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
+** Next(csrEnd) // if EOF skip Aggstep
+** Aggstep (csrEnd)
+** if( (regEnd--)<=0 ){
+** AggFinal (xValue)
+** Gosub addrGosub
+** Next(csr) // if EOF goto flush_partition_done
+** if( (regStart--)<=0 ){
+** AggInverse (csrStart)
+** Next(csrStart)
+** }
+** }
+** flush_partition_done:
+** ResetSorter (csr)
+** Return
+**
+** ROWS BETWEEN <expr> PRECEDING AND CURRENT ROW
+** ROWS BETWEEN CURRENT ROW AND <expr> FOLLOWING
+** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
+**
+** These are similar to the above. For "CURRENT ROW", intialize the
+** register to 0. For "UNBOUNDED PRECEDING" to infinity.
+**
+** ROWS BETWEEN <expr> PRECEDING AND UNBOUNDED FOLLOWING
+** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+**
+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
+** while( 1 ){
+** Next(csrEnd) // Exit while(1) at EOF
+** Aggstep (csrEnd)
+** }
+** while( 1 ){
+** AggFinal (xValue)
+** Gosub addrGosub
+** Next(csr) // if EOF goto flush_partition_done
+** if( (regStart--)<=0 ){
+** AggInverse (csrStart)
+** Next(csrStart)
+** }
+** }
+**
+** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if()
+** condition is always true (as if regStart were initialized to 0).
+**
+** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+**
+** This is the only RANGE case handled by this routine. It modifies the
+** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
+** be:
+**
+** while( 1 ){
+** AggFinal (xValue)
+** while( 1 ){
+** regPeer++
+** Gosub addrGosub
+** Next(csr) // if EOF goto flush_partition_done
+** if( new peer ) break;
+** }
+** while( (regPeer--)>0 ){
+** AggInverse (csrStart)
+** Next(csrStart)
+** }
+** }
+**
+** ROWS BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING
+**
+** regEnd = regEnd - regStart
+** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
+** Aggstep (csrEnd)
+** Next(csrEnd) // if EOF fall-through
+** if( (regEnd--)<=0 ){
+** if( (regStart--)<=0 ){
+** AggFinal (xValue)
+** Gosub addrGosub
+** Next(csr) // if EOF goto flush_partition_done
+** }
+** AggInverse (csrStart)
+** Next (csrStart)
+** }
+**
+** ROWS BETWEEN <expr> PRECEDING AND <expr> PRECEDING
+**
+** Replace the bit after "Rewind" in the above with:
+**
+** if( (regEnd--)<=0 ){
+** AggStep (csrEnd)
+** Next (csrEnd)
+** }
+** AggFinal (xValue)
+** Gosub addrGosub
+** Next(csr) // if EOF goto flush_partition_done
+** if( (regStart--)<=0 ){
+** AggInverse (csr2)
+** Next (csr2)
+** }
+**
+*/
+static void windowCodeRowExprStep(
+ Parse *pParse,
+ Select *p,
+ WhereInfo *pWInfo,
+ int regGosub,
+ int addrGosub
+){
+ Window *pMWin = p->pWin;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int regFlushPart; /* Register for "Gosub flush_partition" */
+ int lblFlushPart; /* Label for "Gosub flush_partition" */
+ int lblFlushDone; /* Label for "Gosub flush_partition_done" */
+
+ int regArg;
+ int addr;
+ int csrStart = pParse->nTab++;
+ int csrEnd = pParse->nTab++;
+ int regStart; /* Value of <expr> PRECEDING */
+ int regEnd; /* Value of <expr> FOLLOWING */
+ int addrGoto;
+ int addrTop;
+ int addrIfPos1 = 0;
+ int addrIfPos2 = 0;
+ int regSize = 0;
+
+ assert( pMWin->eStart==TK_PRECEDING
+ || pMWin->eStart==TK_CURRENT
+ || pMWin->eStart==TK_FOLLOWING
+ || pMWin->eStart==TK_UNBOUNDED
+ );
+ assert( pMWin->eEnd==TK_FOLLOWING
+ || pMWin->eEnd==TK_CURRENT
+ || pMWin->eEnd==TK_UNBOUNDED
+ || pMWin->eEnd==TK_PRECEDING
+ );
+
+ /* Allocate register and label for the "flush_partition" sub-routine. */
+ regFlushPart = ++pParse->nMem;
+ lblFlushPart = sqlite3VdbeMakeLabel(v);
+ lblFlushDone = sqlite3VdbeMakeLabel(v);
+
+ regStart = ++pParse->nMem;
+ regEnd = ++pParse->nMem;
+
+ windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
+
+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+
+ /* Start of "flush_partition" */
+ sqlite3VdbeResolveLabel(v, lblFlushPart);
+ sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
+ VdbeCoverage(v);
+ VdbeComment((v, "Flush_partition subroutine"));
+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
+
+ /* If either regStart or regEnd are not non-negative integers, throw
+ ** an exception. */
+ if( pMWin->pStart ){
+ sqlite3ExprCode(pParse, pMWin->pStart, regStart);
+ windowCheckIntValue(pParse, regStart, 0);
+ }
+ if( pMWin->pEnd ){
+ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
+ windowCheckIntValue(pParse, regEnd, 1);
+ }
+
+ /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
+ **
+ ** if( regEnd<regStart ){
+ ** // The frame always consists of 0 rows
+ ** regStart = regSize;
+ ** }
+ ** regEnd = regEnd - regStart;
+ */
+ if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
+ assert( pMWin->pStart!=0 );
+ assert( pMWin->eEnd==TK_FOLLOWING );
+ sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
+ sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
+ }
+
+ if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
+ assert( pMWin->pEnd!=0 );
+ assert( pMWin->eStart==TK_PRECEDING );
+ sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
+ }
+
+ /* Initialize the accumulator register for each window function to NULL */
+ regArg = windowInitAccum(pParse, pMWin);
+
+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeChangeP5(v, 1);
+ sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeChangeP5(v, 1);
+
+ /* Invoke AggStep function for each window function using the row that
+ ** csrEnd currently points to. Or, if csrEnd is already at EOF,
+ ** do nothing. */
+ addrTop = sqlite3VdbeCurrentAddr(v);
+ if( pMWin->eEnd==TK_PRECEDING ){
+ addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ addr = sqlite3VdbeAddOp0(v, OP_Goto);
+ windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
+ if( pMWin->eEnd==TK_UNBOUNDED ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
+ sqlite3VdbeJumpHere(v, addr);
+ addrTop = sqlite3VdbeCurrentAddr(v);
+ }else{
+ sqlite3VdbeJumpHere(v, addr);
+ if( pMWin->eEnd==TK_PRECEDING ){
+ sqlite3VdbeJumpHere(v, addrIfPos1);
+ }
+ }
+
+ if( pMWin->eEnd==TK_FOLLOWING ){
+ addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
+ VdbeCoverage(v);
+ }
+ if( pMWin->eStart==TK_FOLLOWING ){
+ addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
+ VdbeCoverage(v);
+ }
+ windowAggFinal(pParse, pMWin, 0);
+ windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
+ if( pMWin->eStart==TK_FOLLOWING ){
+ sqlite3VdbeJumpHere(v, addrIfPos2);
+ }
+
+ if( pMWin->eStart==TK_CURRENT
+ || pMWin->eStart==TK_PRECEDING
+ || pMWin->eStart==TK_FOLLOWING
+ ){
+ int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
+ if( pMWin->eStart==TK_PRECEDING ){
+ sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
+ VdbeCoverage(v);
+ }
+ if( pMWin->eStart==TK_FOLLOWING ){
+ sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
+ VdbeCoverageAlwaysTaken(v);
+ }
+ windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
+ sqlite3VdbeResolveLabel(v, lblSkipInverse);
+ }
+ if( pMWin->eEnd==TK_FOLLOWING ){
+ sqlite3VdbeJumpHere(v, addrIfPos1);
+ }
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
+
+ /* flush_partition_done: */
+ sqlite3VdbeResolveLabel(v, lblFlushDone);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
+ VdbeComment((v, "end flush_partition subroutine"));
+
+ /* Jump to here to skip over flush_partition */
+ sqlite3VdbeJumpHere(v, addrGoto);
+}
+
+/*
+** This function does the work of sqlite3WindowCodeStep() for cases that
+** would normally be handled by windowCodeDefaultStep() when there are
+** one or more built-in window-functions that require the entire partition
+** to be cached in a temp table before any rows can be returned. Additionally.
+** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
+** this function.
+**
+** Pseudo-code corresponding to the VM code generated by this function
+** for each type of window follows.
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+**
+** flush_partition:
+** Once {
+** OpenDup (iEphCsr -> csrLead)
+** }
+** Integer ctr 0
+** foreach row (csrLead){
+** if( new peer ){
+** AggFinal (xValue)
+** for(i=0; i<ctr; i++){
+** Gosub addrGosub
+** Next iEphCsr
+** }
+** Integer ctr 0
+** }
+** AggStep (csrLead)
+** Incr ctr
+** }
+**
+** AggFinal (xFinalize)
+** for(i=0; i<ctr; i++){
+** Gosub addrGosub
+** Next iEphCsr
+** }
+**
+** ResetSorter (csr)
+** Return
+**
+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+**
+** As above, except that the "if( new peer )" branch is always taken.
+**
+** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
+**
+** As above, except that each of the for() loops becomes:
+**
+** for(i=0; i<ctr; i++){
+** Gosub addrGosub
+** AggInverse (iEphCsr)
+** Next iEphCsr
+** }
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+**
+** flush_partition:
+** Once {
+** OpenDup (iEphCsr -> csrLead)
+** }
+** foreach row (csrLead) {
+** AggStep (csrLead)
+** }
+** foreach row (iEphCsr) {
+** Gosub addrGosub
+** }
+**
+** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+**
+** flush_partition:
+** Once {
+** OpenDup (iEphCsr -> csrLead)
+** }
+** foreach row (csrLead){
+** AggStep (csrLead)
+** }
+** Rewind (csrLead)
+** Integer ctr 0
+** foreach row (csrLead){
+** if( new peer ){
+** AggFinal (xValue)
+** for(i=0; i<ctr; i++){
+** Gosub addrGosub
+** AggInverse (iEphCsr)
+** Next iEphCsr
+** }
+** Integer ctr 0
+** }
+** Incr ctr
+** }
+**
+** AggFinal (xFinalize)
+** for(i=0; i<ctr; i++){
+** Gosub addrGosub
+** Next iEphCsr
+** }
+**
+** ResetSorter (csr)
+** Return
+*/
+static void windowCodeCacheStep(
+ Parse *pParse,
+ Select *p,
+ WhereInfo *pWInfo,
+ int regGosub,
+ int addrGosub
+){
+ Window *pMWin = p->pWin;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int k;
+ int addr;
+ ExprList *pPart = pMWin->pPartition;
+ ExprList *pOrderBy = pMWin->pOrderBy;
+ int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
+ int regNewPeer;
+
+ int addrGoto; /* Address of Goto used to jump flush_par.. */
+ int addrNext; /* Jump here for next iteration of loop */
+ int regFlushPart;
+ int lblFlushPart;
+ int csrLead;
+ int regCtr;
+ int regArg; /* Register array to martial function args */
+ int regSize;
+ int lblEmpty;
+ int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT
+ && pMWin->eEnd==TK_UNBOUNDED;
+
+ assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED)
+ );
+
+ lblEmpty = sqlite3VdbeMakeLabel(v);
+ regNewPeer = pParse->nMem+1;
+ pParse->nMem += nPeer;
+
+ /* Allocate register and label for the "flush_partition" sub-routine. */
+ regFlushPart = ++pParse->nMem;
+ lblFlushPart = sqlite3VdbeMakeLabel(v);
+
+ csrLead = pParse->nTab++;
+ regCtr = ++pParse->nMem;
+
+ windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+
+ /* Start of "flush_partition" */
+ sqlite3VdbeResolveLabel(v, lblFlushPart);
+ sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
+
+ /* Initialize the accumulator register for each window function to NULL */
+ regArg = windowInitAccum(pParse, pMWin);
+
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
+ sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
+ VdbeCoverageNeverTaken(v);
+
+ if( bReverse ){
+ int addr2 = sqlite3VdbeCurrentAddr(v);
+ windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
+ sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
+ VdbeCoverageNeverTaken(v);
+ }
+ addrNext = sqlite3VdbeCurrentAddr(v);
+
+ if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
+ int bCurrent = (pMWin->eStart==TK_CURRENT);
+ int addrJump = 0; /* Address of OP_Jump below */
+ if( pMWin->eType==TK_RANGE ){
+ int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
+ int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
+ for(k=0; k<nPeer; k++){
+ sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
+ }
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
+ }
+
+ windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub,
+ (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
+ );
+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+ }
+
+ if( bReverse==0 ){
+ windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
+ }
+ sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
+ sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
+ VdbeCoverage(v);
+
+ windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
+
+ sqlite3VdbeResolveLabel(v, lblEmpty);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
+
+ /* Jump to here to skip over flush_partition */
+ sqlite3VdbeJumpHere(v, addrGoto);
+}
+
+
+/*
+** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+**
+** ...
+** if( new partition ){
+** AggFinal (xFinalize)
+** Gosub addrGosub
+** ResetSorter eph-table
+** }
+** else if( new peer ){
+** AggFinal (xValue)
+** Gosub addrGosub
+** ResetSorter eph-table
+** }
+** AggStep
+** Insert (record into eph-table)
+** sqlite3WhereEnd()
+** AggFinal (xFinalize)
+** Gosub addrGosub
+**
+** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+**
+** As above, except take no action for a "new peer". Invoke
+** the sub-routine once only for each partition.
+**
+** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
+**
+** As above, except that the "new peer" condition is handled in the
+** same way as "new partition" (so there is no "else if" block).
+**
+** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+**
+** As above, except assume every row is a "new peer".
+*/
+static void windowCodeDefaultStep(
+ Parse *pParse,
+ Select *p,
+ WhereInfo *pWInfo,
+ int regGosub,
+ int addrGosub
+){
+ Window *pMWin = p->pWin;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int k;
+ int iSubCsr = p->pSrc->a[0].iCursor;
+ int nSub = p->pSrc->a[0].pTab->nCol;
+ int reg = pParse->nMem+1;
+ int regRecord = reg+nSub;
+ int regRowid = regRecord+1;
+ int addr;
+ ExprList *pPart = pMWin->pPartition;
+ ExprList *pOrderBy = pMWin->pOrderBy;
+
+ assert( pMWin->eType==TK_RANGE
+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
+ );
+
+ assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
+ || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
+ || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
+ );
+
+ if( pMWin->eEnd==TK_UNBOUNDED ){
+ pOrderBy = 0;
+ }
+
+ pParse->nMem += nSub + 2;
+
+ /* Load the individual column values of the row returned by
+ ** the sub-select into an array of registers. */
+ for(k=0; k<nSub; k++){
+ sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
+ }
+
+ /* Check if this is the start of a new partition or peer group. */
+ if( pPart || pOrderBy ){
+ int nPart = (pPart ? pPart->nExpr : 0);
+ int addrGoto = 0;
+ int addrJump = 0;
+ int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
+
+ if( pPart ){
+ int regNewPart = reg + pMWin->nBufferCol;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
+ VdbeCoverageEqNe(v);
+ windowAggFinal(pParse, pMWin, 1);
+ if( pOrderBy ){
+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+ }
+ }
+
+ if( pOrderBy ){
+ int regNewPeer = reg + pMWin->nBufferCol + nPart;
+ int regPeer = pMWin->regPart + nPart;
+
+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+ if( pMWin->eType==TK_RANGE ){
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
+ VdbeCoverage(v);
+ }else{
+ addrJump = 0;
+ }
+ windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
+ if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
+ }
+
+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
+ VdbeCoverage(v);
+
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
+ sqlite3VdbeAddOp3(
+ v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
+ );
+
+ if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+ }
+
+ /* Invoke step function for window functions */
+ windowAggStep(pParse, pMWin, -1, 0, reg, 0);
+
+ /* Buffer the current row in the ephemeral table. */
+ if( pMWin->nBufferCol>0 ){
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
+ sqlite3VdbeAppendP4(v, (void*)"", 0);
+ }
+ sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
+
+ /* End the database scan loop. */
+ sqlite3WhereEnd(pWInfo);
+
+ windowAggFinal(pParse, pMWin, 1);
+ sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
+ sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
+ VdbeCoverage(v);
+}
+
+/*
+** Allocate and return a duplicate of the Window object indicated by the
+** third argument. Set the Window.pOwner field of the new object to
+** pOwner.
+*/
+SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
+ Window *pNew = 0;
+ if( p ){
+ pNew = sqlite3DbMallocZero(db, sizeof(Window));
+ if( pNew ){
+ pNew->zName = sqlite3DbStrDup(db, p->zName);
+ pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+ pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
+ pNew->eType = p->eType;
+ pNew->eEnd = p->eEnd;
+ pNew->eStart = p->eStart;
+ pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
+ pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
+ pNew->pOwner = pOwner;
+ }
+ }
+ return pNew;
+}
+
+/*
+** Return a copy of the linked list of Window objects passed as the
+** second argument.
+*/
+SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
+ Window *pWin;
+ Window *pRet = 0;
+ Window **pp = &pRet;
+
+ for(pWin=p; pWin; pWin=pWin->pNextWin){
+ *pp = sqlite3WindowDup(db, 0, pWin);
+ if( *pp==0 ) break;
+ pp = &((*pp)->pNextWin);
+ }
+
+ return pRet;
+}
+
+/*
+** sqlite3WhereBegin() has already been called for the SELECT statement
+** passed as the second argument when this function is invoked. It generates
+** code to populate the Window.regResult register for each window function and
+** invoke the sub-routine at instruction addrGosub once for each row.
+** This function calls sqlite3WhereEnd() before returning.
+*/
+SQLITE_PRIVATE void sqlite3WindowCodeStep(
+ Parse *pParse, /* Parse context */
+ Select *p, /* Rewritten SELECT statement */
+ WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */
+ int regGosub, /* Register for OP_Gosub */
+ int addrGosub /* OP_Gosub here to return each row */
+){
+ Window *pMWin = p->pWin;
+
+ /* There are three different functions that may be used to do the work
+ ** of this one, depending on the window frame and the specific built-in
+ ** window functions used (if any).
+ **
+ ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
+ **
+ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ **
+ ** The exception is because windowCodeRowExprStep() implements all window
+ ** frame types by caching the entire partition in a temp table, and
+ ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
+ ** implement without such a cache.
+ **
+ ** windowCodeCacheStep() is used for:
+ **
+ ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ **
+ ** It is also used for anything not handled by windowCodeRowExprStep()
+ ** that invokes a built-in window function that requires the entire
+ ** partition to be cached in a temp table before any rows are returned
+ ** (e.g. nth_value() or percent_rank()).
+ **
+ ** Finally, assuming there is no built-in window function that requires
+ ** the partition to be cached, windowCodeDefaultStep() is used for:
+ **
+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+ ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
+ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ **
+ ** windowCodeDefaultStep() is the only one of the three functions that
+ ** does not cache each partition in a temp table before beginning to
+ ** return rows.
+ */
+ if( pMWin->eType==TK_ROWS
+ && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
+ ){
+ VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
+ windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
+ }else{
+ Window *pWin;
+ int bCache = 0; /* True to use CacheStep() */
+
+ if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
+ bCache = 1;
+ }else{
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
+ || (pFunc->zName==nth_valueName)
+ || (pFunc->zName==first_valueName)
+ || (pFunc->zName==leadName)
+ || (pFunc->zName==lagName)
+ ){
+ bCache = 1;
+ break;
+ }
+ }
+ }
+
+ /* Otherwise, call windowCodeDefaultStep(). */
+ if( bCache ){
+ VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
+ windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
+ }else{
+ VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
+ windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
+ }
+ }
+}
+
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+/************** End of window.c **********************************************/
/************** Begin file parse.c *******************************************/
/*
** 2000-05-29
@@ -137221,15 +146336,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
#define YYMALLOCARGTYPE size_t
/*
-** An instance of this structure holds information about the
-** LIMIT clause of a SELECT statement.
-*/
-struct LimitVal {
- Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
- Expr *pOffset; /* The OFFSET expression. NULL if there is none */
-};
-
-/*
** An instance of the following structure describes the event of a
** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD. If the event is of the form
@@ -137240,6 +146346,8 @@ struct LimitVal {
*/
struct TrigEvent { int a; IdList * b; };
+struct FrameBound { int eType; Expr *pExpr; };
+
/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
@@ -137272,26 +146380,29 @@ static void disableLookaside(Parse *pParse){
}
}
- /* This is a utility routine used to set the ExprSpan.zStart and
- ** ExprSpan.zEnd values of pOut so that the span covers the complete
- ** range of text beginning with pStart and going to the end of pEnd.
- */
- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
- pOut->zStart = pStart->z;
- pOut->zEnd = &pEnd->z[pEnd->n];
- }
/* Construct a new Expr object from a single identifier. Use the
** 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 t){
+ static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
- memset(p, 0, sizeof(Expr));
+ /* memset(p, 0, sizeof(Expr)); */
p->op = (u8)op;
+ p->affinity = 0;
p->flags = EP_Leaf;
p->iAgg = -1;
+ p->pLeft = p->pRight = 0;
+ p->x.pList = 0;
+ p->pAggInfo = 0;
+ p->pTab = 0;
+ p->op2 = 0;
+ p->iTable = 0;
+ p->iColumn = 0;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ p->pWin = 0;
+#endif
p->u.zToken = (char*)&p[1];
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
@@ -137302,71 +146413,25 @@ static void disableLookaside(Parse *pParse){
#if SQLITE_MAX_EXPR_DEPTH>0
p->nHeight = 1;
#endif
+ if( IN_RENAME_OBJECT ){
+ return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t);
+ }
}
- pOut->pExpr = p;
- 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(
- Parse *pParse, /* The parsing context. Errors accumulate here */
- int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand, and output */
- ExprSpan *pRight /* The right operand */
- ){
- pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
- 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, ExprSpan *pSpan){
- if( doNot ){
- pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
- }
+ return p;
}
- /* Construct an expression node for a unary postfix operator
- */
- static void spanUnaryPostfix(
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand, and output */
- Token *pPostOp /* The operand token for setting the span */
- ){
- pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOperand->zEnd = &pPostOp->z[pPostOp->n];
- }
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
** unary TK_ISNULL or TK_NOTNULL expression. */
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
sqlite3 *db = pParse->db;
- if( pA && pY && pY->op==TK_NULL ){
+ if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){
pA->op = (u8)op;
sqlite3ExprDelete(db, pA->pRight);
pA->pRight = 0;
}
}
- /* Construct an expression node for a unary prefix operator
- */
- static void spanUnaryPrefix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPreOp /* The operand token for setting the span */
- ){
- pOut->zStart = pPreOp->z;
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOut->zEnd = pOperand->zEnd;
- }
-
/* Add a single new term to an ExprList that is used to store a
** list of identifiers. Report an error if the ID list contains
** a COLLATE clause or an ASC or DESC keyword, except ignore the
@@ -137429,65 +146494,78 @@ static void disableLookaside(Parse *pParse){
** zero the stack is dynamically sized using realloc()
** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument
+** sqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter
** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
+** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
+** YYNTOKEN Number of terminal symbols
** YY_MAX_SHIFT Maximum value for shift actions
** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** YY_MIN_REDUCE Minimum value for reduce actions
-** YY_MAX_REDUCE Maximum value for reduce actions
** YY_ERROR_ACTION The yy_action[] code for syntax error
** YY_ACCEPT_ACTION The yy_action[] code for accept
** YY_NO_ACTION The yy_action[] code for no-op
+** YY_MIN_REDUCE Minimum value for reduce actions
+** YY_MAX_REDUCE Maximum value for reduce actions
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
-#define YYCODETYPE unsigned char
-#define YYNOCODE 252
+#define YYCODETYPE unsigned short int
+#define YYNOCODE 277
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 83
+#define YYWILDCARD 91
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- Expr* yy72;
- TriggerStep* yy145;
- ExprList* yy148;
- SrcList* yy185;
- ExprSpan yy190;
- int yy194;
- Select* yy243;
- IdList* yy254;
- With* yy285;
- struct TrigEvent yy332;
- struct LimitVal yy354;
- struct {int value; int mask;} yy497;
+ Expr* yy18;
+ struct TrigEvent yy34;
+ IdList* yy48;
+ int yy70;
+ struct {int value; int mask;} yy111;
+ struct FrameBound yy119;
+ SrcList* yy135;
+ TriggerStep* yy207;
+ Window* yy327;
+ Upsert* yy340;
+ const char* yy392;
+ ExprList* yy420;
+ With* yy449;
+ Select* yy489;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
-#define sqlite3ParserARG_SDECL Parse *pParse;
-#define sqlite3ParserARG_PDECL ,Parse *pParse
-#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
-#define sqlite3ParserARG_STORE yypParser->pParse = pParse
+#define sqlite3ParserARG_SDECL
+#define sqlite3ParserARG_PDECL
+#define sqlite3ParserARG_PARAM
+#define sqlite3ParserARG_FETCH
+#define sqlite3ParserARG_STORE
+#define sqlite3ParserCTX_SDECL Parse *pParse;
+#define sqlite3ParserCTX_PDECL ,Parse *pParse
+#define sqlite3ParserCTX_PARAM ,pParse
+#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
+#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-#define YYNSTATE 459
-#define YYNRULE 329
-#define YY_MAX_SHIFT 458
-#define YY_MIN_SHIFTREDUCE 668
-#define YY_MAX_SHIFTREDUCE 996
-#define YY_MIN_REDUCE 997
-#define YY_MAX_REDUCE 1325
-#define YY_ERROR_ACTION 1326
-#define YY_ACCEPT_ACTION 1327
-#define YY_NO_ACTION 1328
+#define YYNSTATE 525
+#define YYNRULE 367
+#define YYNTOKEN 155
+#define YY_MAX_SHIFT 524
+#define YY_MIN_SHIFTREDUCE 760
+#define YY_MAX_SHIFTREDUCE 1126
+#define YY_ERROR_ACTION 1127
+#define YY_ACCEPT_ACTION 1128
+#define YY_NO_ACTION 1129
+#define YY_MIN_REDUCE 1130
+#define YY_MAX_REDUCE 1496
/************* End control #defines *******************************************/
+#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
@@ -137516,9 +146594,6 @@ typedef union {
** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
-** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
-** and YY_MAX_REDUCE
-**
** N == YY_ERROR_ACTION A syntax error has occurred.
**
** N == YY_ACCEPT_ACTION The parser accepts its input.
@@ -137526,25 +146601,22 @@ typedef union {
** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
+**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = yy_action[ yy_shift_ofst[S] + X ]
** (B) N = yy_default[S]
**
-** The (A) formula is preferred. The B formula is used instead if:
-** (1) The yy_shift_ofst[S]+X value is out of range, or
-** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
-** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
-** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
-** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
-** Hence only tests (1) and (2) need to be evaluated.)
+** The (A) formula is preferred. The B formula is used instead if
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
**
** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
-** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-** YY_SHIFT_USE_DFLT.
+** the yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
@@ -137558,463 +146630,569 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1569)
+#define YY_ACTTAB_COUNT (2009)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 328, 1327, 155, 155, 2, 203, 94, 94, 94, 93,
- /* 10 */ 354, 98, 98, 98, 98, 91, 95, 95, 94, 94,
- /* 20 */ 94, 93, 354, 272, 99, 100, 90, 975, 975, 851,
- /* 30 */ 854, 843, 843, 97, 97, 98, 98, 98, 98, 354,
- /* 40 */ 973, 96, 96, 96, 96, 95, 95, 94, 94, 94,
- /* 50 */ 93, 354, 954, 96, 96, 96, 96, 95, 95, 94,
- /* 60 */ 94, 94, 93, 354, 250, 96, 96, 96, 96, 95,
- /* 70 */ 95, 94, 94, 94, 93, 354, 224, 224, 973, 132,
- /* 80 */ 892, 352, 351, 419, 172, 328, 1290, 453, 418, 954,
- /* 90 */ 955, 956, 812, 981, 1036, 954, 304, 790, 432, 132,
- /* 100 */ 979, 366, 980, 9, 9, 791, 132, 52, 52, 99,
- /* 110 */ 100, 90, 975, 975, 851, 854, 843, 843, 97, 97,
- /* 120 */ 98, 98, 98, 98, 376, 982, 241, 982, 266, 373,
- /* 130 */ 265, 120, 954, 955, 956, 194, 58, 328, 405, 402,
- /* 140 */ 401, 812, 431, 433, 75, 812, 1264, 1264, 132, 400,
- /* 150 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 160 */ 354, 99, 100, 90, 975, 975, 851, 854, 843, 843,
- /* 170 */ 97, 97, 98, 98, 98, 98, 790, 266, 373, 265,
- /* 180 */ 830, 266, 368, 253, 791, 1088, 101, 1118, 72, 328,
- /* 190 */ 227, 1117, 242, 415, 446, 823, 92, 89, 178, 822,
- /* 200 */ 1026, 272, 96, 96, 96, 96, 95, 95, 94, 94,
- /* 210 */ 94, 93, 354, 99, 100, 90, 975, 975, 851, 854,
- /* 220 */ 843, 843, 97, 97, 98, 98, 98, 98, 453, 376,
- /* 230 */ 822, 822, 824, 92, 89, 178, 60, 92, 89, 178,
- /* 240 */ 1029, 328, 361, 934, 1320, 304, 61, 1320, 52, 52,
- /* 250 */ 840, 840, 852, 855, 96, 96, 96, 96, 95, 95,
- /* 260 */ 94, 94, 94, 93, 354, 99, 100, 90, 975, 975,
- /* 270 */ 851, 854, 843, 843, 97, 97, 98, 98, 98, 98,
- /* 280 */ 92, 89, 178, 431, 416, 198, 934, 1321, 458, 999,
- /* 290 */ 1321, 359, 1028, 328, 243, 231, 114, 281, 352, 351,
- /* 300 */ 1246, 954, 420, 1075, 932, 844, 96, 96, 96, 96,
- /* 310 */ 95, 95, 94, 94, 94, 93, 354, 99, 100, 90,
- /* 320 */ 975, 975, 851, 854, 843, 843, 97, 97, 98, 98,
- /* 330 */ 98, 98, 453, 332, 453, 120, 23, 260, 954, 955,
- /* 340 */ 956, 972, 982, 442, 982, 328, 333, 932, 958, 705,
- /* 350 */ 200, 175, 52, 52, 52, 52, 943, 357, 96, 96,
- /* 360 */ 96, 96, 95, 95, 94, 94, 94, 93, 354, 99,
- /* 370 */ 100, 90, 975, 975, 851, 854, 843, 843, 97, 97,
- /* 380 */ 98, 98, 98, 98, 358, 453, 958, 431, 421, 431,
- /* 390 */ 430, 1294, 92, 89, 178, 272, 257, 328, 259, 1062,
- /* 400 */ 1041, 698, 93, 354, 387, 52, 52, 384, 1062, 378,
- /* 410 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 420 */ 354, 99, 100, 90, 975, 975, 851, 854, 843, 843,
- /* 430 */ 97, 97, 98, 98, 98, 98, 228, 453, 167, 453,
- /* 440 */ 431, 411, 157, 450, 450, 450, 353, 353, 353, 328,
- /* 450 */ 314, 320, 995, 831, 324, 242, 415, 51, 51, 36,
- /* 460 */ 36, 258, 96, 96, 96, 96, 95, 95, 94, 94,
- /* 470 */ 94, 93, 354, 99, 100, 90, 975, 975, 851, 854,
- /* 480 */ 843, 843, 97, 97, 98, 98, 98, 98, 194, 320,
- /* 490 */ 933, 405, 402, 401, 224, 224, 1269, 943, 357, 1322,
- /* 500 */ 321, 328, 400, 1067, 1067, 817, 418, 1065, 1065, 954,
- /* 510 */ 303, 452, 996, 272, 96, 96, 96, 96, 95, 95,
- /* 520 */ 94, 94, 94, 93, 354, 99, 100, 90, 975, 975,
- /* 530 */ 851, 854, 843, 843, 97, 97, 98, 98, 98, 98,
- /* 540 */ 761, 1045, 453, 897, 897, 390, 954, 955, 956, 414,
- /* 550 */ 996, 751, 751, 328, 229, 272, 221, 300, 272, 775,
- /* 560 */ 894, 382, 52, 52, 894, 425, 96, 96, 96, 96,
- /* 570 */ 95, 95, 94, 94, 94, 93, 354, 99, 100, 90,
- /* 580 */ 975, 975, 851, 854, 843, 843, 97, 97, 98, 98,
- /* 590 */ 98, 98, 103, 453, 279, 388, 1245, 347, 157, 1211,
- /* 600 */ 913, 673, 674, 675, 176, 197, 196, 195, 328, 302,
- /* 610 */ 323, 1270, 2, 37, 37, 914, 1138, 1044, 96, 96,
- /* 620 */ 96, 96, 95, 95, 94, 94, 94, 93, 354, 701,
- /* 630 */ 915, 177, 99, 100, 90, 975, 975, 851, 854, 843,
- /* 640 */ 843, 97, 97, 98, 98, 98, 98, 230, 146, 120,
- /* 650 */ 739, 1239, 830, 274, 1145, 277, 1145, 775, 171, 170,
- /* 660 */ 740, 1145, 82, 328, 80, 272, 701, 823, 158, 272,
- /* 670 */ 382, 822, 78, 96, 96, 96, 96, 95, 95, 94,
- /* 680 */ 94, 94, 93, 354, 120, 954, 397, 99, 100, 90,
- /* 690 */ 975, 975, 851, 854, 843, 843, 97, 97, 98, 98,
- /* 700 */ 98, 98, 822, 822, 824, 1145, 1074, 374, 335, 133,
- /* 710 */ 1070, 1145, 1254, 198, 272, 328, 1020, 334, 245, 337,
- /* 720 */ 24, 338, 954, 955, 956, 372, 339, 81, 96, 96,
- /* 730 */ 96, 96, 95, 95, 94, 94, 94, 93, 354, 99,
- /* 740 */ 100, 90, 975, 975, 851, 854, 843, 843, 97, 97,
- /* 750 */ 98, 98, 98, 98, 132, 271, 264, 449, 334, 223,
- /* 760 */ 175, 1293, 929, 756, 728, 322, 1077, 328, 755, 246,
- /* 770 */ 389, 305, 305, 382, 333, 365, 348, 418, 1237, 284,
- /* 780 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
- /* 790 */ 354, 99, 88, 90, 975, 975, 851, 854, 843, 843,
- /* 800 */ 97, 97, 98, 98, 98, 98, 341, 350, 725, 726,
- /* 810 */ 453, 120, 118, 891, 162, 891, 814, 375, 328, 202,
- /* 820 */ 202, 377, 249, 267, 202, 398, 74, 708, 208, 1073,
- /* 830 */ 12, 12, 96, 96, 96, 96, 95, 95, 94, 94,
- /* 840 */ 94, 93, 354, 100, 90, 975, 975, 851, 854, 843,
- /* 850 */ 843, 97, 97, 98, 98, 98, 98, 453, 775, 232,
- /* 860 */ 453, 282, 120, 290, 74, 708, 718, 717, 328, 346,
- /* 870 */ 753, 881, 1213, 77, 289, 1259, 784, 52, 52, 202,
- /* 880 */ 27, 27, 422, 96, 96, 96, 96, 95, 95, 94,
- /* 890 */ 94, 94, 93, 354, 90, 975, 975, 851, 854, 843,
- /* 900 */ 843, 97, 97, 98, 98, 98, 98, 86, 448, 881,
- /* 910 */ 3, 1197, 426, 1017, 877, 439, 890, 208, 890, 693,
- /* 920 */ 1095, 261, 116, 826, 451, 1234, 117, 1233, 86, 448,
- /* 930 */ 177, 3, 385, 96, 96, 96, 96, 95, 95, 94,
- /* 940 */ 94, 94, 93, 354, 343, 451, 120, 355, 120, 212,
- /* 950 */ 169, 291, 408, 286, 407, 199, 775, 954, 437, 423,
- /* 960 */ 443, 826, 284, 695, 1043, 268, 273, 132, 355, 153,
- /* 970 */ 830, 380, 74, 276, 278, 280, 83, 84, 1058, 437,
- /* 980 */ 147, 1042, 447, 85, 355, 455, 454, 285, 132, 822,
- /* 990 */ 25, 830, 453, 120, 954, 955, 956, 83, 84, 86,
- /* 1000 */ 448, 695, 3, 412, 85, 355, 455, 454, 453, 5,
- /* 1010 */ 822, 203, 32, 32, 1111, 120, 451, 954, 225, 1144,
- /* 1020 */ 822, 822, 824, 825, 19, 203, 226, 954, 38, 38,
- /* 1030 */ 1091, 318, 318, 317, 215, 315, 120, 453, 682, 355,
- /* 1040 */ 237, 822, 822, 824, 825, 19, 973, 413, 381, 1,
- /* 1050 */ 437, 180, 710, 248, 954, 955, 956, 10, 10, 453,
- /* 1060 */ 973, 247, 830, 1102, 954, 955, 956, 434, 83, 84,
- /* 1070 */ 760, 340, 954, 20, 435, 85, 355, 455, 454, 10,
- /* 1080 */ 10, 822, 86, 448, 973, 3, 954, 453, 306, 307,
- /* 1090 */ 182, 954, 1150, 342, 1025, 1019, 1008, 183, 973, 451,
- /* 1100 */ 132, 181, 76, 448, 21, 3, 453, 10, 10, 954,
- /* 1110 */ 955, 956, 822, 822, 824, 825, 19, 719, 1283, 451,
- /* 1120 */ 393, 233, 355, 954, 955, 956, 10, 10, 954, 955,
- /* 1130 */ 956, 1007, 218, 437, 1009, 329, 1277, 777, 293, 295,
- /* 1140 */ 428, 297, 355, 7, 159, 830, 367, 406, 319, 364,
- /* 1150 */ 252, 83, 84, 437, 1236, 720, 776, 263, 85, 355,
- /* 1160 */ 455, 454, 362, 379, 822, 830, 364, 363, 403, 1215,
- /* 1170 */ 157, 83, 84, 685, 98, 98, 98, 98, 85, 355,
- /* 1180 */ 455, 454, 327, 256, 822, 299, 1215, 1217, 1239, 173,
- /* 1190 */ 1041, 288, 438, 344, 1208, 822, 822, 824, 825, 19,
- /* 1200 */ 312, 234, 453, 234, 96, 96, 96, 96, 95, 95,
- /* 1210 */ 94, 94, 94, 93, 354, 822, 822, 824, 825, 19,
- /* 1220 */ 913, 120, 39, 39, 1207, 453, 168, 364, 453, 1280,
- /* 1230 */ 371, 453, 135, 453, 990, 914, 453, 1253, 453, 1251,
- /* 1240 */ 453, 205, 987, 453, 374, 40, 40, 1215, 41, 41,
- /* 1250 */ 915, 42, 42, 28, 28, 874, 29, 29, 31, 31,
- /* 1260 */ 43, 43, 383, 44, 44, 453, 59, 453, 336, 453,
- /* 1270 */ 436, 62, 144, 156, 453, 102, 453, 1133, 453, 251,
- /* 1280 */ 453, 429, 453, 130, 137, 45, 45, 11, 11, 46,
- /* 1290 */ 46, 254, 1204, 453, 105, 105, 47, 47, 48, 48,
- /* 1300 */ 33, 33, 49, 49, 1130, 453, 72, 255, 453, 369,
- /* 1310 */ 139, 453, 396, 50, 50, 453, 370, 453, 185, 453,
- /* 1320 */ 160, 140, 453, 141, 453, 34, 34, 453, 122, 122,
- /* 1330 */ 453, 123, 123, 453, 142, 124, 124, 56, 56, 35,
- /* 1340 */ 35, 453, 106, 106, 53, 53, 453, 107, 107, 453,
- /* 1350 */ 108, 108, 453, 104, 104, 453, 410, 453, 148, 453,
- /* 1360 */ 1140, 121, 121, 453, 189, 453, 119, 119, 453, 112,
- /* 1370 */ 112, 453, 111, 111, 1238, 109, 109, 110, 110, 55,
- /* 1380 */ 55, 1202, 756, 57, 57, 54, 54, 755, 26, 26,
- /* 1390 */ 386, 30, 30, 67, 1222, 392, 270, 1103, 219, 190,
- /* 1400 */ 154, 394, 275, 191, 325, 1010, 192, 409, 1061, 1060,
- /* 1410 */ 1059, 345, 1052, 710, 326, 1051, 1033, 424, 1099, 71,
- /* 1420 */ 1032, 287, 204, 1031, 292, 1292, 1100, 294, 6, 301,
- /* 1430 */ 1098, 1097, 296, 298, 79, 441, 349, 445, 73, 213,
- /* 1440 */ 427, 1016, 22, 456, 1188, 949, 214, 238, 216, 217,
- /* 1450 */ 457, 239, 240, 1005, 1000, 125, 309, 1081, 308, 310,
- /* 1460 */ 311, 126, 115, 235, 669, 356, 127, 166, 244, 179,
- /* 1470 */ 360, 113, 889, 887, 330, 331, 810, 136, 134, 128,
- /* 1480 */ 138, 742, 262, 184, 903, 143, 145, 63, 64, 65,
- /* 1490 */ 66, 129, 906, 186, 187, 902, 8, 13, 188, 269,
- /* 1500 */ 895, 984, 202, 161, 391, 149, 150, 684, 395, 289,
- /* 1510 */ 193, 283, 151, 399, 68, 14, 750, 15, 404, 69,
- /* 1520 */ 16, 131, 236, 829, 721, 828, 857, 70, 754, 4,
- /* 1530 */ 417, 174, 220, 222, 152, 783, 778, 77, 872, 74,
- /* 1540 */ 201, 858, 17, 856, 912, 206, 911, 207, 18, 861,
- /* 1550 */ 938, 163, 440, 210, 939, 164, 209, 165, 444, 860,
- /* 1560 */ 827, 316, 694, 87, 211, 313, 1285, 944, 1284,
+ /* 0 */ 372, 105, 102, 197, 105, 102, 197, 519, 1128, 1,
+ /* 10 */ 1, 524, 2, 1132, 519, 1196, 1175, 1460, 275, 374,
+ /* 20 */ 127, 1393, 1201, 1201, 1196, 1170, 178, 1209, 64, 64,
+ /* 30 */ 481, 891, 326, 432, 352, 37, 37, 812, 366, 892,
+ /* 40 */ 513, 513, 513, 112, 113, 103, 1104, 1104, 957, 960,
+ /* 50 */ 950, 950, 110, 110, 111, 111, 111, 111, 369, 252,
+ /* 60 */ 252, 519, 252, 252, 501, 519, 313, 519, 463, 519,
+ /* 70 */ 1083, 495, 516, 482, 6, 516, 813, 134, 502, 228,
+ /* 80 */ 194, 432, 37, 37, 519, 208, 64, 64, 64, 64,
+ /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107,
+ /* 100 */ 107, 106, 405, 258, 385, 13, 13, 402, 401, 432,
+ /* 110 */ 252, 252, 374, 480, 409, 1108, 1083, 1084, 1085, 390,
+ /* 120 */ 1110, 394, 501, 516, 501, 1427, 1423, 308, 1109, 311,
+ /* 130 */ 1260, 500, 374, 503, 16, 16, 112, 113, 103, 1104,
+ /* 140 */ 1104, 957, 960, 950, 950, 110, 110, 111, 111, 111,
+ /* 150 */ 111, 262, 1111, 499, 1111, 405, 112, 113, 103, 1104,
+ /* 160 */ 1104, 957, 960, 950, 950, 110, 110, 111, 111, 111,
+ /* 170 */ 111, 129, 1429, 347, 1424, 343, 1063, 496, 1061, 263,
+ /* 180 */ 73, 105, 102, 197, 998, 109, 109, 109, 109, 108,
+ /* 190 */ 108, 107, 107, 107, 106, 405, 374, 111, 111, 111,
+ /* 200 */ 111, 104, 496, 89, 1436, 109, 109, 109, 109, 108,
+ /* 210 */ 108, 107, 107, 107, 106, 405, 111, 111, 111, 111,
+ /* 220 */ 112, 113, 103, 1104, 1104, 957, 960, 950, 950, 110,
+ /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108,
+ /* 240 */ 108, 107, 107, 107, 106, 405, 114, 108, 108, 107,
+ /* 250 */ 107, 107, 106, 405, 109, 109, 109, 109, 108, 108,
+ /* 260 */ 107, 107, 107, 106, 405, 152, 403, 403, 403, 109,
+ /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 405,
+ /* 280 */ 178, 497, 1416, 438, 1041, 1490, 1083, 519, 1490, 374,
+ /* 290 */ 425, 301, 361, 416, 74, 1083, 109, 109, 109, 109,
+ /* 300 */ 108, 108, 107, 107, 107, 106, 405, 1417, 37, 37,
+ /* 310 */ 1435, 274, 510, 112, 113, 103, 1104, 1104, 957, 960,
+ /* 320 */ 950, 950, 110, 110, 111, 111, 111, 111, 1440, 524,
+ /* 330 */ 2, 1132, 1083, 1084, 1085, 434, 275, 1083, 127, 370,
+ /* 340 */ 937, 1083, 1084, 1085, 220, 1209, 917, 462, 459, 458,
+ /* 350 */ 396, 167, 519, 1039, 152, 449, 928, 457, 152, 878,
+ /* 360 */ 927, 293, 109, 109, 109, 109, 108, 108, 107, 107,
+ /* 370 */ 107, 106, 405, 13, 13, 261, 857, 252, 252, 227,
+ /* 380 */ 106, 405, 374, 1083, 1084, 1085, 315, 392, 1083, 300,
+ /* 390 */ 516, 927, 927, 929, 231, 327, 1259, 1392, 1427, 494,
+ /* 400 */ 274, 510, 12, 208, 274, 510, 112, 113, 103, 1104,
+ /* 410 */ 1104, 957, 960, 950, 950, 110, 110, 111, 111, 111,
+ /* 420 */ 111, 1444, 290, 1132, 292, 1083, 1101, 247, 275, 1102,
+ /* 430 */ 127, 391, 409, 393, 1083, 1084, 1085, 1209, 159, 238,
+ /* 440 */ 255, 325, 465, 320, 464, 225, 794, 105, 102, 197,
+ /* 450 */ 517, 318, 846, 846, 449, 109, 109, 109, 109, 108,
+ /* 460 */ 108, 107, 107, 107, 106, 405, 519, 518, 519, 252,
+ /* 470 */ 252, 1083, 1084, 1085, 439, 374, 1102, 937, 1464, 798,
+ /* 480 */ 274, 510, 516, 105, 102, 197, 340, 63, 63, 64,
+ /* 490 */ 64, 27, 794, 928, 291, 208, 1358, 927, 519, 112,
+ /* 500 */ 113, 103, 1104, 1104, 957, 960, 950, 950, 110, 110,
+ /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 405, 49,
+ /* 520 */ 49, 519, 28, 1083, 409, 501, 425, 301, 927, 927,
+ /* 530 */ 929, 186, 472, 1083, 471, 1003, 1003, 446, 519, 1083,
+ /* 540 */ 338, 519, 45, 45, 1087, 346, 173, 168, 109, 109,
+ /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 405, 13,
+ /* 560 */ 13, 205, 13, 13, 252, 252, 1199, 1199, 374, 1083,
+ /* 570 */ 1084, 1085, 791, 265, 5, 363, 498, 516, 473, 1083,
+ /* 580 */ 1084, 1085, 402, 401, 1083, 1083, 1084, 1085, 3, 282,
+ /* 590 */ 1083, 1087, 112, 113, 103, 1104, 1104, 957, 960, 950,
+ /* 600 */ 950, 110, 110, 111, 111, 111, 111, 252, 252, 1019,
+ /* 610 */ 220, 1083, 877, 462, 459, 458, 947, 947, 958, 961,
+ /* 620 */ 516, 252, 252, 457, 1020, 1083, 449, 1111, 1213, 1111,
+ /* 630 */ 1083, 1084, 1085, 519, 516, 430, 1083, 1084, 1085, 1021,
+ /* 640 */ 516, 109, 109, 109, 109, 108, 108, 107, 107, 107,
+ /* 650 */ 106, 405, 1056, 519, 50, 50, 519, 1083, 1084, 1085,
+ /* 660 */ 832, 374, 1055, 383, 415, 1068, 1362, 207, 412, 777,
+ /* 670 */ 833, 1083, 1084, 1085, 64, 64, 326, 64, 64, 1306,
+ /* 680 */ 951, 415, 414, 1362, 1364, 112, 113, 103, 1104, 1104,
+ /* 690 */ 957, 960, 950, 950, 110, 110, 111, 111, 111, 111,
+ /* 700 */ 298, 486, 519, 1041, 1491, 519, 438, 1491, 358, 1124,
+ /* 710 */ 487, 1000, 917, 489, 470, 1000, 132, 178, 33, 454,
+ /* 720 */ 1207, 136, 410, 64, 64, 483, 64, 64, 423, 373,
+ /* 730 */ 283, 1150, 252, 252, 109, 109, 109, 109, 108, 108,
+ /* 740 */ 107, 107, 107, 106, 405, 516, 224, 444, 415, 266,
+ /* 750 */ 1362, 266, 252, 252, 374, 300, 420, 286, 938, 400,
+ /* 760 */ 980, 474, 404, 252, 252, 516, 9, 477, 231, 504,
+ /* 770 */ 358, 1040, 1039, 1492, 359, 378, 516, 1125, 112, 113,
+ /* 780 */ 103, 1104, 1104, 957, 960, 950, 950, 110, 110, 111,
+ /* 790 */ 111, 111, 111, 252, 252, 1019, 519, 1351, 299, 252,
+ /* 800 */ 252, 252, 252, 1102, 379, 249, 516, 449, 876, 326,
+ /* 810 */ 1020, 484, 516, 195, 516, 438, 273, 15, 15, 519,
+ /* 820 */ 318, 519, 95, 519, 93, 1021, 371, 109, 109, 109,
+ /* 830 */ 109, 108, 108, 107, 107, 107, 106, 405, 519, 1125,
+ /* 840 */ 39, 39, 51, 51, 52, 52, 507, 374, 519, 1208,
+ /* 850 */ 1102, 922, 443, 345, 133, 440, 223, 222, 221, 53,
+ /* 860 */ 53, 326, 1404, 765, 766, 767, 519, 374, 88, 54,
+ /* 870 */ 54, 112, 113, 103, 1104, 1104, 957, 960, 950, 950,
+ /* 880 */ 110, 110, 111, 111, 111, 111, 411, 55, 55, 196,
+ /* 890 */ 519, 112, 113, 103, 1104, 1104, 957, 960, 950, 950,
+ /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1153, 380,
+ /* 910 */ 519, 40, 40, 519, 876, 519, 997, 519, 997, 116,
+ /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
+ /* 930 */ 405, 41, 41, 519, 43, 43, 44, 44, 56, 56,
+ /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
+ /* 950 */ 405, 519, 383, 519, 57, 57, 519, 803, 519, 383,
+ /* 960 */ 519, 449, 200, 519, 327, 519, 1401, 519, 1463, 519,
+ /* 970 */ 1291, 821, 58, 58, 14, 14, 519, 59, 59, 118,
+ /* 980 */ 118, 60, 60, 519, 46, 46, 61, 61, 62, 62,
+ /* 990 */ 47, 47, 519, 190, 189, 91, 519, 140, 140, 519,
+ /* 1000 */ 398, 519, 277, 1204, 141, 141, 519, 1119, 519, 996,
+ /* 1010 */ 519, 996, 519, 69, 69, 374, 278, 48, 48, 259,
+ /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120,
+ /* 1030 */ 120, 121, 121, 117, 117, 374, 519, 516, 387, 112,
+ /* 1040 */ 113, 103, 1104, 1104, 957, 960, 950, 950, 110, 110,
+ /* 1050 */ 111, 111, 111, 111, 519, 876, 519, 139, 139, 112,
+ /* 1060 */ 113, 103, 1104, 1104, 957, 960, 950, 950, 110, 110,
+ /* 1070 */ 111, 111, 111, 111, 1291, 138, 138, 125, 125, 519,
+ /* 1080 */ 12, 519, 281, 1291, 519, 449, 131, 1291, 109, 109,
+ /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 405, 519,
+ /* 1100 */ 124, 124, 122, 122, 519, 123, 123, 519, 109, 109,
+ /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 405, 519,
+ /* 1120 */ 68, 68, 467, 787, 519, 70, 70, 306, 67, 67,
+ /* 1130 */ 1036, 253, 253, 360, 1291, 191, 196, 1437, 469, 1305,
+ /* 1140 */ 38, 38, 388, 94, 516, 42, 42, 177, 852, 274,
+ /* 1150 */ 510, 389, 424, 851, 1360, 445, 512, 380, 381, 153,
+ /* 1160 */ 427, 876, 436, 374, 224, 251, 194, 891, 182, 297,
+ /* 1170 */ 787, 852, 88, 254, 470, 892, 851, 919, 811, 810,
+ /* 1180 */ 230, 1245, 914, 374, 17, 417, 801, 112, 113, 103,
+ /* 1190 */ 1104, 1104, 957, 960, 950, 950, 110, 110, 111, 111,
+ /* 1200 */ 111, 111, 399, 818, 819, 1179, 987, 112, 101, 103,
+ /* 1210 */ 1104, 1104, 957, 960, 950, 950, 110, 110, 111, 111,
+ /* 1220 */ 111, 111, 379, 426, 431, 433, 302, 230, 230, 88,
+ /* 1230 */ 1244, 455, 316, 801, 226, 88, 109, 109, 109, 109,
+ /* 1240 */ 108, 108, 107, 107, 107, 106, 405, 86, 437, 983,
+ /* 1250 */ 931, 885, 226, 987, 230, 419, 109, 109, 109, 109,
+ /* 1260 */ 108, 108, 107, 107, 107, 106, 405, 324, 849, 785,
+ /* 1270 */ 850, 100, 130, 100, 1407, 294, 374, 323, 1381, 1380,
+ /* 1280 */ 441, 1453, 303, 1241, 307, 310, 312, 314, 1192, 1178,
+ /* 1290 */ 1177, 1176, 319, 328, 329, 1232, 374, 931, 1253, 271,
+ /* 1300 */ 1290, 113, 103, 1104, 1104, 957, 960, 950, 950, 110,
+ /* 1310 */ 110, 111, 111, 111, 111, 1228, 1239, 506, 505, 1296,
+ /* 1320 */ 1225, 1159, 103, 1104, 1104, 957, 960, 950, 950, 110,
+ /* 1330 */ 110, 111, 111, 111, 111, 1152, 1141, 1140, 1142, 1447,
+ /* 1340 */ 450, 244, 184, 98, 511, 188, 4, 357, 331, 109,
+ /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 405,
+ /* 1360 */ 514, 333, 335, 199, 418, 460, 296, 289, 322, 109,
+ /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 405,
+ /* 1380 */ 11, 285, 1283, 406, 365, 192, 1175, 1355, 435, 509,
+ /* 1390 */ 350, 1354, 337, 98, 511, 508, 4, 187, 1450, 1119,
+ /* 1400 */ 233, 1400, 155, 1398, 1116, 152, 72, 75, 382, 429,
+ /* 1410 */ 514, 165, 115, 499, 937, 1280, 1275, 30, 149, 157,
+ /* 1420 */ 96, 96, 8, 284, 86, 288, 287, 97, 1272, 406,
+ /* 1430 */ 521, 520, 421, 406, 927, 422, 453, 210, 160, 161,
+ /* 1440 */ 162, 163, 362, 428, 1286, 508, 442, 214, 80, 364,
+ /* 1450 */ 31, 274, 510, 169, 1349, 448, 492, 245, 1369, 216,
+ /* 1460 */ 174, 491, 451, 309, 937, 927, 927, 929, 930, 24,
+ /* 1470 */ 96, 96, 305, 217, 367, 466, 1143, 97, 218, 406,
+ /* 1480 */ 521, 520, 1195, 1194, 927, 1193, 395, 803, 98, 511,
+ /* 1490 */ 368, 4, 1186, 1167, 1185, 269, 1166, 321, 1165, 1462,
+ /* 1500 */ 397, 270, 485, 476, 479, 514, 85, 232, 1236, 98,
+ /* 1510 */ 511, 330, 4, 490, 340, 927, 927, 929, 930, 24,
+ /* 1520 */ 1439, 1072, 408, 1237, 339, 256, 514, 1418, 406, 10,
+ /* 1530 */ 356, 356, 355, 241, 353, 181, 92, 774, 1235, 1218,
+ /* 1540 */ 508, 342, 87, 332, 334, 1217, 1234, 336, 344, 406,
+ /* 1550 */ 201, 492, 280, 183, 488, 348, 493, 349, 239, 937,
+ /* 1560 */ 279, 508, 1335, 29, 1149, 96, 96, 522, 1078, 272,
+ /* 1570 */ 243, 240, 97, 242, 406, 521, 520, 523, 1138, 927,
+ /* 1580 */ 937, 142, 1133, 1385, 143, 1386, 96, 96, 856, 376,
+ /* 1590 */ 203, 761, 154, 97, 1384, 406, 521, 520, 204, 377,
+ /* 1600 */ 927, 146, 144, 1383, 407, 1163, 1162, 128, 202, 71,
+ /* 1610 */ 927, 927, 929, 930, 24, 267, 1160, 185, 276, 198,
+ /* 1620 */ 257, 98, 511, 126, 4, 911, 995, 156, 993, 145,
+ /* 1630 */ 206, 927, 927, 929, 930, 24, 158, 835, 514, 209,
+ /* 1640 */ 295, 1009, 375, 164, 915, 147, 384, 274, 510, 386,
+ /* 1650 */ 166, 76, 77, 78, 148, 1012, 211, 212, 1008, 137,
+ /* 1660 */ 18, 406, 79, 213, 304, 1001, 1113, 230, 447, 215,
+ /* 1670 */ 413, 171, 32, 508, 323, 776, 170, 452, 172, 219,
+ /* 1680 */ 456, 81, 19, 20, 492, 317, 461, 82, 268, 491,
+ /* 1690 */ 150, 814, 937, 179, 83, 468, 151, 180, 96, 96,
+ /* 1700 */ 963, 84, 1044, 34, 475, 97, 1045, 406, 521, 520,
+ /* 1710 */ 1072, 408, 927, 35, 256, 884, 478, 248, 193, 356,
+ /* 1720 */ 356, 355, 241, 353, 250, 175, 774, 229, 879, 21,
+ /* 1730 */ 100, 98, 511, 22, 4, 1058, 1049, 176, 341, 201,
+ /* 1740 */ 7, 280, 1062, 927, 927, 929, 930, 24, 514, 279,
+ /* 1750 */ 88, 1060, 23, 978, 964, 962, 966, 1018, 1017, 967,
+ /* 1760 */ 235, 90, 511, 234, 4, 25, 36, 515, 932, 786,
+ /* 1770 */ 845, 406, 99, 26, 236, 237, 351, 1455, 514, 203,
+ /* 1780 */ 354, 1454, 1073, 508, 1129, 1129, 1129, 204, 1129, 1129,
+ /* 1790 */ 146, 1129, 1129, 1129, 1129, 1129, 1129, 202, 1129, 1129,
+ /* 1800 */ 1129, 406, 937, 1129, 1129, 1129, 1129, 1129, 96, 96,
+ /* 1810 */ 1129, 1129, 1129, 508, 1129, 97, 1129, 406, 521, 520,
+ /* 1820 */ 1129, 1129, 927, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1830 */ 1129, 375, 937, 1129, 1129, 1129, 274, 510, 96, 96,
+ /* 1840 */ 1129, 1129, 1129, 1129, 1129, 97, 1129, 406, 521, 520,
+ /* 1850 */ 1129, 1129, 927, 927, 927, 929, 930, 24, 1129, 413,
+ /* 1860 */ 1129, 1129, 1129, 256, 1129, 1129, 1129, 1129, 356, 356,
+ /* 1870 */ 355, 241, 353, 1129, 1129, 774, 1129, 1129, 1129, 1129,
+ /* 1880 */ 1129, 1129, 1129, 927, 927, 929, 930, 24, 201, 1129,
+ /* 1890 */ 280, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 279, 1129,
+ /* 1900 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1910 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1920 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 203, 1129,
+ /* 1930 */ 1129, 1129, 1129, 1129, 1129, 1129, 204, 1129, 1129, 146,
+ /* 1940 */ 1129, 1129, 1129, 1129, 1129, 1129, 202, 1129, 1129, 1129,
+ /* 1950 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1960 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1970 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 1980 */ 375, 1129, 1129, 1129, 1129, 274, 510, 1129, 1129, 1129,
+ /* 1990 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129,
+ /* 2000 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 413,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 144, 145, 146, 147, 24, 90, 91, 92, 93,
- /* 10 */ 94, 54, 55, 56, 57, 58, 88, 89, 90, 91,
- /* 20 */ 92, 93, 94, 152, 43, 44, 45, 46, 47, 48,
- /* 30 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 94,
- /* 40 */ 59, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 50 */ 93, 94, 59, 84, 85, 86, 87, 88, 89, 90,
- /* 60 */ 91, 92, 93, 94, 193, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 93, 94, 194, 195, 97, 79,
- /* 80 */ 11, 88, 89, 152, 26, 19, 171, 152, 206, 96,
- /* 90 */ 97, 98, 72, 100, 179, 59, 152, 31, 163, 79,
- /* 100 */ 107, 219, 109, 172, 173, 39, 79, 172, 173, 43,
- /* 110 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 120 */ 54, 55, 56, 57, 152, 132, 199, 134, 108, 109,
- /* 130 */ 110, 196, 96, 97, 98, 99, 209, 19, 102, 103,
- /* 140 */ 104, 72, 207, 208, 26, 72, 119, 120, 79, 113,
- /* 150 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 160 */ 94, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 170 */ 52, 53, 54, 55, 56, 57, 31, 108, 109, 110,
- /* 180 */ 82, 108, 109, 110, 39, 210, 68, 175, 130, 19,
- /* 190 */ 218, 175, 119, 120, 250, 97, 221, 222, 223, 101,
- /* 200 */ 172, 152, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 210 */ 92, 93, 94, 43, 44, 45, 46, 47, 48, 49,
- /* 220 */ 50, 51, 52, 53, 54, 55, 56, 57, 152, 152,
- /* 230 */ 132, 133, 134, 221, 222, 223, 66, 221, 222, 223,
- /* 240 */ 172, 19, 193, 22, 23, 152, 24, 26, 172, 173,
- /* 250 */ 46, 47, 48, 49, 84, 85, 86, 87, 88, 89,
- /* 260 */ 90, 91, 92, 93, 94, 43, 44, 45, 46, 47,
- /* 270 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 280 */ 221, 222, 223, 207, 208, 46, 22, 23, 148, 149,
- /* 290 */ 26, 242, 172, 19, 154, 218, 156, 23, 88, 89,
- /* 300 */ 241, 59, 163, 163, 83, 101, 84, 85, 86, 87,
- /* 310 */ 88, 89, 90, 91, 92, 93, 94, 43, 44, 45,
- /* 320 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 330 */ 56, 57, 152, 157, 152, 196, 196, 16, 96, 97,
- /* 340 */ 98, 26, 132, 250, 134, 19, 107, 83, 59, 23,
- /* 350 */ 211, 212, 172, 173, 172, 173, 1, 2, 84, 85,
- /* 360 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 43,
- /* 370 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 380 */ 54, 55, 56, 57, 244, 152, 97, 207, 208, 207,
- /* 390 */ 208, 185, 221, 222, 223, 152, 75, 19, 77, 179,
- /* 400 */ 180, 23, 93, 94, 228, 172, 173, 231, 188, 152,
- /* 410 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 420 */ 94, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 430 */ 52, 53, 54, 55, 56, 57, 193, 152, 123, 152,
- /* 440 */ 207, 208, 152, 168, 169, 170, 168, 169, 170, 19,
- /* 450 */ 160, 22, 23, 23, 164, 119, 120, 172, 173, 172,
- /* 460 */ 173, 140, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 470 */ 92, 93, 94, 43, 44, 45, 46, 47, 48, 49,
- /* 480 */ 50, 51, 52, 53, 54, 55, 56, 57, 99, 22,
- /* 490 */ 23, 102, 103, 104, 194, 195, 0, 1, 2, 247,
- /* 500 */ 248, 19, 113, 190, 191, 23, 206, 190, 191, 59,
- /* 510 */ 225, 152, 83, 152, 84, 85, 86, 87, 88, 89,
- /* 520 */ 90, 91, 92, 93, 94, 43, 44, 45, 46, 47,
- /* 530 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 540 */ 90, 181, 152, 108, 109, 110, 96, 97, 98, 115,
- /* 550 */ 83, 117, 118, 19, 193, 152, 23, 152, 152, 26,
- /* 560 */ 29, 152, 172, 173, 33, 152, 84, 85, 86, 87,
- /* 570 */ 88, 89, 90, 91, 92, 93, 94, 43, 44, 45,
- /* 580 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 590 */ 56, 57, 22, 152, 16, 64, 193, 207, 152, 193,
- /* 600 */ 12, 7, 8, 9, 152, 108, 109, 110, 19, 152,
- /* 610 */ 164, 146, 147, 172, 173, 27, 163, 181, 84, 85,
- /* 620 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 59,
- /* 630 */ 42, 98, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 640 */ 51, 52, 53, 54, 55, 56, 57, 238, 22, 196,
- /* 650 */ 62, 163, 82, 75, 152, 77, 152, 124, 88, 89,
- /* 660 */ 72, 152, 137, 19, 139, 152, 96, 97, 24, 152,
- /* 670 */ 152, 101, 138, 84, 85, 86, 87, 88, 89, 90,
- /* 680 */ 91, 92, 93, 94, 196, 59, 19, 43, 44, 45,
- /* 690 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 700 */ 56, 57, 132, 133, 134, 152, 193, 219, 245, 246,
- /* 710 */ 193, 152, 152, 46, 152, 19, 166, 167, 152, 217,
- /* 720 */ 232, 217, 96, 97, 98, 237, 217, 138, 84, 85,
- /* 730 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 43,
- /* 740 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 750 */ 54, 55, 56, 57, 79, 193, 238, 166, 167, 211,
- /* 760 */ 212, 23, 23, 116, 26, 26, 195, 19, 121, 152,
- /* 770 */ 217, 152, 152, 152, 107, 100, 217, 206, 163, 112,
- /* 780 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 790 */ 94, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 800 */ 52, 53, 54, 55, 56, 57, 187, 187, 7, 8,
- /* 810 */ 152, 196, 22, 132, 24, 134, 23, 23, 19, 26,
- /* 820 */ 26, 23, 152, 23, 26, 23, 26, 59, 26, 163,
- /* 830 */ 172, 173, 84, 85, 86, 87, 88, 89, 90, 91,
- /* 840 */ 92, 93, 94, 44, 45, 46, 47, 48, 49, 50,
- /* 850 */ 51, 52, 53, 54, 55, 56, 57, 152, 26, 238,
- /* 860 */ 152, 23, 196, 101, 26, 97, 100, 101, 19, 19,
- /* 870 */ 23, 59, 152, 26, 112, 152, 23, 172, 173, 26,
- /* 880 */ 172, 173, 19, 84, 85, 86, 87, 88, 89, 90,
- /* 890 */ 91, 92, 93, 94, 45, 46, 47, 48, 49, 50,
- /* 900 */ 51, 52, 53, 54, 55, 56, 57, 19, 20, 97,
- /* 910 */ 22, 23, 207, 163, 23, 163, 132, 26, 134, 23,
- /* 920 */ 213, 152, 26, 59, 36, 152, 22, 152, 19, 20,
- /* 930 */ 98, 22, 152, 84, 85, 86, 87, 88, 89, 90,
- /* 940 */ 91, 92, 93, 94, 94, 36, 196, 59, 196, 99,
- /* 950 */ 100, 101, 102, 103, 104, 105, 124, 59, 70, 96,
- /* 960 */ 163, 97, 112, 59, 181, 152, 152, 79, 59, 71,
- /* 970 */ 82, 19, 26, 152, 152, 152, 88, 89, 152, 70,
- /* 980 */ 22, 152, 163, 95, 96, 97, 98, 152, 79, 101,
- /* 990 */ 22, 82, 152, 196, 96, 97, 98, 88, 89, 19,
- /* 1000 */ 20, 97, 22, 163, 95, 96, 97, 98, 152, 22,
- /* 1010 */ 101, 24, 172, 173, 152, 196, 36, 59, 22, 152,
- /* 1020 */ 132, 133, 134, 135, 136, 24, 5, 59, 172, 173,
- /* 1030 */ 152, 10, 11, 12, 13, 14, 196, 152, 17, 59,
- /* 1040 */ 210, 132, 133, 134, 135, 136, 59, 207, 96, 22,
- /* 1050 */ 70, 30, 106, 32, 96, 97, 98, 172, 173, 152,
- /* 1060 */ 59, 40, 82, 152, 96, 97, 98, 152, 88, 89,
- /* 1070 */ 90, 186, 59, 22, 191, 95, 96, 97, 98, 172,
- /* 1080 */ 173, 101, 19, 20, 97, 22, 59, 152, 152, 152,
- /* 1090 */ 69, 59, 152, 186, 152, 152, 152, 76, 97, 36,
- /* 1100 */ 79, 80, 19, 20, 53, 22, 152, 172, 173, 96,
- /* 1110 */ 97, 98, 132, 133, 134, 135, 136, 35, 122, 36,
- /* 1120 */ 234, 186, 59, 96, 97, 98, 172, 173, 96, 97,
- /* 1130 */ 98, 152, 233, 70, 152, 114, 152, 124, 210, 210,
- /* 1140 */ 186, 210, 59, 198, 197, 82, 214, 65, 150, 152,
- /* 1150 */ 201, 88, 89, 70, 201, 73, 124, 239, 95, 96,
- /* 1160 */ 97, 98, 141, 239, 101, 82, 169, 170, 176, 152,
- /* 1170 */ 152, 88, 89, 21, 54, 55, 56, 57, 95, 96,
- /* 1180 */ 97, 98, 164, 214, 101, 214, 169, 170, 163, 184,
- /* 1190 */ 180, 175, 227, 111, 175, 132, 133, 134, 135, 136,
- /* 1200 */ 200, 183, 152, 185, 84, 85, 86, 87, 88, 89,
- /* 1210 */ 90, 91, 92, 93, 94, 132, 133, 134, 135, 136,
- /* 1220 */ 12, 196, 172, 173, 175, 152, 198, 230, 152, 155,
- /* 1230 */ 78, 152, 243, 152, 60, 27, 152, 159, 152, 159,
- /* 1240 */ 152, 122, 38, 152, 219, 172, 173, 230, 172, 173,
- /* 1250 */ 42, 172, 173, 172, 173, 103, 172, 173, 172, 173,
- /* 1260 */ 172, 173, 237, 172, 173, 152, 240, 152, 159, 152,
- /* 1270 */ 62, 240, 22, 220, 152, 129, 152, 205, 152, 204,
- /* 1280 */ 152, 126, 152, 43, 189, 172, 173, 172, 173, 172,
- /* 1290 */ 173, 204, 140, 152, 172, 173, 172, 173, 172, 173,
- /* 1300 */ 172, 173, 172, 173, 205, 152, 130, 201, 152, 18,
- /* 1310 */ 192, 152, 18, 172, 173, 152, 159, 152, 158, 152,
- /* 1320 */ 220, 192, 152, 192, 152, 172, 173, 152, 172, 173,
- /* 1330 */ 152, 172, 173, 152, 192, 172, 173, 172, 173, 172,
- /* 1340 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
- /* 1350 */ 172, 173, 152, 172, 173, 152, 90, 152, 189, 152,
- /* 1360 */ 189, 172, 173, 152, 158, 152, 172, 173, 152, 172,
- /* 1370 */ 173, 152, 172, 173, 201, 172, 173, 172, 173, 172,
- /* 1380 */ 173, 201, 116, 172, 173, 172, 173, 121, 172, 173,
- /* 1390 */ 159, 172, 173, 137, 236, 61, 235, 159, 159, 158,
- /* 1400 */ 22, 177, 159, 158, 177, 159, 158, 107, 174, 174,
- /* 1410 */ 174, 63, 182, 106, 177, 182, 174, 125, 216, 107,
- /* 1420 */ 176, 174, 159, 174, 215, 174, 216, 215, 22, 159,
- /* 1430 */ 216, 216, 215, 215, 137, 177, 94, 177, 128, 25,
- /* 1440 */ 127, 162, 26, 161, 224, 13, 153, 226, 153, 6,
- /* 1450 */ 151, 229, 229, 151, 151, 165, 203, 205, 204, 202,
- /* 1460 */ 201, 165, 178, 178, 4, 3, 165, 22, 142, 15,
- /* 1470 */ 81, 16, 23, 23, 249, 249, 120, 131, 246, 111,
- /* 1480 */ 123, 20, 16, 125, 1, 123, 131, 53, 53, 53,
- /* 1490 */ 53, 111, 96, 34, 122, 1, 5, 22, 107, 140,
- /* 1500 */ 67, 74, 26, 24, 41, 67, 107, 20, 19, 112,
- /* 1510 */ 105, 23, 22, 66, 22, 22, 116, 22, 66, 22,
- /* 1520 */ 22, 37, 66, 23, 28, 23, 23, 26, 23, 22,
- /* 1530 */ 26, 122, 23, 23, 22, 96, 124, 26, 23, 26,
- /* 1540 */ 34, 23, 34, 23, 23, 26, 23, 22, 34, 11,
- /* 1550 */ 23, 22, 24, 122, 23, 22, 26, 22, 24, 23,
- /* 1560 */ 23, 15, 23, 22, 122, 23, 122, 1, 122,
+ /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156,
+ /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19,
+ /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185,
+ /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39,
+ /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206,
+ /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163,
+ /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223,
+ /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185,
+ /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163,
+ /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198,
+ /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79,
+ /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46,
+ /* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46,
+ /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233,
+ /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96,
+ /* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56,
+ /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96,
+ /* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57,
+ /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96,
+ /* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98,
+ /* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97,
+ /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92,
+ /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19,
+ /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95,
+ /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185,
+ /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49,
+ /* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158,
+ /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184,
+ /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113,
+ /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132,
+ /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99,
+ /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26,
+ /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116,
+ /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275,
+ /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46,
+ /* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59,
+ /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108,
+ /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240,
+ /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96,
+ /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206,
+ /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23,
+ /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184,
+ /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43,
+ /* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184,
+ /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142,
+ /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59,
+ /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93,
+ /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184,
+ /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105,
+ /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105,
+ /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174,
+ /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12,
+ /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49,
+ /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143,
+ /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42,
+ /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107,
+ /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21,
+ /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237,
+ /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47,
+ /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23,
+ /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19,
+ /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175,
+ /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97,
+ /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195,
+ /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220,
+ /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174,
+ /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44,
+ /* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206,
+ /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163,
+ /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163,
+ /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94,
+ /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91,
+ /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205,
+ /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184,
+ /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184,
+ /* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107,
+ /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178,
+ /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22,
+ /* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185,
+ /* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163,
+ /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163,
+ /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184,
+ /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185,
+ /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163,
+ /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141,
+ /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230,
+ /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184,
+ /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43,
+ /* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43,
+ /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163,
+ /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93,
+ /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
+ /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93,
+ /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
+ /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185,
+ /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237,
+ /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127,
+ /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263,
+ /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23,
+ /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110,
+ /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45,
+ /* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45,
+ /* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26,
+ /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95,
+ /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23,
+ /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95,
+ /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23,
+ /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163,
+ /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193,
+ /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222,
+ /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163,
+ /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163,
+ /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92,
+ /* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92,
+ /* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244,
+ /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60,
+ /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104,
+ /* 1410 */ 36, 22, 137, 134, 90, 236, 217, 235, 43, 201,
+ /* 1420 */ 96, 97, 48, 216, 138, 213, 216, 103, 217, 105,
+ /* 1430 */ 106, 107, 18, 59, 110, 170, 18, 169, 204, 204,
+ /* 1440 */ 204, 204, 213, 213, 201, 71, 170, 169, 146, 236,
+ /* 1450 */ 235, 127, 128, 201, 213, 62, 82, 170, 253, 169,
+ /* 1460 */ 22, 87, 189, 170, 90, 141, 142, 143, 144, 145,
+ /* 1470 */ 96, 97, 252, 169, 189, 104, 170, 103, 169, 105,
+ /* 1480 */ 106, 107, 186, 186, 110, 186, 64, 115, 19, 20,
+ /* 1490 */ 189, 22, 194, 186, 194, 246, 188, 186, 186, 186,
+ /* 1500 */ 102, 246, 133, 189, 189, 36, 104, 170, 228, 19,
+ /* 1510 */ 20, 227, 22, 84, 22, 141, 142, 143, 144, 145,
+ /* 1520 */ 0, 1, 2, 228, 271, 5, 36, 269, 59, 22,
+ /* 1530 */ 10, 11, 12, 13, 14, 216, 146, 17, 228, 217,
+ /* 1540 */ 71, 216, 136, 227, 227, 217, 228, 227, 170, 59,
+ /* 1550 */ 30, 82, 32, 215, 135, 214, 87, 213, 25, 90,
+ /* 1560 */ 40, 71, 241, 26, 173, 96, 97, 172, 13, 243,
+ /* 1570 */ 6, 164, 103, 164, 105, 106, 107, 162, 162, 110,
+ /* 1580 */ 90, 176, 162, 182, 176, 182, 96, 97, 98, 266,
+ /* 1590 */ 70, 4, 263, 103, 182, 105, 106, 107, 78, 266,
+ /* 1600 */ 110, 81, 176, 182, 3, 182, 182, 190, 88, 182,
+ /* 1610 */ 141, 142, 143, 144, 145, 190, 182, 22, 151, 15,
+ /* 1620 */ 89, 19, 20, 16, 22, 128, 23, 139, 23, 119,
+ /* 1630 */ 24, 141, 142, 143, 144, 145, 131, 20, 36, 133,
+ /* 1640 */ 16, 1, 122, 131, 140, 119, 61, 127, 128, 37,
+ /* 1650 */ 139, 53, 53, 53, 119, 105, 34, 130, 1, 5,
+ /* 1660 */ 22, 59, 53, 104, 149, 68, 75, 26, 41, 130,
+ /* 1670 */ 150, 104, 24, 71, 120, 20, 68, 19, 22, 114,
+ /* 1680 */ 67, 22, 22, 22, 82, 23, 67, 22, 67, 87,
+ /* 1690 */ 37, 28, 90, 23, 138, 22, 153, 23, 96, 97,
+ /* 1700 */ 23, 26, 23, 22, 24, 103, 23, 105, 106, 107,
+ /* 1710 */ 1, 2, 110, 22, 5, 105, 24, 23, 130, 10,
+ /* 1720 */ 11, 12, 13, 14, 23, 22, 17, 34, 132, 34,
+ /* 1730 */ 26, 19, 20, 34, 22, 85, 23, 26, 24, 30,
+ /* 1740 */ 44, 32, 75, 141, 142, 143, 144, 145, 36, 40,
+ /* 1750 */ 26, 83, 34, 23, 23, 23, 23, 23, 23, 11,
+ /* 1760 */ 22, 19, 20, 26, 22, 22, 22, 26, 23, 23,
+ /* 1770 */ 124, 59, 22, 22, 130, 130, 23, 130, 36, 70,
+ /* 1780 */ 15, 130, 1, 71, 277, 277, 277, 78, 277, 277,
+ /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277,
+ /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97,
+ /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107,
+ /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277,
+ /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97,
+ /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107,
+ /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150,
+ /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11,
+ /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277,
+ /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277,
+ /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277,
+ /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277,
+ /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81,
+ /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277,
+ /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277,
+ /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277,
+ /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277,
};
-#define YY_SHIFT_USE_DFLT (1569)
-#define YY_SHIFT_COUNT (458)
-#define YY_SHIFT_MIN (-84)
-#define YY_SHIFT_MAX (1566)
-static const short yy_shift_ofst[] = {
- /* 0 */ 355, 888, 1021, 909, 1063, 1063, 1063, 1063, 20, -19,
- /* 10 */ 66, 66, 170, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
- /* 20 */ -7, -7, 36, 73, 69, 27, 118, 222, 274, 326,
- /* 30 */ 378, 430, 482, 534, 589, 644, 696, 696, 696, 696,
- /* 40 */ 696, 696, 696, 696, 696, 696, 696, 696, 696, 696,
- /* 50 */ 696, 696, 696, 748, 696, 799, 849, 849, 980, 1063,
- /* 60 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
- /* 70 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
- /* 80 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
- /* 90 */ 1083, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
- /* 100 */ 1063, 1063, 1063, 1063, -43, 1120, 1120, 1120, 1120, 1120,
- /* 110 */ -31, -72, -84, 242, 1152, 667, 210, 210, 242, 309,
- /* 120 */ 336, -55, 1569, 1569, 1569, 850, 850, 850, 626, 626,
- /* 130 */ 588, 588, 898, 221, 264, 242, 242, 242, 242, 242,
- /* 140 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
- /* 150 */ 242, 242, 242, 242, 242, 496, 675, 289, 289, 336,
- /* 160 */ 0, 0, 0, 0, 0, 0, 1569, 1569, 1569, 570,
- /* 170 */ 98, 98, 958, 389, 450, 968, 1013, 1032, 1027, 242,
- /* 180 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
- /* 190 */ 242, 242, 242, 242, 242, 1082, 1082, 1082, 242, 242,
- /* 200 */ 533, 242, 242, 242, 987, 242, 242, 1208, 242, 242,
- /* 210 */ 242, 242, 242, 242, 242, 242, 242, 242, 435, 531,
- /* 220 */ 1001, 1001, 1001, 832, 434, 1266, 594, 58, 863, 863,
- /* 230 */ 952, 58, 952, 946, 738, 239, 145, 863, 525, 145,
- /* 240 */ 145, 315, 647, 790, 1174, 1119, 1119, 1204, 1204, 1119,
- /* 250 */ 1250, 1146, 1155, 1240, 1146, 1155, 1176, 1291, 1291, 1291,
- /* 260 */ 1291, 1119, 1294, 1176, 1250, 1240, 1240, 1176, 1119, 1294,
- /* 270 */ 1256, 1334, 1119, 1119, 1294, 1378, 1119, 1294, 1119, 1294,
- /* 280 */ 1378, 1300, 1300, 1300, 1348, 1378, 1300, 1307, 1300, 1348,
- /* 290 */ 1300, 1300, 1292, 1312, 1292, 1312, 1292, 1312, 1292, 1312,
- /* 300 */ 1119, 1406, 1119, 1297, 1378, 1342, 1342, 1378, 1146, 1155,
- /* 310 */ 1310, 1313, 1176, 1414, 1416, 1432, 1432, 1443, 1443, 1443,
- /* 320 */ 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 204, 321,
- /* 330 */ 429, 467, 578, 497, 904, 739, 1051, 793, 794, 798,
- /* 340 */ 800, 802, 838, 768, 766, 801, 762, 847, 853, 812,
- /* 350 */ 891, 681, 784, 896, 864, 996, 1460, 1462, 1445, 1326,
- /* 360 */ 1454, 1389, 1455, 1449, 1450, 1356, 1346, 1368, 1357, 1461,
- /* 370 */ 1358, 1466, 1483, 1362, 1355, 1434, 1435, 1436, 1437, 1380,
- /* 380 */ 1396, 1459, 1372, 1494, 1491, 1475, 1391, 1359, 1433, 1476,
- /* 390 */ 1438, 1427, 1463, 1399, 1479, 1487, 1489, 1397, 1405, 1490,
- /* 400 */ 1447, 1492, 1493, 1488, 1495, 1452, 1496, 1497, 1456, 1484,
- /* 410 */ 1500, 1502, 1503, 1501, 1400, 1498, 1505, 1507, 1504, 1409,
- /* 420 */ 1509, 1510, 1439, 1506, 1512, 1412, 1511, 1508, 1513, 1514,
- /* 430 */ 1515, 1511, 1518, 1520, 1521, 1519, 1523, 1525, 1538, 1527,
- /* 440 */ 1529, 1528, 1530, 1531, 1533, 1534, 1530, 1536, 1535, 1537,
- /* 450 */ 1539, 1541, 1431, 1442, 1444, 1446, 1542, 1546, 1566,
+#define YY_SHIFT_COUNT (524)
+#define YY_SHIFT_MIN (0)
+#define YY_SHIFT_MAX (1858)
+static const unsigned short int yy_shift_ofst[] = {
+ /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712,
+ /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712,
+ /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236,
+ /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270,
+ /* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016,
+ /* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016,
+ /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277,
+ /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
+ /* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
+ /* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
+ /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712,
+ /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162,
+ /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531,
+ /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53,
+ /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597,
+ /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531,
+ /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
+ /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984,
+ /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250,
+ /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531,
+ /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531,
+ /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
+ /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531,
+ /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531,
+ /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370,
+ /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706,
+ /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136,
+ /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366,
+ /* 280 */ 1366, 1270, 1305, 1389, 1275, 1279, 1375, 1275, 1279, 1286,
+ /* 290 */ 1414, 1414, 1414, 1414, 1270, 1418, 1286, 1286, 1305, 1389,
+ /* 300 */ 1375, 1375, 1286, 1270, 1418, 1302, 1393, 1270, 1418, 1438,
+ /* 310 */ 1270, 1418, 1270, 1418, 1438, 1371, 1371, 1371, 1422, 1438,
+ /* 320 */ 1371, 1372, 1371, 1422, 1371, 1371, 1438, 1398, 1398, 1438,
+ /* 330 */ 1369, 1402, 1369, 1402, 1369, 1402, 1369, 1402, 1270, 1279,
+ /* 340 */ 1429, 1492, 1275, 1279, 1507, 1270, 1390, 1275, 1406, 1419,
+ /* 350 */ 1286, 1533, 1537, 1555, 1555, 1564, 1564, 1564, 2009, 2009,
+ /* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ /* 370 */ 2009, 2009, 2009, 2009, 570, 345, 686, 748, 50, 740,
+ /* 380 */ 1064, 1107, 469, 537, 1042, 1146, 1162, 1154, 1201, 1202,
+ /* 390 */ 1203, 1208, 1209, 1127, 1069, 1196, 1157, 1147, 1226, 1228,
+ /* 400 */ 1245, 775, 868, 1246, 1247, 1191, 1151, 1587, 1601, 1595,
+ /* 410 */ 1467, 1604, 1531, 1607, 1603, 1605, 1497, 1488, 1510, 1606,
+ /* 420 */ 1505, 1617, 1506, 1624, 1640, 1512, 1504, 1526, 1585, 1612,
+ /* 430 */ 1511, 1598, 1599, 1600, 1609, 1535, 1550, 1622, 1527, 1657,
+ /* 440 */ 1654, 1638, 1559, 1515, 1597, 1641, 1608, 1591, 1627, 1539,
+ /* 450 */ 1567, 1648, 1655, 1658, 1554, 1565, 1656, 1613, 1659, 1660,
+ /* 460 */ 1662, 1661, 1619, 1663, 1665, 1621, 1653, 1670, 1556, 1673,
+ /* 470 */ 1543, 1674, 1677, 1675, 1679, 1681, 1680, 1683, 1691, 1692,
+ /* 480 */ 1588, 1694, 1701, 1610, 1693, 1703, 1596, 1704, 1695, 1704,
+ /* 490 */ 1699, 1650, 1667, 1668, 1696, 1713, 1714, 1711, 1724, 1718,
+ /* 500 */ 1730, 1704, 1731, 1732, 1733, 1734, 1737, 1735, 1738, 1748,
+ /* 510 */ 1743, 1744, 1745, 1746, 1750, 1751, 1741, 1646, 1644, 1645,
+ /* 520 */ 1647, 1651, 1753, 1765, 1781,
};
-#define YY_REDUCE_USE_DFLT (-144)
-#define YY_REDUCE_COUNT (327)
-#define YY_REDUCE_MIN (-143)
-#define YY_REDUCE_MAX (1303)
+#define YY_REDUCE_COUNT (373)
+#define YY_REDUCE_MIN (-237)
+#define YY_REDUCE_MAX (1434)
static const short yy_reduce_ofst[] = {
- /* 0 */ -143, -65, 140, 840, 76, 180, 182, 233, 488, -25,
- /* 10 */ 12, 16, 59, 885, 907, 935, 390, 705, 954, 285,
- /* 20 */ 997, 1017, 1018, -118, 1025, 139, 171, 171, 171, 171,
- /* 30 */ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- /* 40 */ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
- /* 50 */ 171, 171, 171, 171, 171, 171, 171, 171, -69, 287,
- /* 60 */ 441, 658, 708, 856, 1050, 1073, 1076, 1079, 1081, 1084,
- /* 70 */ 1086, 1088, 1091, 1113, 1115, 1117, 1122, 1124, 1126, 1128,
- /* 80 */ 1130, 1141, 1153, 1156, 1159, 1163, 1165, 1167, 1170, 1172,
- /* 90 */ 1175, 1178, 1181, 1189, 1194, 1197, 1200, 1203, 1205, 1207,
- /* 100 */ 1211, 1213, 1216, 1219, 171, 171, 171, 171, 171, 171,
- /* 110 */ 171, 171, 171, 49, 176, 220, 275, 278, 290, 171,
- /* 120 */ 300, 171, 171, 171, 171, -85, -85, -85, -28, 77,
- /* 130 */ 313, 317, -56, 252, 252, 446, -129, 243, 361, 403,
- /* 140 */ 406, 513, 517, 409, 502, 518, 504, 509, 621, 553,
- /* 150 */ 562, 619, 559, 93, 620, 465, 453, 550, 591, 571,
- /* 160 */ 615, 666, 750, 752, 797, 819, 463, 548, -73, 28,
- /* 170 */ 68, 120, 257, 206, 359, 405, 413, 452, 457, 560,
- /* 180 */ 566, 617, 670, 720, 723, 769, 773, 775, 780, 813,
- /* 190 */ 814, 821, 822, 823, 826, 360, 436, 783, 829, 835,
- /* 200 */ 707, 862, 867, 878, 830, 911, 915, 883, 936, 937,
- /* 210 */ 940, 359, 942, 943, 944, 979, 982, 984, 886, 899,
- /* 220 */ 928, 929, 931, 707, 947, 945, 998, 949, 932, 969,
- /* 230 */ 918, 953, 924, 992, 1005, 1010, 1016, 971, 965, 1019,
- /* 240 */ 1049, 1000, 1028, 1074, 989, 1078, 1080, 1026, 1031, 1109,
- /* 250 */ 1053, 1072, 1075, 1095, 1099, 1087, 1106, 1118, 1129, 1131,
- /* 260 */ 1142, 1157, 1160, 1173, 1100, 1169, 1171, 1180, 1231, 1206,
- /* 270 */ 1158, 1161, 1238, 1239, 1241, 1224, 1243, 1245, 1246, 1248,
- /* 280 */ 1227, 1234, 1235, 1236, 1230, 1237, 1242, 1244, 1247, 1233,
- /* 290 */ 1249, 1251, 1202, 1209, 1210, 1212, 1214, 1217, 1215, 1218,
- /* 300 */ 1263, 1220, 1270, 1221, 1258, 1222, 1223, 1260, 1252, 1254,
- /* 310 */ 1253, 1257, 1259, 1279, 1282, 1293, 1295, 1299, 1302, 1303,
- /* 320 */ 1225, 1226, 1232, 1290, 1296, 1284, 1285, 1301,
+ /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156,
+ /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189,
+ /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554,
+ /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234,
+ /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
+ /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
+ /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
+ /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685,
+ /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793,
+ /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833,
+ /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916,
+ /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234,
+ /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14,
+ /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234,
+ /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180,
+ /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646,
+ /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652,
+ /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442,
+ /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126,
+ /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723,
+ /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111,
+ /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124,
+ /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135,
+ /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172,
+ /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139,
+ /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138,
+ /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200,
+ /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149,
+ /* 280 */ 1150, 1238, 1179, 1182, 1199, 1207, 1218, 1211, 1210, 1212,
+ /* 290 */ 1234, 1235, 1236, 1237, 1265, 1268, 1229, 1230, 1213, 1215,
+ /* 300 */ 1243, 1252, 1241, 1276, 1278, 1205, 1220, 1287, 1290, 1273,
+ /* 310 */ 1293, 1304, 1306, 1309, 1285, 1296, 1297, 1299, 1298, 1301,
+ /* 320 */ 1307, 1308, 1311, 1300, 1312, 1313, 1314, 1249, 1255, 1315,
+ /* 330 */ 1280, 1284, 1295, 1316, 1310, 1317, 1318, 1320, 1337, 1319,
+ /* 340 */ 1253, 1258, 1322, 1325, 1321, 1378, 1326, 1328, 1338, 1341,
+ /* 350 */ 1344, 1391, 1395, 1407, 1409, 1415, 1416, 1420, 1323, 1333,
+ /* 360 */ 1329, 1405, 1401, 1403, 1412, 1421, 1408, 1417, 1425, 1423,
+ /* 370 */ 1424, 1427, 1434, 1426,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1274, 1264, 1264, 1264, 1197, 1197, 1197, 1197, 1264, 1092,
- /* 10 */ 1121, 1121, 1248, 1326, 1326, 1326, 1326, 1326, 1326, 1196,
- /* 20 */ 1326, 1326, 1326, 1326, 1264, 1096, 1127, 1326, 1326, 1326,
- /* 30 */ 1326, 1198, 1199, 1326, 1326, 1326, 1247, 1249, 1137, 1136,
- /* 40 */ 1135, 1134, 1230, 1108, 1132, 1125, 1129, 1198, 1192, 1193,
- /* 50 */ 1191, 1195, 1199, 1326, 1128, 1162, 1176, 1161, 1326, 1326,
- /* 60 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 70 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 80 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 90 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 100 */ 1326, 1326, 1326, 1326, 1170, 1175, 1182, 1174, 1171, 1164,
- /* 110 */ 1163, 1165, 1166, 1326, 1015, 1063, 1326, 1326, 1326, 1167,
- /* 120 */ 1326, 1168, 1179, 1178, 1177, 1255, 1282, 1281, 1326, 1326,
- /* 130 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 140 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 150 */ 1326, 1326, 1326, 1326, 1326, 1274, 1264, 1021, 1021, 1326,
- /* 160 */ 1264, 1264, 1264, 1264, 1264, 1264, 1260, 1096, 1087, 1326,
- /* 170 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 180 */ 1252, 1250, 1326, 1212, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 190 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 200 */ 1326, 1326, 1326, 1326, 1092, 1326, 1326, 1326, 1326, 1326,
- /* 210 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1276, 1326, 1225,
- /* 220 */ 1092, 1092, 1092, 1094, 1076, 1086, 1001, 1131, 1110, 1110,
- /* 230 */ 1315, 1131, 1315, 1038, 1296, 1035, 1121, 1110, 1194, 1121,
- /* 240 */ 1121, 1093, 1086, 1326, 1318, 1101, 1101, 1317, 1317, 1101,
- /* 250 */ 1142, 1126, 1115, 1066, 1126, 1115, 1131, 1072, 1072, 1072,
- /* 260 */ 1072, 1101, 1012, 1131, 1142, 1066, 1066, 1131, 1101, 1012,
- /* 270 */ 1229, 1312, 1101, 1101, 1012, 1205, 1101, 1012, 1101, 1012,
- /* 280 */ 1205, 1064, 1064, 1064, 1053, 1205, 1064, 1038, 1064, 1053,
- /* 290 */ 1064, 1064, 1114, 1109, 1114, 1109, 1114, 1109, 1114, 1109,
- /* 300 */ 1101, 1200, 1101, 1326, 1205, 1209, 1209, 1205, 1126, 1115,
- /* 310 */ 1124, 1122, 1131, 1018, 1056, 1279, 1279, 1275, 1275, 1275,
- /* 320 */ 1323, 1323, 1260, 1291, 1291, 1040, 1040, 1291, 1326, 1326,
- /* 330 */ 1326, 1326, 1326, 1326, 1286, 1326, 1214, 1326, 1326, 1326,
- /* 340 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 350 */ 1326, 1326, 1326, 1326, 1326, 1147, 1326, 997, 1257, 1326,
- /* 360 */ 1326, 1256, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 370 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 380 */ 1326, 1326, 1314, 1326, 1326, 1326, 1326, 1326, 1326, 1228,
- /* 390 */ 1227, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 400 */ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 410 */ 1326, 1326, 1326, 1326, 1078, 1326, 1326, 1326, 1300, 1326,
- /* 420 */ 1326, 1326, 1326, 1326, 1326, 1326, 1123, 1326, 1116, 1326,
- /* 430 */ 1326, 1305, 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- /* 440 */ 1326, 1326, 1266, 1326, 1326, 1326, 1265, 1326, 1326, 1326,
- /* 450 */ 1326, 1326, 1149, 1326, 1148, 1152, 1326, 1006, 1326,
+ /* 0 */ 1496, 1496, 1496, 1344, 1127, 1233, 1127, 1127, 1127, 1344,
+ /* 10 */ 1344, 1344, 1127, 1263, 1263, 1395, 1158, 1127, 1127, 1127,
+ /* 20 */ 1127, 1127, 1127, 1127, 1343, 1127, 1127, 1127, 1127, 1127,
+ /* 30 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1269, 1127,
+ /* 40 */ 1127, 1127, 1127, 1127, 1345, 1346, 1127, 1127, 1127, 1394,
+ /* 50 */ 1396, 1279, 1278, 1277, 1276, 1377, 1250, 1274, 1267, 1271,
+ /* 60 */ 1339, 1340, 1338, 1342, 1346, 1345, 1127, 1270, 1310, 1324,
+ /* 70 */ 1309, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 80 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 90 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 100 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 110 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1318, 1323, 1329,
+ /* 120 */ 1322, 1319, 1312, 1311, 1313, 1314, 1127, 1148, 1197, 1127,
+ /* 130 */ 1127, 1127, 1127, 1413, 1412, 1127, 1127, 1158, 1315, 1316,
+ /* 140 */ 1326, 1325, 1402, 1452, 1451, 1127, 1127, 1127, 1127, 1127,
+ /* 150 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 160 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 170 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1158, 1154, 1304,
+ /* 180 */ 1303, 1422, 1154, 1257, 1127, 1408, 1233, 1224, 1127, 1127,
+ /* 190 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 200 */ 1127, 1399, 1397, 1127, 1359, 1127, 1127, 1127, 1127, 1127,
+ /* 210 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 220 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 230 */ 1127, 1127, 1229, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 240 */ 1127, 1127, 1127, 1446, 1127, 1372, 1211, 1229, 1229, 1229,
+ /* 250 */ 1229, 1231, 1212, 1210, 1223, 1158, 1134, 1488, 1273, 1252,
+ /* 260 */ 1252, 1485, 1273, 1273, 1485, 1172, 1466, 1169, 1263, 1263,
+ /* 270 */ 1263, 1252, 1341, 1230, 1223, 1127, 1488, 1238, 1238, 1487,
+ /* 280 */ 1487, 1238, 1282, 1288, 1268, 1257, 1200, 1268, 1257, 1273,
+ /* 290 */ 1206, 1206, 1206, 1206, 1238, 1145, 1273, 1273, 1282, 1288,
+ /* 300 */ 1200, 1200, 1273, 1238, 1145, 1376, 1482, 1238, 1145, 1352,
+ /* 310 */ 1238, 1145, 1238, 1145, 1352, 1198, 1198, 1198, 1187, 1352,
+ /* 320 */ 1198, 1172, 1198, 1187, 1198, 1198, 1352, 1356, 1356, 1352,
+ /* 330 */ 1256, 1251, 1256, 1251, 1256, 1251, 1256, 1251, 1238, 1257,
+ /* 340 */ 1421, 1127, 1268, 1257, 1347, 1238, 1127, 1268, 1266, 1264,
+ /* 350 */ 1273, 1151, 1190, 1449, 1449, 1445, 1445, 1445, 1493, 1493,
+ /* 360 */ 1408, 1461, 1158, 1158, 1158, 1158, 1461, 1174, 1174, 1158,
+ /* 370 */ 1158, 1158, 1158, 1461, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 380 */ 1456, 1127, 1361, 1242, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 390 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 400 */ 1127, 1127, 1127, 1127, 1127, 1127, 1293, 1127, 1130, 1405,
+ /* 410 */ 1127, 1127, 1403, 1127, 1127, 1127, 1127, 1127, 1127, 1243,
+ /* 420 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 430 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1484, 1127,
+ /* 440 */ 1127, 1127, 1127, 1127, 1127, 1375, 1374, 1127, 1127, 1240,
+ /* 450 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 460 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 470 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 480 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1265, 1127, 1420,
+ /* 490 */ 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1434, 1258, 1127,
+ /* 500 */ 1127, 1475, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127,
+ /* 510 */ 1127, 1127, 1127, 1127, 1127, 1127, 1470, 1214, 1295, 1127,
+ /* 520 */ 1294, 1298, 1127, 1139, 1127,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -138095,6 +147273,7 @@ static const YYCODETYPE yyFallback[] = {
0, /* ESCAPE => nothing */
0, /* ID => nothing */
59, /* COLUMNKW => ID */
+ 59, /* DO => ID */
59, /* FOR => ID */
59, /* IGNORE => ID */
59, /* INITIALLY => ID */
@@ -138109,11 +147288,18 @@ static const YYCODETYPE yyFallback[] = {
59, /* REPLACE => ID */
59, /* RESTRICT => ID */
59, /* ROW => ID */
+ 59, /* ROWS => ID */
59, /* TRIGGER => ID */
59, /* VACUUM => ID */
59, /* VIEW => ID */
59, /* VIRTUAL => ID */
59, /* WITH => ID */
+ 59, /* CURRENT => ID */
+ 59, /* FOLLOWING => ID */
+ 59, /* PARTITION => ID */
+ 59, /* PRECEDING => ID */
+ 59, /* RANGE => ID */
+ 59, /* UNBOUNDED => ID */
59, /* REINDEX => ID */
59, /* RENAME => ID */
59, /* CTIME_KW => ID */
@@ -138156,6 +147342,7 @@ struct yyParser {
int yyerrcnt; /* Shifts left before out of the error */
#endif
sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
+ sqlite3ParserCTX_SDECL /* A place to hold %extra_context */
#if YYSTACKDEPTH<=0
int yystksz; /* Current side of the stack */
yyStackEntry *yystack; /* The parser's stack */
@@ -138199,75 +147386,289 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
}
#endif /* NDEBUG */
-#ifndef NDEBUG
+#if defined(YYCOVERAGE) || !defined(NDEBUG)
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
- "$", "SEMI", "EXPLAIN", "QUERY",
- "PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
- "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
- "ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
- "TABLE", "CREATE", "IF", "NOT",
- "EXISTS", "TEMP", "LP", "RP",
- "AS", "WITHOUT", "COMMA", "ABORT",
- "ACTION", "AFTER", "ANALYZE", "ASC",
- "ATTACH", "BEFORE", "BY", "CASCADE",
- "CAST", "CONFLICT", "DATABASE", "DESC",
- "DETACH", "EACH", "FAIL", "OR",
- "AND", "IS", "MATCH", "LIKE_KW",
- "BETWEEN", "IN", "ISNULL", "NOTNULL",
- "NE", "EQ", "GT", "LE",
- "LT", "GE", "ESCAPE", "ID",
- "COLUMNKW", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "NO", "KEY", "OF",
- "OFFSET", "PRAGMA", "RAISE", "RECURSIVE",
- "REPLACE", "RESTRICT", "ROW", "TRIGGER",
- "VACUUM", "VIEW", "VIRTUAL", "WITH",
- "REINDEX", "RENAME", "CTIME_KW", "ANY",
- "BITAND", "BITOR", "LSHIFT", "RSHIFT",
- "PLUS", "MINUS", "STAR", "SLASH",
- "REM", "CONCAT", "COLLATE", "BITNOT",
- "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT",
- "DEFAULT", "NULL", "PRIMARY", "UNIQUE",
- "CHECK", "REFERENCES", "AUTOINCR", "ON",
- "INSERT", "DELETE", "UPDATE", "SET",
- "DEFERRABLE", "FOREIGN", "DROP", "UNION",
- "ALL", "EXCEPT", "INTERSECT", "SELECT",
- "VALUES", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "FLOAT", "BLOB", "INTEGER", "VARIABLE",
- "CASE", "WHEN", "THEN", "ELSE",
- "INDEX", "ALTER", "ADD", "error",
- "input", "cmdlist", "ecmd", "explain",
- "cmdx", "cmd", "transtype", "trans_opt",
- "nm", "savepoint_opt", "create_table", "create_table_args",
- "createkw", "temp", "ifnotexists", "dbnm",
- "columnlist", "conslist_opt", "table_options", "select",
- "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",
- "paren_exprlist", "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",
+ /* 0 */ "$",
+ /* 1 */ "SEMI",
+ /* 2 */ "EXPLAIN",
+ /* 3 */ "QUERY",
+ /* 4 */ "PLAN",
+ /* 5 */ "BEGIN",
+ /* 6 */ "TRANSACTION",
+ /* 7 */ "DEFERRED",
+ /* 8 */ "IMMEDIATE",
+ /* 9 */ "EXCLUSIVE",
+ /* 10 */ "COMMIT",
+ /* 11 */ "END",
+ /* 12 */ "ROLLBACK",
+ /* 13 */ "SAVEPOINT",
+ /* 14 */ "RELEASE",
+ /* 15 */ "TO",
+ /* 16 */ "TABLE",
+ /* 17 */ "CREATE",
+ /* 18 */ "IF",
+ /* 19 */ "NOT",
+ /* 20 */ "EXISTS",
+ /* 21 */ "TEMP",
+ /* 22 */ "LP",
+ /* 23 */ "RP",
+ /* 24 */ "AS",
+ /* 25 */ "WITHOUT",
+ /* 26 */ "COMMA",
+ /* 27 */ "ABORT",
+ /* 28 */ "ACTION",
+ /* 29 */ "AFTER",
+ /* 30 */ "ANALYZE",
+ /* 31 */ "ASC",
+ /* 32 */ "ATTACH",
+ /* 33 */ "BEFORE",
+ /* 34 */ "BY",
+ /* 35 */ "CASCADE",
+ /* 36 */ "CAST",
+ /* 37 */ "CONFLICT",
+ /* 38 */ "DATABASE",
+ /* 39 */ "DESC",
+ /* 40 */ "DETACH",
+ /* 41 */ "EACH",
+ /* 42 */ "FAIL",
+ /* 43 */ "OR",
+ /* 44 */ "AND",
+ /* 45 */ "IS",
+ /* 46 */ "MATCH",
+ /* 47 */ "LIKE_KW",
+ /* 48 */ "BETWEEN",
+ /* 49 */ "IN",
+ /* 50 */ "ISNULL",
+ /* 51 */ "NOTNULL",
+ /* 52 */ "NE",
+ /* 53 */ "EQ",
+ /* 54 */ "GT",
+ /* 55 */ "LE",
+ /* 56 */ "LT",
+ /* 57 */ "GE",
+ /* 58 */ "ESCAPE",
+ /* 59 */ "ID",
+ /* 60 */ "COLUMNKW",
+ /* 61 */ "DO",
+ /* 62 */ "FOR",
+ /* 63 */ "IGNORE",
+ /* 64 */ "INITIALLY",
+ /* 65 */ "INSTEAD",
+ /* 66 */ "NO",
+ /* 67 */ "KEY",
+ /* 68 */ "OF",
+ /* 69 */ "OFFSET",
+ /* 70 */ "PRAGMA",
+ /* 71 */ "RAISE",
+ /* 72 */ "RECURSIVE",
+ /* 73 */ "REPLACE",
+ /* 74 */ "RESTRICT",
+ /* 75 */ "ROW",
+ /* 76 */ "ROWS",
+ /* 77 */ "TRIGGER",
+ /* 78 */ "VACUUM",
+ /* 79 */ "VIEW",
+ /* 80 */ "VIRTUAL",
+ /* 81 */ "WITH",
+ /* 82 */ "CURRENT",
+ /* 83 */ "FOLLOWING",
+ /* 84 */ "PARTITION",
+ /* 85 */ "PRECEDING",
+ /* 86 */ "RANGE",
+ /* 87 */ "UNBOUNDED",
+ /* 88 */ "REINDEX",
+ /* 89 */ "RENAME",
+ /* 90 */ "CTIME_KW",
+ /* 91 */ "ANY",
+ /* 92 */ "BITAND",
+ /* 93 */ "BITOR",
+ /* 94 */ "LSHIFT",
+ /* 95 */ "RSHIFT",
+ /* 96 */ "PLUS",
+ /* 97 */ "MINUS",
+ /* 98 */ "STAR",
+ /* 99 */ "SLASH",
+ /* 100 */ "REM",
+ /* 101 */ "CONCAT",
+ /* 102 */ "COLLATE",
+ /* 103 */ "BITNOT",
+ /* 104 */ "ON",
+ /* 105 */ "INDEXED",
+ /* 106 */ "STRING",
+ /* 107 */ "JOIN_KW",
+ /* 108 */ "CONSTRAINT",
+ /* 109 */ "DEFAULT",
+ /* 110 */ "NULL",
+ /* 111 */ "PRIMARY",
+ /* 112 */ "UNIQUE",
+ /* 113 */ "CHECK",
+ /* 114 */ "REFERENCES",
+ /* 115 */ "AUTOINCR",
+ /* 116 */ "INSERT",
+ /* 117 */ "DELETE",
+ /* 118 */ "UPDATE",
+ /* 119 */ "SET",
+ /* 120 */ "DEFERRABLE",
+ /* 121 */ "FOREIGN",
+ /* 122 */ "DROP",
+ /* 123 */ "UNION",
+ /* 124 */ "ALL",
+ /* 125 */ "EXCEPT",
+ /* 126 */ "INTERSECT",
+ /* 127 */ "SELECT",
+ /* 128 */ "VALUES",
+ /* 129 */ "DISTINCT",
+ /* 130 */ "DOT",
+ /* 131 */ "FROM",
+ /* 132 */ "JOIN",
+ /* 133 */ "USING",
+ /* 134 */ "ORDER",
+ /* 135 */ "GROUP",
+ /* 136 */ "HAVING",
+ /* 137 */ "LIMIT",
+ /* 138 */ "WHERE",
+ /* 139 */ "INTO",
+ /* 140 */ "NOTHING",
+ /* 141 */ "FLOAT",
+ /* 142 */ "BLOB",
+ /* 143 */ "INTEGER",
+ /* 144 */ "VARIABLE",
+ /* 145 */ "CASE",
+ /* 146 */ "WHEN",
+ /* 147 */ "THEN",
+ /* 148 */ "ELSE",
+ /* 149 */ "INDEX",
+ /* 150 */ "ALTER",
+ /* 151 */ "ADD",
+ /* 152 */ "WINDOW",
+ /* 153 */ "OVER",
+ /* 154 */ "FILTER",
+ /* 155 */ "input",
+ /* 156 */ "cmdlist",
+ /* 157 */ "ecmd",
+ /* 158 */ "cmdx",
+ /* 159 */ "explain",
+ /* 160 */ "cmd",
+ /* 161 */ "transtype",
+ /* 162 */ "trans_opt",
+ /* 163 */ "nm",
+ /* 164 */ "savepoint_opt",
+ /* 165 */ "create_table",
+ /* 166 */ "create_table_args",
+ /* 167 */ "createkw",
+ /* 168 */ "temp",
+ /* 169 */ "ifnotexists",
+ /* 170 */ "dbnm",
+ /* 171 */ "columnlist",
+ /* 172 */ "conslist_opt",
+ /* 173 */ "table_options",
+ /* 174 */ "select",
+ /* 175 */ "columnname",
+ /* 176 */ "carglist",
+ /* 177 */ "typetoken",
+ /* 178 */ "typename",
+ /* 179 */ "signed",
+ /* 180 */ "plus_num",
+ /* 181 */ "minus_num",
+ /* 182 */ "scanpt",
+ /* 183 */ "ccons",
+ /* 184 */ "term",
+ /* 185 */ "expr",
+ /* 186 */ "onconf",
+ /* 187 */ "sortorder",
+ /* 188 */ "autoinc",
+ /* 189 */ "eidlist_opt",
+ /* 190 */ "refargs",
+ /* 191 */ "defer_subclause",
+ /* 192 */ "refarg",
+ /* 193 */ "refact",
+ /* 194 */ "init_deferred_pred_opt",
+ /* 195 */ "conslist",
+ /* 196 */ "tconscomma",
+ /* 197 */ "tcons",
+ /* 198 */ "sortlist",
+ /* 199 */ "eidlist",
+ /* 200 */ "defer_subclause_opt",
+ /* 201 */ "orconf",
+ /* 202 */ "resolvetype",
+ /* 203 */ "raisetype",
+ /* 204 */ "ifexists",
+ /* 205 */ "fullname",
+ /* 206 */ "selectnowith",
+ /* 207 */ "oneselect",
+ /* 208 */ "wqlist",
+ /* 209 */ "multiselect_op",
+ /* 210 */ "distinct",
+ /* 211 */ "selcollist",
+ /* 212 */ "from",
+ /* 213 */ "where_opt",
+ /* 214 */ "groupby_opt",
+ /* 215 */ "having_opt",
+ /* 216 */ "orderby_opt",
+ /* 217 */ "limit_opt",
+ /* 218 */ "window_clause",
+ /* 219 */ "values",
+ /* 220 */ "nexprlist",
+ /* 221 */ "sclp",
+ /* 222 */ "as",
+ /* 223 */ "seltablist",
+ /* 224 */ "stl_prefix",
+ /* 225 */ "joinop",
+ /* 226 */ "indexed_opt",
+ /* 227 */ "on_opt",
+ /* 228 */ "using_opt",
+ /* 229 */ "exprlist",
+ /* 230 */ "xfullname",
+ /* 231 */ "idlist",
+ /* 232 */ "with",
+ /* 233 */ "setlist",
+ /* 234 */ "insert_cmd",
+ /* 235 */ "idlist_opt",
+ /* 236 */ "upsert",
+ /* 237 */ "over_clause",
+ /* 238 */ "likeop",
+ /* 239 */ "between_op",
+ /* 240 */ "in_op",
+ /* 241 */ "paren_exprlist",
+ /* 242 */ "case_operand",
+ /* 243 */ "case_exprlist",
+ /* 244 */ "case_else",
+ /* 245 */ "uniqueflag",
+ /* 246 */ "collate",
+ /* 247 */ "nmnum",
+ /* 248 */ "trigger_decl",
+ /* 249 */ "trigger_cmd_list",
+ /* 250 */ "trigger_time",
+ /* 251 */ "trigger_event",
+ /* 252 */ "foreach_clause",
+ /* 253 */ "when_clause",
+ /* 254 */ "trigger_cmd",
+ /* 255 */ "trnm",
+ /* 256 */ "tridxby",
+ /* 257 */ "database_kw_opt",
+ /* 258 */ "key_opt",
+ /* 259 */ "add_column_fullname",
+ /* 260 */ "kwcolumn_opt",
+ /* 261 */ "create_vtab",
+ /* 262 */ "vtabarglist",
+ /* 263 */ "vtabarg",
+ /* 264 */ "vtabargtoken",
+ /* 265 */ "lp",
+ /* 266 */ "anylist",
+ /* 267 */ "windowdefn_list",
+ /* 268 */ "windowdefn",
+ /* 269 */ "window",
+ /* 270 */ "frame_opt",
+ /* 271 */ "part_opt",
+ /* 272 */ "filter_opt",
+ /* 273 */ "range_or_rows",
+ /* 274 */ "frame_bound",
+ /* 275 */ "frame_bound_s",
+ /* 276 */ "frame_bound_e",
};
-#endif /* NDEBUG */
+#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
@@ -138301,307 +147702,345 @@ static const char *const yyRuleName[] = {
/* 25 */ "typetoken ::= typename LP signed RP",
/* 26 */ "typetoken ::= typename LP signed COMMA signed RP",
/* 27 */ "typename ::= typename ID|STRING",
- /* 28 */ "ccons ::= CONSTRAINT nm",
- /* 29 */ "ccons ::= DEFAULT term",
- /* 30 */ "ccons ::= DEFAULT LP expr RP",
- /* 31 */ "ccons ::= DEFAULT PLUS term",
- /* 32 */ "ccons ::= DEFAULT MINUS term",
- /* 33 */ "ccons ::= DEFAULT ID|INDEXED",
- /* 34 */ "ccons ::= NOT NULL onconf",
- /* 35 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 36 */ "ccons ::= UNIQUE onconf",
- /* 37 */ "ccons ::= CHECK LP expr RP",
- /* 38 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
- /* 39 */ "ccons ::= defer_subclause",
- /* 40 */ "ccons ::= COLLATE ID|STRING",
- /* 41 */ "autoinc ::=",
- /* 42 */ "autoinc ::= AUTOINCR",
- /* 43 */ "refargs ::=",
- /* 44 */ "refargs ::= refargs refarg",
- /* 45 */ "refarg ::= MATCH nm",
- /* 46 */ "refarg ::= ON INSERT refact",
- /* 47 */ "refarg ::= ON DELETE refact",
- /* 48 */ "refarg ::= ON UPDATE refact",
- /* 49 */ "refact ::= SET NULL",
- /* 50 */ "refact ::= SET DEFAULT",
- /* 51 */ "refact ::= CASCADE",
- /* 52 */ "refact ::= RESTRICT",
- /* 53 */ "refact ::= NO ACTION",
- /* 54 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 55 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 56 */ "init_deferred_pred_opt ::=",
- /* 57 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 58 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 59 */ "conslist_opt ::=",
- /* 60 */ "tconscomma ::= COMMA",
- /* 61 */ "tcons ::= CONSTRAINT nm",
- /* 62 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
- /* 63 */ "tcons ::= UNIQUE LP sortlist RP onconf",
- /* 64 */ "tcons ::= CHECK LP expr RP onconf",
- /* 65 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
- /* 66 */ "defer_subclause_opt ::=",
- /* 67 */ "onconf ::=",
- /* 68 */ "onconf ::= ON CONFLICT resolvetype",
- /* 69 */ "orconf ::=",
- /* 70 */ "orconf ::= OR resolvetype",
- /* 71 */ "resolvetype ::= IGNORE",
- /* 72 */ "resolvetype ::= REPLACE",
- /* 73 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 74 */ "ifexists ::= IF EXISTS",
- /* 75 */ "ifexists ::=",
- /* 76 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
- /* 77 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 78 */ "cmd ::= select",
- /* 79 */ "select ::= with selectnowith",
- /* 80 */ "selectnowith ::= selectnowith multiselect_op oneselect",
- /* 81 */ "multiselect_op ::= UNION",
- /* 82 */ "multiselect_op ::= UNION ALL",
- /* 83 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 84 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 85 */ "values ::= VALUES LP nexprlist RP",
- /* 86 */ "values ::= values COMMA LP exprlist RP",
- /* 87 */ "distinct ::= DISTINCT",
- /* 88 */ "distinct ::= ALL",
- /* 89 */ "distinct ::=",
- /* 90 */ "sclp ::=",
- /* 91 */ "selcollist ::= sclp expr as",
- /* 92 */ "selcollist ::= sclp STAR",
- /* 93 */ "selcollist ::= sclp nm DOT STAR",
- /* 94 */ "as ::= AS nm",
- /* 95 */ "as ::=",
- /* 96 */ "from ::=",
- /* 97 */ "from ::= FROM seltablist",
- /* 98 */ "stl_prefix ::= seltablist joinop",
- /* 99 */ "stl_prefix ::=",
- /* 100 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 101 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
- /* 102 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 103 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 104 */ "dbnm ::=",
- /* 105 */ "dbnm ::= DOT nm",
- /* 106 */ "fullname ::= nm dbnm",
- /* 107 */ "joinop ::= COMMA|JOIN",
- /* 108 */ "joinop ::= JOIN_KW JOIN",
- /* 109 */ "joinop ::= JOIN_KW nm JOIN",
- /* 110 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 111 */ "on_opt ::= ON expr",
- /* 112 */ "on_opt ::=",
- /* 113 */ "indexed_opt ::=",
- /* 114 */ "indexed_opt ::= INDEXED BY nm",
- /* 115 */ "indexed_opt ::= NOT INDEXED",
- /* 116 */ "using_opt ::= USING LP idlist RP",
- /* 117 */ "using_opt ::=",
- /* 118 */ "orderby_opt ::=",
- /* 119 */ "orderby_opt ::= ORDER BY sortlist",
- /* 120 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 121 */ "sortlist ::= expr sortorder",
- /* 122 */ "sortorder ::= ASC",
- /* 123 */ "sortorder ::= DESC",
- /* 124 */ "sortorder ::=",
- /* 125 */ "groupby_opt ::=",
- /* 126 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 127 */ "having_opt ::=",
- /* 128 */ "having_opt ::= HAVING expr",
- /* 129 */ "limit_opt ::=",
- /* 130 */ "limit_opt ::= LIMIT expr",
- /* 131 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 132 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 133 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt",
- /* 134 */ "where_opt ::=",
- /* 135 */ "where_opt ::= WHERE expr",
- /* 136 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt",
- /* 137 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 138 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 139 */ "setlist ::= nm EQ expr",
- /* 140 */ "setlist ::= LP idlist RP EQ expr",
- /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
- /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
- /* 143 */ "insert_cmd ::= INSERT orconf",
- /* 144 */ "insert_cmd ::= REPLACE",
- /* 145 */ "idlist_opt ::=",
- /* 146 */ "idlist_opt ::= LP idlist RP",
- /* 147 */ "idlist ::= idlist COMMA nm",
- /* 148 */ "idlist ::= nm",
- /* 149 */ "expr ::= LP expr RP",
- /* 150 */ "expr ::= ID|INDEXED",
- /* 151 */ "expr ::= JOIN_KW",
- /* 152 */ "expr ::= nm DOT nm",
- /* 153 */ "expr ::= nm DOT nm DOT nm",
- /* 154 */ "term ::= NULL|FLOAT|BLOB",
- /* 155 */ "term ::= STRING",
- /* 156 */ "term ::= INTEGER",
- /* 157 */ "expr ::= VARIABLE",
- /* 158 */ "expr ::= expr COLLATE ID|STRING",
- /* 159 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 160 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 161 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 162 */ "term ::= CTIME_KW",
- /* 163 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 164 */ "expr ::= expr AND expr",
- /* 165 */ "expr ::= expr OR expr",
- /* 166 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 167 */ "expr ::= expr EQ|NE expr",
- /* 168 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 169 */ "expr ::= expr PLUS|MINUS expr",
- /* 170 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 171 */ "expr ::= expr CONCAT expr",
- /* 172 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 173 */ "expr ::= expr likeop expr",
- /* 174 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 175 */ "expr ::= expr ISNULL|NOTNULL",
- /* 176 */ "expr ::= expr NOT NULL",
- /* 177 */ "expr ::= expr IS expr",
- /* 178 */ "expr ::= expr IS NOT expr",
- /* 179 */ "expr ::= NOT expr",
- /* 180 */ "expr ::= BITNOT expr",
- /* 181 */ "expr ::= MINUS expr",
- /* 182 */ "expr ::= PLUS expr",
- /* 183 */ "between_op ::= BETWEEN",
- /* 184 */ "between_op ::= NOT BETWEEN",
- /* 185 */ "expr ::= expr between_op expr AND expr",
- /* 186 */ "in_op ::= IN",
- /* 187 */ "in_op ::= NOT IN",
- /* 188 */ "expr ::= expr in_op LP exprlist RP",
- /* 189 */ "expr ::= LP select RP",
- /* 190 */ "expr ::= expr in_op LP select RP",
- /* 191 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 192 */ "expr ::= EXISTS LP select RP",
- /* 193 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 194 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 195 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 196 */ "case_else ::= ELSE expr",
- /* 197 */ "case_else ::=",
- /* 198 */ "case_operand ::= expr",
- /* 199 */ "case_operand ::=",
- /* 200 */ "exprlist ::=",
- /* 201 */ "nexprlist ::= nexprlist COMMA expr",
- /* 202 */ "nexprlist ::= expr",
- /* 203 */ "paren_exprlist ::=",
- /* 204 */ "paren_exprlist ::= LP exprlist RP",
- /* 205 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 206 */ "uniqueflag ::= UNIQUE",
- /* 207 */ "uniqueflag ::=",
- /* 208 */ "eidlist_opt ::=",
- /* 209 */ "eidlist_opt ::= LP eidlist RP",
- /* 210 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 211 */ "eidlist ::= nm collate sortorder",
- /* 212 */ "collate ::=",
- /* 213 */ "collate ::= COLLATE ID|STRING",
- /* 214 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 215 */ "cmd ::= VACUUM",
- /* 216 */ "cmd ::= VACUUM nm",
- /* 217 */ "cmd ::= PRAGMA nm dbnm",
- /* 218 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 219 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 220 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 221 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 222 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 223 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 224 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 225 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 226 */ "trigger_time ::= BEFORE|AFTER",
- /* 227 */ "trigger_time ::= INSTEAD OF",
- /* 228 */ "trigger_time ::=",
- /* 229 */ "trigger_event ::= DELETE|INSERT",
- /* 230 */ "trigger_event ::= UPDATE",
- /* 231 */ "trigger_event ::= UPDATE OF idlist",
- /* 232 */ "when_clause ::=",
- /* 233 */ "when_clause ::= WHEN expr",
- /* 234 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 235 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 236 */ "trnm ::= nm DOT nm",
- /* 237 */ "tridxby ::= INDEXED BY nm",
- /* 238 */ "tridxby ::= NOT INDEXED",
- /* 239 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 240 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
- /* 241 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 242 */ "trigger_cmd ::= select",
- /* 243 */ "expr ::= RAISE LP IGNORE RP",
- /* 244 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 245 */ "raisetype ::= ROLLBACK",
- /* 246 */ "raisetype ::= ABORT",
- /* 247 */ "raisetype ::= FAIL",
- /* 248 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 249 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 250 */ "cmd ::= DETACH database_kw_opt expr",
- /* 251 */ "key_opt ::=",
- /* 252 */ "key_opt ::= KEY expr",
- /* 253 */ "cmd ::= REINDEX",
- /* 254 */ "cmd ::= REINDEX nm dbnm",
- /* 255 */ "cmd ::= ANALYZE",
- /* 256 */ "cmd ::= ANALYZE nm dbnm",
- /* 257 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 258 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 259 */ "add_column_fullname ::= fullname",
- /* 260 */ "cmd ::= create_vtab",
- /* 261 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 262 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 263 */ "vtabarg ::=",
- /* 264 */ "vtabargtoken ::= ANY",
- /* 265 */ "vtabargtoken ::= lp anylist RP",
- /* 266 */ "lp ::= LP",
- /* 267 */ "with ::=",
- /* 268 */ "with ::= WITH wqlist",
- /* 269 */ "with ::= WITH RECURSIVE wqlist",
- /* 270 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 271 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 272 */ "input ::= cmdlist",
- /* 273 */ "cmdlist ::= cmdlist ecmd",
- /* 274 */ "cmdlist ::= ecmd",
- /* 275 */ "ecmd ::= SEMI",
- /* 276 */ "ecmd ::= explain cmdx SEMI",
- /* 277 */ "explain ::=",
- /* 278 */ "trans_opt ::=",
- /* 279 */ "trans_opt ::= TRANSACTION",
- /* 280 */ "trans_opt ::= TRANSACTION nm",
- /* 281 */ "savepoint_opt ::= SAVEPOINT",
- /* 282 */ "savepoint_opt ::=",
- /* 283 */ "cmd ::= create_table create_table_args",
- /* 284 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 285 */ "columnlist ::= columnname carglist",
- /* 286 */ "nm ::= ID|INDEXED",
- /* 287 */ "nm ::= STRING",
- /* 288 */ "nm ::= JOIN_KW",
- /* 289 */ "typetoken ::= typename",
- /* 290 */ "typename ::= ID|STRING",
- /* 291 */ "signed ::= plus_num",
- /* 292 */ "signed ::= minus_num",
- /* 293 */ "carglist ::= carglist ccons",
- /* 294 */ "carglist ::=",
- /* 295 */ "ccons ::= NULL onconf",
- /* 296 */ "conslist_opt ::= COMMA conslist",
- /* 297 */ "conslist ::= conslist tconscomma tcons",
- /* 298 */ "conslist ::= tcons",
- /* 299 */ "tconscomma ::=",
- /* 300 */ "defer_subclause_opt ::= defer_subclause",
- /* 301 */ "resolvetype ::= raisetype",
- /* 302 */ "selectnowith ::= oneselect",
- /* 303 */ "oneselect ::= values",
- /* 304 */ "sclp ::= selcollist COMMA",
- /* 305 */ "as ::= ID|STRING",
- /* 306 */ "expr ::= term",
- /* 307 */ "likeop ::= LIKE_KW|MATCH",
- /* 308 */ "exprlist ::= nexprlist",
- /* 309 */ "nmnum ::= plus_num",
- /* 310 */ "nmnum ::= nm",
- /* 311 */ "nmnum ::= ON",
- /* 312 */ "nmnum ::= DELETE",
- /* 313 */ "nmnum ::= DEFAULT",
- /* 314 */ "plus_num ::= INTEGER|FLOAT",
- /* 315 */ "foreach_clause ::=",
- /* 316 */ "foreach_clause ::= FOR EACH ROW",
- /* 317 */ "trnm ::= nm",
- /* 318 */ "tridxby ::=",
- /* 319 */ "database_kw_opt ::= DATABASE",
- /* 320 */ "database_kw_opt ::=",
- /* 321 */ "kwcolumn_opt ::=",
- /* 322 */ "kwcolumn_opt ::= COLUMNKW",
- /* 323 */ "vtabarglist ::= vtabarg",
- /* 324 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 325 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 326 */ "anylist ::=",
- /* 327 */ "anylist ::= anylist LP anylist RP",
- /* 328 */ "anylist ::= anylist ANY",
+ /* 28 */ "scanpt ::=",
+ /* 29 */ "ccons ::= CONSTRAINT nm",
+ /* 30 */ "ccons ::= DEFAULT scanpt term scanpt",
+ /* 31 */ "ccons ::= DEFAULT LP expr RP",
+ /* 32 */ "ccons ::= DEFAULT PLUS term scanpt",
+ /* 33 */ "ccons ::= DEFAULT MINUS term scanpt",
+ /* 34 */ "ccons ::= DEFAULT scanpt 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 wqlist selectnowith",
+ /* 81 */ "select ::= WITH RECURSIVE wqlist selectnowith",
+ /* 82 */ "select ::= selectnowith",
+ /* 83 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /* 84 */ "multiselect_op ::= UNION",
+ /* 85 */ "multiselect_op ::= UNION ALL",
+ /* 86 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
+ /* 89 */ "values ::= VALUES LP nexprlist RP",
+ /* 90 */ "values ::= values COMMA LP nexprlist RP",
+ /* 91 */ "distinct ::= DISTINCT",
+ /* 92 */ "distinct ::= ALL",
+ /* 93 */ "distinct ::=",
+ /* 94 */ "sclp ::=",
+ /* 95 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 96 */ "selcollist ::= sclp scanpt STAR",
+ /* 97 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 98 */ "as ::= AS nm",
+ /* 99 */ "as ::=",
+ /* 100 */ "from ::=",
+ /* 101 */ "from ::= FROM seltablist",
+ /* 102 */ "stl_prefix ::= seltablist joinop",
+ /* 103 */ "stl_prefix ::=",
+ /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 108 */ "dbnm ::=",
+ /* 109 */ "dbnm ::= DOT nm",
+ /* 110 */ "fullname ::= nm",
+ /* 111 */ "fullname ::= nm DOT nm",
+ /* 112 */ "xfullname ::= nm",
+ /* 113 */ "xfullname ::= nm DOT nm",
+ /* 114 */ "xfullname ::= nm DOT nm AS nm",
+ /* 115 */ "xfullname ::= nm AS nm",
+ /* 116 */ "joinop ::= COMMA|JOIN",
+ /* 117 */ "joinop ::= JOIN_KW JOIN",
+ /* 118 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 119 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 120 */ "on_opt ::= ON expr",
+ /* 121 */ "on_opt ::=",
+ /* 122 */ "indexed_opt ::=",
+ /* 123 */ "indexed_opt ::= INDEXED BY nm",
+ /* 124 */ "indexed_opt ::= NOT INDEXED",
+ /* 125 */ "using_opt ::= USING LP idlist RP",
+ /* 126 */ "using_opt ::=",
+ /* 127 */ "orderby_opt ::=",
+ /* 128 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 129 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 130 */ "sortlist ::= expr sortorder",
+ /* 131 */ "sortorder ::= ASC",
+ /* 132 */ "sortorder ::= DESC",
+ /* 133 */ "sortorder ::=",
+ /* 134 */ "groupby_opt ::=",
+ /* 135 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 136 */ "having_opt ::=",
+ /* 137 */ "having_opt ::= HAVING expr",
+ /* 138 */ "limit_opt ::=",
+ /* 139 */ "limit_opt ::= LIMIT expr",
+ /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 141 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt orderby_opt limit_opt",
+ /* 143 */ "where_opt ::=",
+ /* 144 */ "where_opt ::= WHERE expr",
+ /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt orderby_opt limit_opt",
+ /* 146 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 148 */ "setlist ::= nm EQ expr",
+ /* 149 */ "setlist ::= LP idlist RP EQ expr",
+ /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
+ /* 152 */ "upsert ::=",
+ /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
+ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
+ /* 155 */ "upsert ::= ON CONFLICT DO NOTHING",
+ /* 156 */ "insert_cmd ::= INSERT orconf",
+ /* 157 */ "insert_cmd ::= REPLACE",
+ /* 158 */ "idlist_opt ::=",
+ /* 159 */ "idlist_opt ::= LP idlist RP",
+ /* 160 */ "idlist ::= idlist COMMA nm",
+ /* 161 */ "idlist ::= nm",
+ /* 162 */ "expr ::= LP expr RP",
+ /* 163 */ "expr ::= ID|INDEXED",
+ /* 164 */ "expr ::= JOIN_KW",
+ /* 165 */ "expr ::= nm DOT nm",
+ /* 166 */ "expr ::= nm DOT nm DOT nm",
+ /* 167 */ "term ::= NULL|FLOAT|BLOB",
+ /* 168 */ "term ::= STRING",
+ /* 169 */ "term ::= INTEGER",
+ /* 170 */ "expr ::= VARIABLE",
+ /* 171 */ "expr ::= expr COLLATE ID|STRING",
+ /* 172 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 174 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
+ /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
+ /* 177 */ "term ::= CTIME_KW",
+ /* 178 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 179 */ "expr ::= expr AND expr",
+ /* 180 */ "expr ::= expr OR expr",
+ /* 181 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 182 */ "expr ::= expr EQ|NE expr",
+ /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 184 */ "expr ::= expr PLUS|MINUS expr",
+ /* 185 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 186 */ "expr ::= expr CONCAT expr",
+ /* 187 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 188 */ "expr ::= expr likeop expr",
+ /* 189 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 190 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 191 */ "expr ::= expr NOT NULL",
+ /* 192 */ "expr ::= expr IS expr",
+ /* 193 */ "expr ::= expr IS NOT expr",
+ /* 194 */ "expr ::= NOT expr",
+ /* 195 */ "expr ::= BITNOT expr",
+ /* 196 */ "expr ::= PLUS|MINUS expr",
+ /* 197 */ "between_op ::= BETWEEN",
+ /* 198 */ "between_op ::= NOT BETWEEN",
+ /* 199 */ "expr ::= expr between_op expr AND expr",
+ /* 200 */ "in_op ::= IN",
+ /* 201 */ "in_op ::= NOT IN",
+ /* 202 */ "expr ::= expr in_op LP exprlist RP",
+ /* 203 */ "expr ::= LP select RP",
+ /* 204 */ "expr ::= expr in_op LP select RP",
+ /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 206 */ "expr ::= EXISTS LP select RP",
+ /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 209 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 210 */ "case_else ::= ELSE expr",
+ /* 211 */ "case_else ::=",
+ /* 212 */ "case_operand ::= expr",
+ /* 213 */ "case_operand ::=",
+ /* 214 */ "exprlist ::=",
+ /* 215 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 216 */ "nexprlist ::= expr",
+ /* 217 */ "paren_exprlist ::=",
+ /* 218 */ "paren_exprlist ::= LP exprlist RP",
+ /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 220 */ "uniqueflag ::= UNIQUE",
+ /* 221 */ "uniqueflag ::=",
+ /* 222 */ "eidlist_opt ::=",
+ /* 223 */ "eidlist_opt ::= LP eidlist RP",
+ /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 225 */ "eidlist ::= nm collate sortorder",
+ /* 226 */ "collate ::=",
+ /* 227 */ "collate ::= COLLATE ID|STRING",
+ /* 228 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 229 */ "cmd ::= VACUUM",
+ /* 230 */ "cmd ::= VACUUM nm",
+ /* 231 */ "cmd ::= PRAGMA nm dbnm",
+ /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 240 */ "trigger_time ::= BEFORE|AFTER",
+ /* 241 */ "trigger_time ::= INSTEAD OF",
+ /* 242 */ "trigger_time ::=",
+ /* 243 */ "trigger_event ::= DELETE|INSERT",
+ /* 244 */ "trigger_event ::= UPDATE",
+ /* 245 */ "trigger_event ::= UPDATE OF idlist",
+ /* 246 */ "when_clause ::=",
+ /* 247 */ "when_clause ::= WHEN expr",
+ /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 250 */ "trnm ::= nm DOT nm",
+ /* 251 */ "tridxby ::= INDEXED BY nm",
+ /* 252 */ "tridxby ::= NOT INDEXED",
+ /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 256 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 257 */ "expr ::= RAISE LP IGNORE RP",
+ /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 259 */ "raisetype ::= ROLLBACK",
+ /* 260 */ "raisetype ::= ABORT",
+ /* 261 */ "raisetype ::= FAIL",
+ /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 264 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 265 */ "key_opt ::=",
+ /* 266 */ "key_opt ::= KEY expr",
+ /* 267 */ "cmd ::= REINDEX",
+ /* 268 */ "cmd ::= REINDEX nm dbnm",
+ /* 269 */ "cmd ::= ANALYZE",
+ /* 270 */ "cmd ::= ANALYZE nm dbnm",
+ /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 273 */ "add_column_fullname ::= fullname",
+ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 275 */ "cmd ::= create_vtab",
+ /* 276 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 278 */ "vtabarg ::=",
+ /* 279 */ "vtabargtoken ::= ANY",
+ /* 280 */ "vtabargtoken ::= lp anylist RP",
+ /* 281 */ "lp ::= LP",
+ /* 282 */ "with ::= WITH wqlist",
+ /* 283 */ "with ::= WITH RECURSIVE wqlist",
+ /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 286 */ "windowdefn_list ::= windowdefn",
+ /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 288 */ "windowdefn ::= nm AS window",
+ /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP",
+ /* 290 */ "part_opt ::= PARTITION BY nexprlist",
+ /* 291 */ "part_opt ::=",
+ /* 292 */ "frame_opt ::=",
+ /* 293 */ "frame_opt ::= range_or_rows frame_bound_s",
+ /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
+ /* 295 */ "range_or_rows ::= RANGE",
+ /* 296 */ "range_or_rows ::= ROWS",
+ /* 297 */ "frame_bound_s ::= frame_bound",
+ /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 299 */ "frame_bound_e ::= frame_bound",
+ /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 301 */ "frame_bound ::= expr PRECEDING",
+ /* 302 */ "frame_bound ::= CURRENT ROW",
+ /* 303 */ "frame_bound ::= expr FOLLOWING",
+ /* 304 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 305 */ "over_clause ::= filter_opt OVER window",
+ /* 306 */ "over_clause ::= filter_opt OVER nm",
+ /* 307 */ "filter_opt ::=",
+ /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP",
+ /* 309 */ "input ::= cmdlist",
+ /* 310 */ "cmdlist ::= cmdlist ecmd",
+ /* 311 */ "cmdlist ::= ecmd",
+ /* 312 */ "ecmd ::= SEMI",
+ /* 313 */ "ecmd ::= cmdx SEMI",
+ /* 314 */ "ecmd ::= explain cmdx",
+ /* 315 */ "trans_opt ::=",
+ /* 316 */ "trans_opt ::= TRANSACTION",
+ /* 317 */ "trans_opt ::= TRANSACTION nm",
+ /* 318 */ "savepoint_opt ::= SAVEPOINT",
+ /* 319 */ "savepoint_opt ::=",
+ /* 320 */ "cmd ::= create_table create_table_args",
+ /* 321 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 322 */ "columnlist ::= columnname carglist",
+ /* 323 */ "nm ::= ID|INDEXED",
+ /* 324 */ "nm ::= STRING",
+ /* 325 */ "nm ::= JOIN_KW",
+ /* 326 */ "typetoken ::= typename",
+ /* 327 */ "typename ::= ID|STRING",
+ /* 328 */ "signed ::= plus_num",
+ /* 329 */ "signed ::= minus_num",
+ /* 330 */ "carglist ::= carglist ccons",
+ /* 331 */ "carglist ::=",
+ /* 332 */ "ccons ::= NULL onconf",
+ /* 333 */ "conslist_opt ::= COMMA conslist",
+ /* 334 */ "conslist ::= conslist tconscomma tcons",
+ /* 335 */ "conslist ::= tcons",
+ /* 336 */ "tconscomma ::=",
+ /* 337 */ "defer_subclause_opt ::= defer_subclause",
+ /* 338 */ "resolvetype ::= raisetype",
+ /* 339 */ "selectnowith ::= oneselect",
+ /* 340 */ "oneselect ::= values",
+ /* 341 */ "sclp ::= selcollist COMMA",
+ /* 342 */ "as ::= ID|STRING",
+ /* 343 */ "expr ::= term",
+ /* 344 */ "likeop ::= LIKE_KW|MATCH",
+ /* 345 */ "exprlist ::= nexprlist",
+ /* 346 */ "nmnum ::= plus_num",
+ /* 347 */ "nmnum ::= nm",
+ /* 348 */ "nmnum ::= ON",
+ /* 349 */ "nmnum ::= DELETE",
+ /* 350 */ "nmnum ::= DEFAULT",
+ /* 351 */ "plus_num ::= INTEGER|FLOAT",
+ /* 352 */ "foreach_clause ::=",
+ /* 353 */ "foreach_clause ::= FOR EACH ROW",
+ /* 354 */ "trnm ::= nm",
+ /* 355 */ "tridxby ::=",
+ /* 356 */ "database_kw_opt ::= DATABASE",
+ /* 357 */ "database_kw_opt ::=",
+ /* 358 */ "kwcolumn_opt ::=",
+ /* 359 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 360 */ "vtabarglist ::= vtabarg",
+ /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 362 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 363 */ "anylist ::=",
+ /* 364 */ "anylist ::= anylist LP anylist RP",
+ /* 365 */ "anylist ::= anylist ANY",
+ /* 366 */ "with ::=",
};
#endif /* NDEBUG */
@@ -138650,28 +148089,29 @@ static int yyGrowStack(yyParser *p){
/* Initialize a new parser that has already been allocated.
*/
-SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
- yyParser *pParser = (yyParser*)yypParser;
+SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){
+ yyParser *yypParser = (yyParser*)yypRawParser;
+ sqlite3ParserCTX_STORE
#ifdef YYTRACKMAXSTACKDEPTH
- pParser->yyhwm = 0;
+ yypParser->yyhwm = 0;
#endif
#if YYSTACKDEPTH<=0
- pParser->yytos = NULL;
- pParser->yystack = NULL;
- pParser->yystksz = 0;
- if( yyGrowStack(pParser) ){
- pParser->yystack = &pParser->yystk0;
- pParser->yystksz = 1;
+ yypParser->yytos = NULL;
+ yypParser->yystack = NULL;
+ yypParser->yystksz = 0;
+ if( yyGrowStack(yypParser) ){
+ yypParser->yystack = &yypParser->yystk0;
+ yypParser->yystksz = 1;
}
#endif
#ifndef YYNOERRORRECOVERY
- pParser->yyerrcnt = -1;
+ yypParser->yyerrcnt = -1;
#endif
- pParser->yytos = pParser->yystack;
- pParser->yystack[0].stateno = 0;
- pParser->yystack[0].major = 0;
+ yypParser->yytos = yypParser->yystack;
+ yypParser->yystack[0].stateno = 0;
+ yypParser->yystack[0].major = 0;
#if YYSTACKDEPTH>0
- pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
+ yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
#endif
}
@@ -138688,11 +148128,14 @@ SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
** A pointer to a parser. This pointer is used in subsequent calls
** to sqlite3Parser and sqlite3ParserFree.
*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
- yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
- if( pParser ) sqlite3ParserInit(pParser);
- return pParser;
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){
+ yyParser *yypParser;
+ yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
+ if( yypParser ){
+ sqlite3ParserCTX_STORE
+ sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM);
+ }
+ return (void*)yypParser;
}
#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
@@ -138709,7 +148152,8 @@ static void yy_destructor(
YYCODETYPE yymajor, /* Type code for object to destroy */
YYMINORTYPE *yypminor /* The object to be destroyed */
){
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ sqlite3ParserCTX_FETCH
switch( yymajor ){
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
@@ -138722,77 +148166,96 @@ static void yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 163: /* select */
- case 194: /* selectnowith */
- case 195: /* oneselect */
- case 206: /* values */
+ case 174: /* select */
+ case 206: /* selectnowith */
+ case 207: /* oneselect */
+ case 219: /* values */
+{
+sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+}
+ break;
+ case 184: /* term */
+ case 185: /* expr */
+ case 213: /* where_opt */
+ case 215: /* having_opt */
+ case 227: /* on_opt */
+ case 242: /* case_operand */
+ case 244: /* case_else */
+ case 253: /* when_clause */
+ case 258: /* key_opt */
+ case 272: /* filter_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+}
+ break;
+ case 189: /* eidlist_opt */
+ case 198: /* sortlist */
+ case 199: /* eidlist */
+ case 211: /* selcollist */
+ case 214: /* groupby_opt */
+ case 216: /* orderby_opt */
+ case 220: /* nexprlist */
+ case 221: /* sclp */
+ case 229: /* exprlist */
+ case 233: /* setlist */
+ case 241: /* paren_exprlist */
+ case 243: /* case_exprlist */
+ case 271: /* part_opt */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy243));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
}
break;
- case 172: /* term */
- case 173: /* expr */
+ case 205: /* fullname */
+ case 212: /* from */
+ case 223: /* seltablist */
+ case 224: /* stl_prefix */
+ case 230: /* xfullname */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
+sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
}
break;
- 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 224: /* paren_exprlist */
- case 226: /* case_exprlist */
+ case 208: /* wqlist */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
+sqlite3WithDelete(pParse->db, (yypminor->yy449));
}
break;
- case 193: /* fullname */
- case 200: /* from */
- case 211: /* seltablist */
- case 212: /* stl_prefix */
+ case 218: /* window_clause */
+ case 267: /* windowdefn_list */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
}
break;
- case 196: /* with */
- case 250: /* wqlist */
+ case 228: /* using_opt */
+ case 231: /* idlist */
+ case 235: /* idlist_opt */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy285));
+sqlite3IdListDelete(pParse->db, (yypminor->yy48));
}
break;
- case 201: /* where_opt */
- case 203: /* having_opt */
- case 215: /* on_opt */
- case 225: /* case_operand */
- case 227: /* case_else */
- case 236: /* when_clause */
- case 241: /* key_opt */
+ case 237: /* over_clause */
+ case 268: /* windowdefn */
+ case 269: /* window */
+ case 270: /* frame_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+sqlite3WindowDelete(pParse->db, (yypminor->yy327));
}
break;
- case 216: /* using_opt */
- case 217: /* idlist */
- case 220: /* idlist_opt */
+ case 249: /* trigger_cmd_list */
+ case 254: /* trigger_cmd */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy254));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
}
break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
+ case 251: /* trigger_event */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145));
+sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
}
break;
- case 234: /* trigger_event */
+ case 274: /* frame_bound */
+ case 275: /* frame_bound_s */
+ case 276: /* frame_bound_e */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy332).b);
+sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -138863,24 +148326,66 @@ SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
}
#endif
+/* This array of booleans keeps track of the parser statement
+** coverage. The element yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(YYCOVERAGE)
+static unsigned char yycoverage[YYNSTATE][YYNTOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<YYNSTATE; stateno++){
+ i = yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){
+ if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ yyTokenName[iLookAhead],
+ yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
*/
-static unsigned int yy_find_shift_action(
- yyParser *pParser, /* The parser */
- YYCODETYPE iLookAhead /* The look-ahead token */
+static YYACTIONTYPE yy_find_shift_action(
+ YYCODETYPE iLookAhead, /* The look-ahead token */
+ YYACTIONTYPE stateno /* Current state number */
){
int i;
- int stateno = pParser->yytos->stateno;
-
- if( stateno>=YY_MIN_REDUCE ) return stateno;
+
+ if( stateno>YY_MAX_SHIFT ) return stateno;
assert( stateno <= YY_SHIFT_COUNT );
+#if defined(YYCOVERAGE)
+ yycoverage[stateno][iLookAhead] = 1;
+#endif
do{
i = yy_shift_ofst[stateno];
+ assert( i>=0 );
+ /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
assert( iLookAhead!=YYNOCODE );
+ assert( iLookAhead < YYNTOKEN );
i += iLookAhead;
- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
@@ -138906,6 +148411,7 @@ static unsigned int yy_find_shift_action(
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
j<YY_ACTTAB_COUNT &&
#endif
+ j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) &&
yy_lookahead[j]==YYWILDCARD && iLookAhead>0
){
#ifndef NDEBUG
@@ -138930,8 +148436,8 @@ static unsigned int yy_find_shift_action(
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
*/
-static int yy_find_reduce_action(
- int stateno, /* Current state number */
+static YYACTIONTYPE yy_find_reduce_action(
+ YYACTIONTYPE stateno, /* Current state number */
YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
@@ -138943,7 +148449,6 @@ static int yy_find_reduce_action(
assert( stateno<=YY_REDUCE_COUNT );
#endif
i = yy_reduce_ofst[stateno];
- assert( i!=YY_REDUCE_USE_DFLT );
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
#ifdef YYERRORSYMBOL
@@ -138961,7 +148466,8 @@ static int yy_find_reduce_action(
** The following routine is called if the stack overflows.
*/
static void yyStackOverflow(yyParser *yypParser){
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ sqlite3ParserCTX_FETCH
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
@@ -138974,27 +148480,29 @@ static void yyStackOverflow(yyParser *yypParser){
sqlite3ErrorMsg(pParse, "parser stack overflow");
/******** End %stack_overflow code ********************************************/
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
+ sqlite3ParserCTX_STORE
}
/*
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
-static void yyTraceShift(yyParser *yypParser, int yyNewState){
+static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
if( yyTraceFILE ){
if( yyNewState<YYNSTATE ){
- fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
- yyTracePrompt,yyTokenName[yypParser->yytos->major],
+ fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
yyNewState);
}else{
- fprintf(yyTraceFILE,"%sShift '%s'\n",
- yyTracePrompt,yyTokenName[yypParser->yytos->major]);
+ fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
+ yyNewState - YY_MIN_REDUCE);
}
}
}
#else
-# define yyTraceShift(X,Y)
+# define yyTraceShift(X,Y,Z)
#endif
/*
@@ -139002,8 +148510,8 @@ static void yyTraceShift(yyParser *yypParser, int yyNewState){
*/
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 */
+ YYACTIONTYPE yyNewState, /* The new state to shift in */
+ YYCODETYPE yyMajor, /* The major token to shift in */
sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */
){
yyStackEntry *yytos;
@@ -139033,10 +148541,10 @@ static void yy_shift(
yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
}
yytos = yypParser->yytos;
- yytos->stateno = (YYACTIONTYPE)yyNewState;
- yytos->major = (YYCODETYPE)yyMajor;
+ yytos->stateno = yyNewState;
+ yytos->major = yyMajor;
yytos->minor.yy0 = yyMinor;
- yyTraceShift(yypParser, yyNewState);
+ yyTraceShift(yypParser, yyNewState, "Shift");
}
/* The following table contains information about every rule that
@@ -139046,335 +148554,373 @@ static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
signed char nrhs; /* Negative of the number of RHS symbols in the rule */
} yyRuleInfo[] = {
- { 147, -1 },
- { 147, -3 },
- { 148, -1 },
- { 149, -3 },
- { 150, 0 },
- { 150, -1 },
- { 150, -1 },
- { 150, -1 },
- { 149, -2 },
- { 149, -2 },
- { 149, -2 },
- { 149, -3 },
- { 149, -5 },
- { 154, -6 },
- { 156, -1 },
- { 158, 0 },
- { 158, -3 },
- { 157, -1 },
- { 157, 0 },
- { 155, -5 },
- { 155, -2 },
- { 162, 0 },
- { 162, -2 },
- { 164, -2 },
- { 166, 0 },
- { 166, -4 },
- { 166, -6 },
- { 167, -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, -2 },
- { 180, -2 },
- { 180, -3 },
- { 180, -3 },
- { 180, -3 },
- { 181, -2 },
- { 181, -2 },
- { 181, -1 },
- { 181, -1 },
- { 181, -2 },
- { 179, -3 },
- { 179, -2 },
- { 182, 0 },
- { 182, -2 },
- { 182, -2 },
- { 161, 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 },
- { 149, -4 },
- { 192, -2 },
- { 192, 0 },
- { 149, -9 },
- { 149, -4 },
- { 149, -1 },
- { 163, -2 },
- { 194, -3 },
- { 197, -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 },
- { 200, -2 },
- { 212, -2 },
- { 212, 0 },
- { 211, -7 },
- { 211, -9 },
- { 211, -7 },
- { 211, -7 },
- { 159, 0 },
- { 159, -2 },
- { 193, -2 },
- { 213, -1 },
- { 213, -2 },
- { 213, -3 },
- { 213, -4 },
- { 215, -2 },
- { 215, 0 },
- { 214, 0 },
- { 214, -3 },
- { 214, -2 },
- { 216, -4 },
- { 216, 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 },
- { 205, -4 },
- { 205, -4 },
- { 149, -8 },
- { 201, 0 },
- { 201, -2 },
- { 149, -10 },
- { 218, -5 },
- { 218, -7 },
- { 218, -3 },
- { 218, -5 },
- { 149, -6 },
- { 149, -7 },
- { 219, -2 },
- { 219, -1 },
- { 220, 0 },
- { 220, -3 },
- { 217, -3 },
- { 217, -1 },
- { 173, -3 },
- { 173, -1 },
- { 173, -1 },
- { 173, -3 },
- { 173, -5 },
- { 172, -1 },
- { 172, -1 },
- { 172, -1 },
- { 173, -1 },
- { 173, -3 },
- { 173, -6 },
- { 173, -5 },
- { 173, -4 },
- { 172, -1 },
- { 173, -5 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 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 },
- { 173, -5 },
- { 173, -3 },
- { 173, -5 },
- { 173, -5 },
- { 173, -4 },
- { 173, -5 },
- { 226, -5 },
- { 226, -4 },
- { 227, -2 },
- { 227, 0 },
- { 225, -1 },
- { 225, 0 },
- { 208, 0 },
- { 207, -3 },
- { 207, -1 },
- { 224, 0 },
- { 224, -3 },
- { 149, -12 },
- { 228, -1 },
- { 228, 0 },
- { 177, 0 },
- { 177, -3 },
- { 187, -5 },
- { 187, -3 },
- { 229, 0 },
- { 229, -2 },
- { 149, -4 },
- { 149, -1 },
- { 149, -2 },
- { 149, -3 },
- { 149, -5 },
- { 149, -6 },
- { 149, -5 },
- { 149, -6 },
- { 169, -2 },
- { 170, -2 },
- { 149, -5 },
- { 231, -11 },
- { 233, -1 },
- { 233, -2 },
- { 233, 0 },
- { 234, -1 },
- { 234, -1 },
- { 234, -3 },
- { 236, 0 },
- { 236, -2 },
- { 232, -3 },
- { 232, -2 },
- { 238, -3 },
- { 239, -3 },
- { 239, -2 },
- { 237, -7 },
- { 237, -5 },
- { 237, -5 },
- { 237, -1 },
- { 173, -4 },
- { 173, -6 },
- { 191, -1 },
- { 191, -1 },
- { 191, -1 },
- { 149, -4 },
- { 149, -6 },
- { 149, -3 },
- { 241, 0 },
- { 241, -2 },
- { 149, -1 },
- { 149, -3 },
- { 149, -1 },
- { 149, -3 },
- { 149, -6 },
- { 149, -7 },
- { 242, -1 },
- { 149, -1 },
- { 149, -4 },
- { 244, -8 },
- { 246, 0 },
- { 247, -1 },
- { 247, -3 },
- { 248, -1 },
- { 196, 0 },
- { 196, -2 },
- { 196, -3 },
- { 250, -6 },
- { 250, -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 },
- { 221, -1 },
- { 208, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 169, -1 },
- { 235, 0 },
- { 235, -3 },
- { 238, -1 },
- { 239, 0 },
- { 240, -1 },
- { 240, 0 },
- { 243, 0 },
- { 243, -1 },
- { 245, -1 },
- { 245, -3 },
- { 246, -2 },
- { 249, 0 },
- { 249, -4 },
- { 249, -2 },
+ { 159, -1 }, /* (0) explain ::= EXPLAIN */
+ { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ { 158, -1 }, /* (2) cmdx ::= cmd */
+ { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
+ { 161, 0 }, /* (4) transtype ::= */
+ { 161, -1 }, /* (5) transtype ::= DEFERRED */
+ { 161, -1 }, /* (6) transtype ::= IMMEDIATE */
+ { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */
+ { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
+ { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
+ { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */
+ { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ { 167, -1 }, /* (14) createkw ::= CREATE */
+ { 169, 0 }, /* (15) ifnotexists ::= */
+ { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
+ { 168, -1 }, /* (17) temp ::= TEMP */
+ { 168, 0 }, /* (18) temp ::= */
+ { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ { 166, -2 }, /* (20) create_table_args ::= AS select */
+ { 173, 0 }, /* (21) table_options ::= */
+ { 173, -2 }, /* (22) table_options ::= WITHOUT nm */
+ { 175, -2 }, /* (23) columnname ::= nm typetoken */
+ { 177, 0 }, /* (24) typetoken ::= */
+ { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */
+ { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ { 178, -2 }, /* (27) typename ::= typename ID|STRING */
+ { 182, 0 }, /* (28) scanpt ::= */
+ { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */
+ { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
+ { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
+ { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
+ { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
+ { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
+ { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */
+ { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */
+ { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */
+ { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
+ { 183, -1 }, /* (40) ccons ::= defer_subclause */
+ { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */
+ { 188, 0 }, /* (42) autoinc ::= */
+ { 188, -1 }, /* (43) autoinc ::= AUTOINCR */
+ { 190, 0 }, /* (44) refargs ::= */
+ { 190, -2 }, /* (45) refargs ::= refargs refarg */
+ { 192, -2 }, /* (46) refarg ::= MATCH nm */
+ { 192, -3 }, /* (47) refarg ::= ON INSERT refact */
+ { 192, -3 }, /* (48) refarg ::= ON DELETE refact */
+ { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */
+ { 193, -2 }, /* (50) refact ::= SET NULL */
+ { 193, -2 }, /* (51) refact ::= SET DEFAULT */
+ { 193, -1 }, /* (52) refact ::= CASCADE */
+ { 193, -1 }, /* (53) refact ::= RESTRICT */
+ { 193, -2 }, /* (54) refact ::= NO ACTION */
+ { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ { 194, 0 }, /* (57) init_deferred_pred_opt ::= */
+ { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ { 172, 0 }, /* (60) conslist_opt ::= */
+ { 196, -1 }, /* (61) tconscomma ::= COMMA */
+ { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */
+ { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
+ { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
+ { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ { 200, 0 }, /* (67) defer_subclause_opt ::= */
+ { 186, 0 }, /* (68) onconf ::= */
+ { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
+ { 201, 0 }, /* (70) orconf ::= */
+ { 201, -2 }, /* (71) orconf ::= OR resolvetype */
+ { 202, -1 }, /* (72) resolvetype ::= IGNORE */
+ { 202, -1 }, /* (73) resolvetype ::= REPLACE */
+ { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
+ { 204, -2 }, /* (75) ifexists ::= IF EXISTS */
+ { 204, 0 }, /* (76) ifexists ::= */
+ { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
+ { 160, -1 }, /* (79) cmd ::= select */
+ { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */
+ { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
+ { 174, -1 }, /* (82) select ::= selectnowith */
+ { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
+ { 209, -1 }, /* (84) multiselect_op ::= UNION */
+ { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */
+ { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
+ { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */
+ { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */
+ { 210, -1 }, /* (91) distinct ::= DISTINCT */
+ { 210, -1 }, /* (92) distinct ::= ALL */
+ { 210, 0 }, /* (93) distinct ::= */
+ { 221, 0 }, /* (94) sclp ::= */
+ { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */
+ { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */
+ { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
+ { 222, -2 }, /* (98) as ::= AS nm */
+ { 222, 0 }, /* (99) as ::= */
+ { 212, 0 }, /* (100) from ::= */
+ { 212, -2 }, /* (101) from ::= FROM seltablist */
+ { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */
+ { 224, 0 }, /* (103) stl_prefix ::= */
+ { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ { 170, 0 }, /* (108) dbnm ::= */
+ { 170, -2 }, /* (109) dbnm ::= DOT nm */
+ { 205, -1 }, /* (110) fullname ::= nm */
+ { 205, -3 }, /* (111) fullname ::= nm DOT nm */
+ { 230, -1 }, /* (112) xfullname ::= nm */
+ { 230, -3 }, /* (113) xfullname ::= nm DOT nm */
+ { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */
+ { 230, -3 }, /* (115) xfullname ::= nm AS nm */
+ { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */
+ { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */
+ { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */
+ { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */
+ { 227, -2 }, /* (120) on_opt ::= ON expr */
+ { 227, 0 }, /* (121) on_opt ::= */
+ { 226, 0 }, /* (122) indexed_opt ::= */
+ { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */
+ { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */
+ { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */
+ { 228, 0 }, /* (126) using_opt ::= */
+ { 216, 0 }, /* (127) orderby_opt ::= */
+ { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */
+ { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */
+ { 198, -2 }, /* (130) sortlist ::= expr sortorder */
+ { 187, -1 }, /* (131) sortorder ::= ASC */
+ { 187, -1 }, /* (132) sortorder ::= DESC */
+ { 187, 0 }, /* (133) sortorder ::= */
+ { 214, 0 }, /* (134) groupby_opt ::= */
+ { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */
+ { 215, 0 }, /* (136) having_opt ::= */
+ { 215, -2 }, /* (137) having_opt ::= HAVING expr */
+ { 217, 0 }, /* (138) limit_opt ::= */
+ { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */
+ { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
+ { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */
+ { 160, -8 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt orderby_opt limit_opt */
+ { 213, 0 }, /* (143) where_opt ::= */
+ { 213, -2 }, /* (144) where_opt ::= WHERE expr */
+ { 160, -10 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt orderby_opt limit_opt */
+ { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */
+ { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ { 233, -3 }, /* (148) setlist ::= nm EQ expr */
+ { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */
+ { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ { 236, 0 }, /* (152) upsert ::= */
+ { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */
+ { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */
+ { 234, -1 }, /* (157) insert_cmd ::= REPLACE */
+ { 235, 0 }, /* (158) idlist_opt ::= */
+ { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */
+ { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */
+ { 231, -1 }, /* (161) idlist ::= nm */
+ { 185, -3 }, /* (162) expr ::= LP expr RP */
+ { 185, -1 }, /* (163) expr ::= ID|INDEXED */
+ { 185, -1 }, /* (164) expr ::= JOIN_KW */
+ { 185, -3 }, /* (165) expr ::= nm DOT nm */
+ { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */
+ { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */
+ { 184, -1 }, /* (168) term ::= STRING */
+ { 184, -1 }, /* (169) term ::= INTEGER */
+ { 185, -1 }, /* (170) expr ::= VARIABLE */
+ { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */
+ { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */
+ { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
+ { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */
+ { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
+ { 184, -1 }, /* (177) term ::= CTIME_KW */
+ { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */
+ { 185, -3 }, /* (179) expr ::= expr AND expr */
+ { 185, -3 }, /* (180) expr ::= expr OR expr */
+ { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */
+ { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */
+ { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */
+ { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */
+ { 185, -3 }, /* (186) expr ::= expr CONCAT expr */
+ { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */
+ { 185, -3 }, /* (188) expr ::= expr likeop expr */
+ { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */
+ { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */
+ { 185, -3 }, /* (191) expr ::= expr NOT NULL */
+ { 185, -3 }, /* (192) expr ::= expr IS expr */
+ { 185, -4 }, /* (193) expr ::= expr IS NOT expr */
+ { 185, -2 }, /* (194) expr ::= NOT expr */
+ { 185, -2 }, /* (195) expr ::= BITNOT expr */
+ { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */
+ { 239, -1 }, /* (197) between_op ::= BETWEEN */
+ { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */
+ { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */
+ { 240, -1 }, /* (200) in_op ::= IN */
+ { 240, -2 }, /* (201) in_op ::= NOT IN */
+ { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */
+ { 185, -3 }, /* (203) expr ::= LP select RP */
+ { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */
+ { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
+ { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */
+ { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
+ { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */
+ { 244, -2 }, /* (210) case_else ::= ELSE expr */
+ { 244, 0 }, /* (211) case_else ::= */
+ { 242, -1 }, /* (212) case_operand ::= expr */
+ { 242, 0 }, /* (213) case_operand ::= */
+ { 229, 0 }, /* (214) exprlist ::= */
+ { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */
+ { 220, -1 }, /* (216) nexprlist ::= expr */
+ { 241, 0 }, /* (217) paren_exprlist ::= */
+ { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */
+ { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */
+ { 245, 0 }, /* (221) uniqueflag ::= */
+ { 189, 0 }, /* (222) eidlist_opt ::= */
+ { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */
+ { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
+ { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */
+ { 246, 0 }, /* (226) collate ::= */
+ { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */
+ { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */
+ { 160, -1 }, /* (229) cmd ::= VACUUM */
+ { 160, -2 }, /* (230) cmd ::= VACUUM nm */
+ { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */
+ { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */
+ { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */
+ { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */
+ { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */
+ { 250, 0 }, /* (242) trigger_time ::= */
+ { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */
+ { 251, -1 }, /* (244) trigger_event ::= UPDATE */
+ { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */
+ { 253, 0 }, /* (246) when_clause ::= */
+ { 253, -2 }, /* (247) when_clause ::= WHEN expr */
+ { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */
+ { 255, -3 }, /* (250) trnm ::= nm DOT nm */
+ { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */
+ { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */
+ { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */
+ { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */
+ { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */
+ { 203, -1 }, /* (259) raisetype ::= ROLLBACK */
+ { 203, -1 }, /* (260) raisetype ::= ABORT */
+ { 203, -1 }, /* (261) raisetype ::= FAIL */
+ { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */
+ { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */
+ { 258, 0 }, /* (265) key_opt ::= */
+ { 258, -2 }, /* (266) key_opt ::= KEY expr */
+ { 160, -1 }, /* (267) cmd ::= REINDEX */
+ { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */
+ { 160, -1 }, /* (269) cmd ::= ANALYZE */
+ { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */
+ { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ { 259, -1 }, /* (273) add_column_fullname ::= fullname */
+ { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ { 160, -1 }, /* (275) cmd ::= create_vtab */
+ { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */
+ { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ { 263, 0 }, /* (278) vtabarg ::= */
+ { 264, -1 }, /* (279) vtabargtoken ::= ANY */
+ { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */
+ { 265, -1 }, /* (281) lp ::= LP */
+ { 232, -2 }, /* (282) with ::= WITH wqlist */
+ { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */
+ { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */
+ { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */
+ { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ { 268, -3 }, /* (288) windowdefn ::= nm AS window */
+ { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */
+ { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */
+ { 271, 0 }, /* (291) part_opt ::= */
+ { 270, 0 }, /* (292) frame_opt ::= */
+ { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */
+ { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+ { 273, -1 }, /* (295) range_or_rows ::= RANGE */
+ { 273, -1 }, /* (296) range_or_rows ::= ROWS */
+ { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */
+ { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */
+ { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */
+ { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */
+ { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */
+ { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */
+ { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */
+ { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */
+ { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */
+ { 272, 0 }, /* (307) filter_opt ::= */
+ { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */
+ { 155, -1 }, /* (309) input ::= cmdlist */
+ { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */
+ { 156, -1 }, /* (311) cmdlist ::= ecmd */
+ { 157, -1 }, /* (312) ecmd ::= SEMI */
+ { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */
+ { 157, -2 }, /* (314) ecmd ::= explain cmdx */
+ { 162, 0 }, /* (315) trans_opt ::= */
+ { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */
+ { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */
+ { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */
+ { 164, 0 }, /* (319) savepoint_opt ::= */
+ { 160, -2 }, /* (320) cmd ::= create_table create_table_args */
+ { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */
+ { 171, -2 }, /* (322) columnlist ::= columnname carglist */
+ { 163, -1 }, /* (323) nm ::= ID|INDEXED */
+ { 163, -1 }, /* (324) nm ::= STRING */
+ { 163, -1 }, /* (325) nm ::= JOIN_KW */
+ { 177, -1 }, /* (326) typetoken ::= typename */
+ { 178, -1 }, /* (327) typename ::= ID|STRING */
+ { 179, -1 }, /* (328) signed ::= plus_num */
+ { 179, -1 }, /* (329) signed ::= minus_num */
+ { 176, -2 }, /* (330) carglist ::= carglist ccons */
+ { 176, 0 }, /* (331) carglist ::= */
+ { 183, -2 }, /* (332) ccons ::= NULL onconf */
+ { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */
+ { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */
+ { 195, -1 }, /* (335) conslist ::= tcons */
+ { 196, 0 }, /* (336) tconscomma ::= */
+ { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */
+ { 202, -1 }, /* (338) resolvetype ::= raisetype */
+ { 206, -1 }, /* (339) selectnowith ::= oneselect */
+ { 207, -1 }, /* (340) oneselect ::= values */
+ { 221, -2 }, /* (341) sclp ::= selcollist COMMA */
+ { 222, -1 }, /* (342) as ::= ID|STRING */
+ { 185, -1 }, /* (343) expr ::= term */
+ { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */
+ { 229, -1 }, /* (345) exprlist ::= nexprlist */
+ { 247, -1 }, /* (346) nmnum ::= plus_num */
+ { 247, -1 }, /* (347) nmnum ::= nm */
+ { 247, -1 }, /* (348) nmnum ::= ON */
+ { 247, -1 }, /* (349) nmnum ::= DELETE */
+ { 247, -1 }, /* (350) nmnum ::= DEFAULT */
+ { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */
+ { 252, 0 }, /* (352) foreach_clause ::= */
+ { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */
+ { 255, -1 }, /* (354) trnm ::= nm */
+ { 256, 0 }, /* (355) tridxby ::= */
+ { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */
+ { 257, 0 }, /* (357) database_kw_opt ::= */
+ { 260, 0 }, /* (358) kwcolumn_opt ::= */
+ { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */
+ { 262, -1 }, /* (360) vtabarglist ::= vtabarg */
+ { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */
+ { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */
+ { 266, 0 }, /* (363) anylist ::= */
+ { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */
+ { 266, -2 }, /* (365) anylist ::= anylist ANY */
+ { 232, 0 }, /* (366) with ::= */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -139382,22 +148928,39 @@ static void yy_accept(yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
+**
+** The yyLookahead and yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The yyLookahead will be YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
*/
-static void yy_reduce(
+static YYACTIONTYPE yy_reduce(
yyParser *yypParser, /* The parser */
- unsigned int yyruleno /* Number of the rule by which to reduce */
+ unsigned int yyruleno, /* Number of the rule by which to reduce */
+ int yyLookahead, /* Lookahead token, or YYNOCODE if none */
+ sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */
+ sqlite3ParserCTX_PDECL /* %extra_context */
){
int yygoto; /* The next state */
- int yyact; /* The next action */
+ YYACTIONTYPE yyact; /* The next action */
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ (void)yyLookahead;
+ (void)yyLookaheadToken;
yymsp = yypParser->yytos;
#ifndef NDEBUG
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);
+ if( yysize ){
+ fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+ yyTracePrompt,
+ yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
+ }else{
+ fprintf(yyTraceFILE, "%sReduce %d [%s].\n",
+ yyTracePrompt, yyruleno, yyRuleName[yyruleno]);
+ }
}
#endif /* NDEBUG */
@@ -139414,13 +148977,19 @@ static void yy_reduce(
#if YYSTACKDEPTH>0
if( yypParser->yytos>=yypParser->yystackEnd ){
yyStackOverflow(yypParser);
- return;
+ /* The call to yyStackOverflow() above pops the stack until it is
+ ** empty, causing the main parser loop to exit. So the return value
+ ** is never used and does not matter. */
+ return 0;
}
#else
if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
if( yyGrowStack(yypParser) ){
yyStackOverflow(yypParser);
- return;
+ /* The call to yyStackOverflow() above pops the stack until it is
+ ** empty, causing the main parser loop to exit. So the return value
+ ** is never used and does not matter. */
+ return 0;
}
yymsp = yypParser->yytos;
}
@@ -139448,15 +149017,15 @@ static void yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy194 = TK_DEFERRED;}
+{yymsp[1].minor.yy70 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/}
+{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -139479,7 +149048,7 @@ static void yy_reduce(
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70);
}
break;
case 14: /* createkw ::= CREATE */
@@ -139488,38 +149057,38 @@ static void yy_reduce(
case 15: /* ifnotexists ::= */
case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 21: /* table_options ::= */ yytestcase(yyruleno==21);
- case 41: /* autoinc ::= */ yytestcase(yyruleno==41);
- case 56: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==56);
- case 66: /* defer_subclause_opt ::= */ yytestcase(yyruleno==66);
- case 75: /* ifexists ::= */ yytestcase(yyruleno==75);
- case 89: /* distinct ::= */ yytestcase(yyruleno==89);
- case 212: /* collate ::= */ yytestcase(yyruleno==212);
-{yymsp[1].minor.yy194 = 0;}
+ 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 93: /* distinct ::= */ yytestcase(yyruleno==93);
+ case 226: /* collate ::= */ yytestcase(yyruleno==226);
+{yymsp[1].minor.yy70 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy194 = 1;}
+{yymsp[-2].minor.yy70 = 1;}
break;
case 17: /* temp ::= TEMP */
- case 42: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==42);
-{yymsp[0].minor.yy194 = 1;}
+ case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
+{yymsp[0].minor.yy70 = 1;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
}
break;
case 22: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy194 = 0;
+ yymsp[-1].minor.yy70 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -139528,8 +149097,8 @@ static void yy_reduce(
{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 24: /* typetoken ::= */
- case 59: /* conslist_opt ::= */ yytestcase(yyruleno==59);
- case 95: /* as ::= */ yytestcase(yyruleno==95);
+ case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
+ case 99: /* as ::= */ yytestcase(yyruleno==99);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 25: /* typetoken ::= typename LP signed RP */
@@ -139545,721 +149114,747 @@ static void yy_reduce(
case 27: /* 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 28: /* ccons ::= CONSTRAINT nm */
- case 61: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==61);
+ case 28: /* scanpt ::= */
+{
+ assert( yyLookahead!=YYNOCODE );
+ yymsp[1].minor.yy392 = yyLookaheadToken.z;
+}
+ break;
+ case 29: /* ccons ::= CONSTRAINT nm */
+ case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 29: /* ccons ::= DEFAULT term */
- case 31: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==31);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
+ case 30: /* ccons ::= DEFAULT scanpt term scanpt */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+ break;
+ case 31: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
- case 30: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
+ case 32: /* ccons ::= DEFAULT PLUS term scanpt */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
break;
- case 32: /* ccons ::= DEFAULT MINUS term */
+ case 33: /* ccons ::= DEFAULT MINUS term scanpt */
{
- ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0);
- v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy190.zEnd;
- sqlite3AddDefaultValue(pParse,&v);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
}
break;
- case 33: /* ccons ::= DEFAULT ID|INDEXED */
+ case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
{
- ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,&v);
+ Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
+ if( p ){
+ sqlite3ExprIdToTrueFalse(p);
+ testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
+ }
+ sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
}
break;
- case 34: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
+ case 35: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);}
break;
- case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);}
+ case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
break;
- case 36: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0,
+ case 37: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 37: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
+ case 38: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
break;
- case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
+ case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
break;
- case 39: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);}
+ case 40: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
break;
- case 40: /* ccons ::= COLLATE ID|STRING */
+ case 41: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 43: /* refargs ::= */
-{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 44: /* refargs ::= */
+{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 44: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; }
+ case 45: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
break;
- case 45: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy497.value = 0; yymsp[-1].minor.yy497.mask = 0x000000; }
+ case 46: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; }
break;
- case 46: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy497.value = 0; yymsp[-2].minor.yy497.mask = 0x000000; }
+ case 47: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; }
break;
- case 47: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194; yymsp[-2].minor.yy497.mask = 0x0000ff; }
+ case 48: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; }
break;
- case 48: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8; yymsp[-2].minor.yy497.mask = 0x00ff00; }
+ case 49: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; }
break;
- case 49: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy194 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 50: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 50: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy194 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 51: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 51: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy194 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 52: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 52: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 53: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 53: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy194 = OE_None; /* EV: R-33326-45252 */}
+ case 54: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */}
break;
- case 54: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy194 = 0;}
+ case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy70 = 0;}
break;
- case 55: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 70: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==70);
- case 143: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==143);
-{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
+ case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
+ case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
+{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;}
break;
- case 57: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 74: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==74);
- case 184: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==184);
- case 187: /* in_op ::= NOT IN */ yytestcase(yyruleno==187);
- case 213: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==213);
-{yymsp[-1].minor.yy194 = 1;}
+ case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
+ case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
+ case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
+ case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
+{yymsp[-1].minor.yy70 = 1;}
break;
- case 58: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy194 = 0;}
+ case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy70 = 0;}
break;
- case 60: /* tconscomma ::= COMMA */
+ case 61: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 62: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);}
+ case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);}
break;
- case 63: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0,
+ case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 64: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
+ case 65: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
break;
- case 65: /* 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.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
}
break;
- case 67: /* onconf ::= */
- case 69: /* orconf ::= */ yytestcase(yyruleno==69);
-{yymsp[1].minor.yy194 = OE_Default;}
+ case 68: /* onconf ::= */
+ case 70: /* orconf ::= */ yytestcase(yyruleno==70);
+{yymsp[1].minor.yy70 = OE_Default;}
break;
- case 68: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;}
+ case 69: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
break;
- case 71: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy194 = OE_Ignore;}
+ case 72: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy70 = OE_Ignore;}
break;
- case 72: /* resolvetype ::= REPLACE */
- case 144: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==144);
-{yymsp[0].minor.yy194 = OE_Replace;}
+ case 73: /* resolvetype ::= REPLACE */
+ case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
+{yymsp[0].minor.yy70 = OE_Replace;}
break;
- case 73: /* cmd ::= DROP TABLE ifexists fullname */
+ case 74: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
}
break;
- case 76: /* 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.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
}
break;
- case 77: /* cmd ::= DROP VIEW ifexists fullname */
+ case 78: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
}
break;
- case 78: /* cmd ::= select */
+ case 79: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy243, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+}
+ break;
+ case 80: /* select ::= WITH wqlist selectnowith */
+{
+ Select *p = yymsp[0].minor.yy489;
+ if( p ){
+ p->pWith = yymsp[-1].minor.yy449;
+ parserDoubleLinkSelect(pParse, p);
+ }else{
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ }
+ yymsp[-2].minor.yy489 = p;
}
break;
- case 79: /* select ::= with selectnowith */
+ case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy243;
+ Select *p = yymsp[0].minor.yy489;
if( p ){
- p->pWith = yymsp[-1].minor.yy285;
+ p->pWith = yymsp[-1].minor.yy449;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ }
+ yymsp[-3].minor.yy489 = p;
+}
+ break;
+ case 82: /* select ::= selectnowith */
+{
+ Select *p = yymsp[0].minor.yy489;
+ if( p ){
+ parserDoubleLinkSelect(pParse, p);
}
- yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/
+ yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
}
break;
- case 80: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy243;
- Select *pLhs = yymsp[-2].minor.yy243;
+ Select *pRhs = yymsp[0].minor.yy489;
+ Select *pLhs = yymsp[-2].minor.yy489;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
- pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy194;
+ pRhs->op = (u8)yymsp[-1].minor.yy70;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy243 = pRhs;
+ yymsp[-2].minor.yy489 = pRhs;
}
break;
- case 81: /* multiselect_op ::= UNION */
- case 83: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==83);
-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/}
+ case 84: /* multiselect_op ::= UNION */
+ case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
+{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
break;
- case 82: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy194 = TK_ALL;}
+ case 85: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy70 = TK_ALL;}
break;
- case 84: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
-#if SELECTTRACE_ENABLED
- Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
-#endif
- yymsp[-8].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset);
-#if SELECTTRACE_ENABLED
- /* Populate the Select.zSelName[] string that is used to help with
- ** query planner debugging, to differentiate between multiple Select
- ** objects in a complex query.
- **
- ** If the SELECT keyword is immediately followed by a C-style comment
- ** then extract the first few alphanumeric characters from within that
- ** comment to be the zSelName value. Otherwise, the label is #N where
- ** is an integer that is incremented with each SELECT statement seen.
- */
- if( yymsp[-8].minor.yy243!=0 ){
- const char *z = s.z+6;
- int i;
- sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->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(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, z);
- }
+ yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18);
+}
+ break;
+ case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+{
+ yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18);
+ if( yymsp[-9].minor.yy489 ){
+ yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327;
+ }else{
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
}
-#endif /* SELECTRACE_ENABLED */
}
break;
- case 85: /* values ::= VALUES LP nexprlist RP */
+ case 89: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0);
+ yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
}
break;
- case 86: /* values ::= values COMMA LP exprlist RP */
+ case 90: /* values ::= values COMMA LP nexprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy243;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+ Select *pRight, *pLeft = yymsp[-4].minor.yy489;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = pLeft;
- yymsp[-4].minor.yy243 = pRight;
+ yymsp[-4].minor.yy489 = pRight;
}else{
- yymsp[-4].minor.yy243 = pLeft;
+ yymsp[-4].minor.yy489 = pLeft;
}
}
break;
- case 87: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy194 = SF_Distinct;}
+ case 91: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy70 = SF_Distinct;}
break;
- case 88: /* distinct ::= ALL */
-{yymsp[0].minor.yy194 = SF_All;}
+ case 92: /* distinct ::= ALL */
+{yymsp[0].minor.yy70 = SF_All;}
break;
- case 90: /* sclp ::= */
- case 118: /* orderby_opt ::= */ yytestcase(yyruleno==118);
- case 125: /* groupby_opt ::= */ yytestcase(yyruleno==125);
- case 200: /* exprlist ::= */ yytestcase(yyruleno==200);
- case 203: /* paren_exprlist ::= */ yytestcase(yyruleno==203);
- case 208: /* eidlist_opt ::= */ yytestcase(yyruleno==208);
-{yymsp[1].minor.yy148 = 0;}
+ case 94: /* sclp ::= */
+ case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
+ case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134);
+ case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
+ case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
+ case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
+{yymsp[1].minor.yy420 = 0;}
break;
- case 91: /* selcollist ::= sclp expr as */
+ case 95: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy148, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy148,&yymsp[-1].minor.yy190);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392);
}
break;
- case 92: /* selcollist ::= sclp STAR */
+ case 96: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
+ yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
}
break;
- case 93: /* selcollist ::= sclp nm DOT STAR */
+ case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
}
break;
- case 94: /* as ::= AS nm */
- case 105: /* dbnm ::= DOT nm */ yytestcase(yyruleno==105);
- case 222: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==222);
- case 223: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==223);
+ case 98: /* as ::= AS nm */
+ case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
+ case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236);
+ case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 96: /* from ::= */
-{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
+ case 100: /* from ::= */
+{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
break;
- case 97: /* from ::= FROM seltablist */
+ case 101: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy185 = yymsp[0].minor.yy185;
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185);
+ yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
}
break;
- case 98: /* stl_prefix ::= seltablist joinop */
+ case 102: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194;
+ if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70;
}
break;
- case 99: /* stl_prefix ::= */
-{yymsp[1].minor.yy185 = 0;}
+ case 103: /* stl_prefix ::= */
+{yymsp[1].minor.yy135 = 0;}
break;
- case 100: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0);
+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0);
}
break;
- case 101: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
{
- yymsp[-8].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148);
+ yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420);
}
break;
- case 102: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
}
break;
- case 103: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){
- yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185;
- }else if( yymsp[-4].minor.yy185->nSrc==1 ){
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- if( yymsp[-6].minor.yy185 ){
- struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy185->a;
+ if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){
+ yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135;
+ }else if( yymsp[-4].minor.yy135->nSrc==1 ){
+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ if( yymsp[-6].minor.yy135 ){
+ struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy135->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.yy185);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0);
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
}
}
break;
- case 104: /* dbnm ::= */
- case 113: /* indexed_opt ::= */ yytestcase(yyruleno==113);
+ case 108: /* dbnm ::= */
+ case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 106: /* fullname ::= nm dbnm */
-{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 110: /* fullname ::= nm */
+{
+ yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+}
+ yymsp[0].minor.yy135 = yylhsminor.yy135;
break;
- case 107: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy194 = JT_INNER; }
+ case 111: /* fullname ::= nm DOT nm */
+{
+ yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+}
+ yymsp[-2].minor.yy135 = yylhsminor.yy135;
+ break;
+ case 112: /* xfullname ::= nm */
+{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+ break;
+ case 113: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 108: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 114: /* xfullname ::= nm DOT nm AS nm */
+{
+ yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+}
break;
- case 109: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 115: /* xfullname ::= nm AS nm */
+{
+ yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+}
break;
- case 110: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 116: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy70 = JT_INNER; }
break;
- case 111: /* on_opt ::= ON expr */
- case 128: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==128);
- case 135: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==135);
- case 196: /* case_else ::= ELSE expr */ yytestcase(yyruleno==196);
-{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
+ case 117: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 112: /* on_opt ::= */
- case 127: /* having_opt ::= */ yytestcase(yyruleno==127);
- case 134: /* where_opt ::= */ yytestcase(yyruleno==134);
- case 197: /* case_else ::= */ yytestcase(yyruleno==197);
- case 199: /* case_operand ::= */ yytestcase(yyruleno==199);
-{yymsp[1].minor.yy72 = 0;}
+ case 118: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 114: /* indexed_opt ::= INDEXED BY nm */
+ case 119: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ break;
+ case 120: /* on_opt ::= ON expr */
+ case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
+ case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
+ case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
+{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;}
+ break;
+ case 121: /* on_opt ::= */
+ case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
+ case 138: /* limit_opt ::= */ yytestcase(yyruleno==138);
+ case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
+ case 211: /* case_else ::= */ yytestcase(yyruleno==211);
+ case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
+{yymsp[1].minor.yy18 = 0;}
+ break;
+ case 123: /* indexed_opt ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 115: /* indexed_opt ::= NOT INDEXED */
+ case 124: /* indexed_opt ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 116: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
+ case 125: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
break;
- case 117: /* using_opt ::= */
- case 145: /* idlist_opt ::= */ yytestcase(yyruleno==145);
-{yymsp[1].minor.yy254 = 0;}
+ case 126: /* using_opt ::= */
+ case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
+{yymsp[1].minor.yy48 = 0;}
break;
- case 119: /* orderby_opt ::= ORDER BY sortlist */
- case 126: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==126);
-{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;}
+ case 128: /* orderby_opt ::= ORDER BY sortlist */
+ case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
+{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;}
break;
- case 120: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 129: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr);
- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194);
+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
}
break;
- case 121: /* sortlist ::= expr sortorder */
+ case 130: /* sortlist ::= expr sortorder */
{
- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194);
+ yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
}
break;
- case 122: /* sortorder ::= ASC */
-{yymsp[0].minor.yy194 = SQLITE_SO_ASC;}
+ case 131: /* sortorder ::= ASC */
+{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
break;
- case 123: /* sortorder ::= DESC */
-{yymsp[0].minor.yy194 = SQLITE_SO_DESC;}
+ case 132: /* sortorder ::= DESC */
+{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
break;
- case 124: /* sortorder ::= */
-{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;}
+ case 133: /* sortorder ::= */
+{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
break;
- case 129: /* limit_opt ::= */
-{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;}
+ case 139: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
break;
- case 130: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;}
+ case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
break;
- case 131: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;}
+ case 141: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
break;
- case 132: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;}
- break;
- case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt orderby_opt limit_opt */
+ case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt orderby_opt limit_opt */
{
- sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1);
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0);
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
- yymsp[-2].minor.yy72 = sqlite3LimitWhere(pParse, yymsp[-4].minor.yy185, yymsp[-2].minor.yy72, yymsp[-1].minor.yy148, yymsp[0].minor.yy354.pLimit, yymsp[0].minor.yy354.pOffset, "DELETE");
-#else
- if( yymsp[-1].minor.yy148 || yymsp[0].minor.yy354.pLimit ){
- sqlite3ErrorMsg(pParse, "%s on DELETE not supported", yymsp[-1].minor.yy148?"ORDER BY":"LIMIT");
- sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy72);
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy354.pLimit);
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy354.pOffset);
- yymsp[-2].minor.yy72 = 0;
- }
-#endif
- sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy185,yymsp[-2].minor.yy72);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy135,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);
}
break;
- case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt orderby_opt limit_opt */
+ case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt orderby_opt limit_opt */
{
- sqlite3WithPush(pParse, yymsp[-9].minor.yy285, 1);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-5].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-3].minor.yy148,"set list");
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
- yymsp[-2].minor.yy72 = sqlite3LimitWhere(pParse, yymsp[-6].minor.yy185, yymsp[-2].minor.yy72, yymsp[-1].minor.yy148, yymsp[0].minor.yy354.pLimit, yymsp[0].minor.yy354.pOffset, "UPDATE");
-#else
- if( yymsp[-1].minor.yy148 || yymsp[0].minor.yy354.pLimit ){
- sqlite3ErrorMsg(pParse, "%s on UPDATE not supported", yymsp[-1].minor.yy148?"ORDER BY":"LIMIT");
- sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy72);
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy354.pLimit);
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy354.pOffset);
- yymsp[-2].minor.yy72 = 0;
- }
-#endif
- sqlite3Update(pParse,yymsp[-6].minor.yy185,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-7].minor.yy194);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-5].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-3].minor.yy420,"set list");
+ sqlite3Update(pParse,yymsp[-6].minor.yy135,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-7].minor.yy70,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,0);
}
break;
- case 137: /* setlist ::= setlist COMMA nm EQ expr */
+ case 146: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1);
}
break;
- case 138: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
+ yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
}
break;
- case 139: /* setlist ::= nm EQ expr */
+ case 148: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
- sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy148 = yylhsminor.yy148;
+ yymsp[-2].minor.yy420 = yylhsminor.yy420;
break;
- case 140: /* setlist ::= LP idlist RP EQ expr */
+ case 149: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
}
break;
- case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
+ case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
- sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
}
break;
- case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
+ case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
{
- sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1);
- sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
}
break;
- case 146: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
+ case 152: /* upsert ::= */
+{ yymsp[1].minor.yy340 = 0; }
+ break;
+ case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);}
+ break;
+ case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); }
break;
- case 147: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
+ case 155: /* upsert ::= ON CONFLICT DO NOTHING */
+{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
break;
- case 148: /* idlist ::= nm */
-{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 159: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
break;
- case 149: /* expr ::= LP expr RP */
-{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
+ case 160: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
break;
- case 150: /* expr ::= ID|INDEXED */
- case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
-{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 161: /* idlist ::= nm */
+{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 152: /* expr ::= nm DOT nm */
+ case 162: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;}
+ break;
+ case 163: /* expr ::= ID|INDEXED */
+ case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
+{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ break;
+ case 165: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
- spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
+ sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
+ }
+ yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
+ yymsp[-2].minor.yy18 = yylhsminor.yy18;
break;
- case 153: /* expr ::= nm DOT nm DOT nm */
+ case 166: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
- spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
+ sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
+ }
+ yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
+ yymsp[-4].minor.yy18 = yylhsminor.yy18;
break;
- case 154: /* term ::= NULL|FLOAT|BLOB */
- case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
-{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 167: /* term ::= NULL|FLOAT|BLOB */
+ case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
+{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 156: /* term ::= INTEGER */
+ case 169: /* term ::= INTEGER */
{
- yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
- yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
- yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
+ yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
}
- yymsp[0].minor.yy190 = yylhsminor.yy190;
+ yymsp[0].minor.yy18 = yylhsminor.yy18;
break;
- case 157: /* expr ::= VARIABLE */
+ case 170: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
u32 n = yymsp[0].minor.yy0.n;
- spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
+ yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
}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.yy190, &t, &t);
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy190.pExpr = 0;
+ yymsp[0].minor.yy18 = 0;
}else{
- yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
+ yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
}
}
}
break;
- case 158: /* expr ::= expr COLLATE ID|STRING */
+ case 171: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
- yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
}
break;
- case 159: /* expr ::= CAST LP expr AS typetoken RP */
+ case 172: /* expr ::= CAST LP expr AS typetoken RP */
{
- spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0);
+ yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0);
}
break;
- case 160: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
- sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
- }
- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
- spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){
- yylhsminor.yy190.pExpr->flags |= EP_Distinct;
- }
+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+}
+ yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ break;
+ case 174: /* expr ::= ID|INDEXED LP STAR RP */
+{
+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-4].minor.yy190 = yylhsminor.yy190;
+ yymsp[-3].minor.yy18 = yylhsminor.yy18;
break;
- case 161: /* expr ::= ID|INDEXED LP STAR RP */
+ case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
{
- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
+ sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
}
- yymsp[-3].minor.yy190 = yylhsminor.yy190;
+ yymsp[-5].minor.yy18 = yylhsminor.yy18;
break;
- case 162: /* term ::= CTIME_KW */
+ case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
{
- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
- spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
}
- yymsp[0].minor.yy190 = yylhsminor.yy190;
+ yymsp[-4].minor.yy18 = yylhsminor.yy18;
break;
- case 163: /* expr ::= LP nexprlist COMMA expr RP */
+ case 177: /* term ::= CTIME_KW */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
- yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yylhsminor.yy190.pExpr ){
- yylhsminor.yy190.pExpr->x.pList = pList;
- spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+ yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+}
+ yymsp[0].minor.yy18 = yylhsminor.yy18;
+ break;
+ case 178: /* expr ::= LP nexprlist COMMA expr RP */
+{
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy18 ){
+ yymsp[-4].minor.yy18->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
- yymsp[-4].minor.yy190 = yylhsminor.yy190;
break;
- case 164: /* expr ::= expr AND expr */
- case 165: /* expr ::= expr OR expr */ yytestcase(yyruleno==165);
- case 166: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==166);
- case 167: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==167);
- case 168: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==168);
- case 169: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==169);
- case 170: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==170);
- case 171: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==171);
-{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
+ case 179: /* expr ::= expr AND expr */
+ case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
+ case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
+ case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
+ case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
+ case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
+ case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
+ case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
+{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
break;
- case 172: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 187: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
- case 173: /* expr ::= expr likeop expr */
+ case 188: /* expr ::= expr likeop expr */
{
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
yymsp[-1].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
- yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
- exprNot(pParse, bNot, &yymsp[-2].minor.yy190);
- yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
- if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18);
+ yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0);
+ if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc;
}
break;
- case 174: /* expr ::= expr likeop expr ESCAPE expr */
+ case 189: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
yymsp[-3].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
- exprNot(pParse, bNot, &yymsp[-4].minor.yy190);
- yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
- if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc;
}
break;
- case 175: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
+ case 190: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
break;
- case 176: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
+ case 191: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
break;
- case 177: /* expr ::= expr IS expr */
+ case 192: /* expr ::= expr IS expr */
{
- spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
+ yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL);
}
break;
- case 178: /* expr ::= expr IS NOT expr */
+ case 193: /* expr ::= expr IS NOT expr */
{
- spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
+ yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL);
}
break;
- case 179: /* expr ::= NOT expr */
- case 180: /* expr ::= BITNOT expr */ yytestcase(yyruleno==180);
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+ case 194: /* expr ::= NOT expr */
+ case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
+{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/}
break;
- case 181: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
- break;
- case 182: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+ case 196: /* expr ::= PLUS|MINUS expr */
+{
+ yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
+ /*A-overwrites-B*/
+}
break;
- case 183: /* between_op ::= BETWEEN */
- case 186: /* in_op ::= IN */ yytestcase(yyruleno==186);
-{yymsp[0].minor.yy194 = 0;}
+ case 197: /* between_op ::= BETWEEN */
+ case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
+{yymsp[0].minor.yy70 = 0;}
break;
- case 185: /* expr ::= expr between_op expr AND expr */
+ case 199: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0);
- if( yymsp[-4].minor.yy190.pExpr ){
- yymsp[-4].minor.yy190.pExpr->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-4].minor.yy18 ){
+ yymsp[-4].minor.yy18->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
- yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
}
break;
- case 188: /* expr ::= expr in_op LP exprlist RP */
+ case 202: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy148==0 ){
+ if( yymsp[-1].minor.yy420==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -140268,9 +149863,9 @@ static void yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1);
- }else if( yymsp[-1].minor.yy148->nExpr==1 ){
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18);
+ yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1);
+ }else if( yymsp[-1].minor.yy420->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
@@ -140287,201 +149882,199 @@ 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.yy148->a[0].pExpr;
- yymsp[-1].minor.yy148->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+ Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr;
+ yymsp[-1].minor.yy420->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
/* 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;
}
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
}else{
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
- if( yymsp[-4].minor.yy190.pExpr ){
- yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-4].minor.yy18 ){
+ yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
}
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
}
- yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 189: /* expr ::= LP select RP */
+ case 203: /* expr ::= LP select RP */
{
- spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
+ yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
}
break;
- case 190: /* expr ::= expr in_op LP select RP */
+ case 204: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
- yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489);
+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
}
break;
- case 191: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
- Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
- yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
+ Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
+ if( yymsp[0].minor.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect);
+ if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
}
break;
- case 192: /* expr ::= EXISTS LP select RP */
+ case 206: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
- p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
+ p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
}
break;
- case 193: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0);
- if( yymsp[-4].minor.yy190.pExpr ){
- yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
+ yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0);
+ if( yymsp[-4].minor.yy18 ){
+ yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
}
}
break;
- case 194: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
+ yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
}
break;
- case 195: /* case_exprlist ::= WHEN expr THEN expr */
+ case 209: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
+ yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18);
}
break;
- case 198: /* case_operand ::= expr */
-{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
+ case 212: /* case_operand ::= expr */
+{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
break;
- case 201: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
+ case 215: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
break;
- case 202: /* nexprlist ::= expr */
-{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
+ case 216: /* nexprlist ::= expr */
+{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
break;
- case 204: /* paren_exprlist ::= LP exprlist RP */
- case 209: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==209);
-{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
+ case 218: /* paren_exprlist ::= LP exprlist RP */
+ case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
+{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;}
break;
- case 205: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 219: /* 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.yy148, yymsp[-10].minor.yy194,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
+ if( IN_RENAME_OBJECT && pParse->pNewIndex ){
+ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
+ }
}
break;
- case 206: /* uniqueflag ::= UNIQUE */
- case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246);
-{yymsp[0].minor.yy194 = OE_Abort;}
+ case 220: /* uniqueflag ::= UNIQUE */
+ case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
+{yymsp[0].minor.yy70 = OE_Abort;}
break;
- case 207: /* uniqueflag ::= */
-{yymsp[1].minor.yy194 = OE_None;}
+ case 221: /* uniqueflag ::= */
+{yymsp[1].minor.yy70 = OE_None;}
break;
- case 210: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
+ yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
}
break;
- case 211: /* eidlist ::= nm collate sortorder */
+ case 225: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
}
break;
- case 214: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
+ case 228: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
break;
- case 215: /* cmd ::= VACUUM */
+ case 229: /* cmd ::= VACUUM */
{sqlite3Vacuum(pParse,0);}
break;
- case 216: /* cmd ::= VACUUM nm */
+ case 230: /* cmd ::= VACUUM nm */
{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
break;
- case 217: /* cmd ::= PRAGMA nm dbnm */
+ case 231: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 218: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 219: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 220: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 221: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 235: /* 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 224: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 238: /* 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.yy145, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all);
}
break;
- case 225: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 239: /* 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.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 226: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 240: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 227: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
+ case 241: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
break;
- case 228: /* trigger_time ::= */
-{ yymsp[1].minor.yy194 = TK_BEFORE; }
+ case 242: /* trigger_time ::= */
+{ yymsp[1].minor.yy70 = TK_BEFORE; }
break;
- case 229: /* trigger_event ::= DELETE|INSERT */
- case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230);
-{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
+ case 243: /* trigger_event ::= DELETE|INSERT */
+ case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244);
+{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;}
break;
- case 231: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
+ case 245: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
break;
- case 232: /* when_clause ::= */
- case 251: /* key_opt ::= */ yytestcase(yyruleno==251);
-{ yymsp[1].minor.yy72 = 0; }
+ case 246: /* when_clause ::= */
+ case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
+ case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
+{ yymsp[1].minor.yy18 = 0; }
break;
- case 233: /* when_clause ::= WHEN expr */
- case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252);
-{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
+ case 247: /* when_clause ::= WHEN expr */
+ case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
+{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
break;
- case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy145!=0 );
- yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
- yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ assert( yymsp[-2].minor.yy207!=0 );
+ yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207;
+ yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207;
}
break;
- case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy145!=0 );
- yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ assert( yymsp[-1].minor.yy207!=0 );
+ yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
}
break;
- case 236: /* trnm ::= nm DOT nm */
+ case 250: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -140489,196 +150082,306 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 237: /* tridxby ::= INDEXED BY nm */
+ case 251: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 238: /* tridxby ::= NOT INDEXED */
+ case 252: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 239: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
+ case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);}
+ yymsp[-7].minor.yy207 = yylhsminor.yy207;
break;
- case 240: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
-{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
+ case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+{
+ yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/
+}
+ yymsp[-7].minor.yy207 = yylhsminor.yy207;
break;
- case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
+ case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);}
+ yymsp[-5].minor.yy207 = yylhsminor.yy207;
break;
- case 242: /* trigger_cmd ::= select */
-{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
+ case 256: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/}
+ yymsp[-2].minor.yy207 = yylhsminor.yy207;
break;
- case 243: /* expr ::= RAISE LP IGNORE RP */
+ case 257: /* expr ::= RAISE LP IGNORE RP */
{
- spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy190.pExpr ){
- yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
+ yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy18 ){
+ yymsp[-3].minor.yy18->affinity = OE_Ignore;
}
}
break;
- case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy190.pExpr ) {
- yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
+ yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
+ if( yymsp[-5].minor.yy18 ) {
+ yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70;
}
}
break;
- case 245: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy194 = OE_Rollback;}
+ case 259: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy70 = OE_Rollback;}
break;
- case 247: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy194 = OE_Fail;}
+ case 261: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy70 = OE_Fail;}
break;
- case 248: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
}
break;
- case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
}
break;
- case 250: /* cmd ::= DETACH database_kw_opt expr */
+ case 264: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
+ sqlite3Detach(pParse, yymsp[0].minor.yy18);
}
break;
- case 253: /* cmd ::= REINDEX */
+ case 267: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 254: /* cmd ::= REINDEX nm dbnm */
+ case 268: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 255: /* cmd ::= ANALYZE */
+ case 269: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 256: /* cmd ::= ANALYZE nm dbnm */
+ case 270: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 257: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
}
break;
- case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
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 259: /* add_column_fullname ::= fullname */
+ case 273: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+}
+ break;
+ case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+{
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 260: /* cmd ::= create_vtab */
+ case 275: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 261: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 276: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 262: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 277: /* 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.yy194);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70);
}
break;
- case 263: /* vtabarg ::= */
+ case 278: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 264: /* vtabargtoken ::= ANY */
- case 265: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==265);
- case 266: /* lp ::= LP */ yytestcase(yyruleno==266);
+ case 279: /* vtabargtoken ::= ANY */
+ case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
+ case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 267: /* with ::= */
-{yymsp[1].minor.yy285 = 0;}
+ case 282: /* with ::= WITH wqlist */
+ case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+ break;
+ case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
+{
+ yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/
+}
+ break;
+ case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+{
+ yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489);
+}
break;
- case 268: /* with ::= WITH wqlist */
-{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
+ case 286: /* windowdefn_list ::= windowdefn */
+{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
+ yymsp[0].minor.yy327 = yylhsminor.yy327;
break;
- case 269: /* with ::= WITH RECURSIVE wqlist */
-{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
+ case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+{
+ assert( yymsp[0].minor.yy327!=0 );
+ yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327;
+ yylhsminor.yy327 = yymsp[0].minor.yy327;
+}
+ yymsp[-2].minor.yy327 = yylhsminor.yy327;
break;
- case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 288: /* windowdefn ::= nm AS window */
{
- yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
+ if( ALWAYS(yymsp[0].minor.yy327) ){
+ yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
+ }
+ yylhsminor.yy327 = yymsp[0].minor.yy327;
}
+ yymsp[-2].minor.yy327 = yylhsminor.yy327;
break;
- case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
{
- yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
+ yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327;
+ if( ALWAYS(yymsp[-4].minor.yy327) ){
+ yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420;
+ yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420;
+ }
+}
+ break;
+ case 290: /* part_opt ::= PARTITION BY nexprlist */
+{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; }
+ break;
+ case 291: /* part_opt ::= */
+{ yymsp[1].minor.yy420 = 0; }
+ break;
+ case 292: /* frame_opt ::= */
+{
+ yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
+}
+ break;
+ case 293: /* frame_opt ::= range_or_rows frame_bound_s */
+{
+ yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0);
}
+ yymsp[-1].minor.yy327 = yylhsminor.yy327;
+ break;
+ case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+{
+ yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr);
+}
+ yymsp[-4].minor.yy327 = yylhsminor.yy327;
+ break;
+ case 295: /* range_or_rows ::= RANGE */
+{ yymsp[0].minor.yy70 = TK_RANGE; }
+ break;
+ case 296: /* range_or_rows ::= ROWS */
+{ yymsp[0].minor.yy70 = TK_ROWS; }
+ break;
+ case 297: /* frame_bound_s ::= frame_bound */
+ case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299);
+{ yylhsminor.yy119 = yymsp[0].minor.yy119; }
+ yymsp[0].minor.yy119 = yylhsminor.yy119;
+ break;
+ case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300);
+{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;}
+ break;
+ case 301: /* frame_bound ::= expr PRECEDING */
+{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
+ yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ break;
+ case 302: /* frame_bound ::= CURRENT ROW */
+{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; }
+ break;
+ case 303: /* frame_bound ::= expr FOLLOWING */
+{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
+ yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ break;
+ case 304: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; }
+ break;
+ case 305: /* over_clause ::= filter_opt OVER window */
+{
+ yylhsminor.yy327 = yymsp[0].minor.yy327;
+ assert( yylhsminor.yy327!=0 );
+ yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+}
+ yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ break;
+ case 306: /* over_clause ::= filter_opt OVER nm */
+{
+ yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy327 ){
+ yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+ }else{
+ sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
+ }
+}
+ yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ break;
+ case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
break;
default:
- /* (272) input ::= cmdlist */ yytestcase(yyruleno==272);
- /* (273) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==273);
- /* (274) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=274);
- /* (275) ecmd ::= SEMI */ yytestcase(yyruleno==275);
- /* (276) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==276);
- /* (277) explain ::= */ yytestcase(yyruleno==277);
- /* (278) trans_opt ::= */ yytestcase(yyruleno==278);
- /* (279) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==279);
- /* (280) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==280);
- /* (281) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==281);
- /* (282) savepoint_opt ::= */ yytestcase(yyruleno==282);
- /* (283) cmd ::= create_table create_table_args */ yytestcase(yyruleno==283);
- /* (284) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==284);
- /* (285) columnlist ::= columnname carglist */ yytestcase(yyruleno==285);
- /* (286) nm ::= ID|INDEXED */ yytestcase(yyruleno==286);
- /* (287) nm ::= STRING */ yytestcase(yyruleno==287);
- /* (288) nm ::= JOIN_KW */ yytestcase(yyruleno==288);
- /* (289) typetoken ::= typename */ yytestcase(yyruleno==289);
- /* (290) typename ::= ID|STRING */ yytestcase(yyruleno==290);
- /* (291) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=291);
- /* (292) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=292);
- /* (293) carglist ::= carglist ccons */ yytestcase(yyruleno==293);
- /* (294) carglist ::= */ yytestcase(yyruleno==294);
- /* (295) ccons ::= NULL onconf */ yytestcase(yyruleno==295);
- /* (296) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==296);
- /* (297) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==297);
- /* (298) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=298);
- /* (299) tconscomma ::= */ yytestcase(yyruleno==299);
- /* (300) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=300);
- /* (301) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=301);
- /* (302) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=302);
- /* (303) oneselect ::= values */ yytestcase(yyruleno==303);
- /* (304) sclp ::= selcollist COMMA */ yytestcase(yyruleno==304);
- /* (305) as ::= ID|STRING */ yytestcase(yyruleno==305);
- /* (306) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=306);
- /* (307) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==307);
- /* (308) exprlist ::= nexprlist */ yytestcase(yyruleno==308);
- /* (309) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=309);
- /* (310) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=310);
- /* (311) nmnum ::= ON */ yytestcase(yyruleno==311);
- /* (312) nmnum ::= DELETE */ yytestcase(yyruleno==312);
- /* (313) nmnum ::= DEFAULT */ yytestcase(yyruleno==313);
- /* (314) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==314);
- /* (315) foreach_clause ::= */ yytestcase(yyruleno==315);
- /* (316) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==316);
- /* (317) trnm ::= nm */ yytestcase(yyruleno==317);
- /* (318) tridxby ::= */ yytestcase(yyruleno==318);
- /* (319) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==319);
- /* (320) database_kw_opt ::= */ yytestcase(yyruleno==320);
- /* (321) kwcolumn_opt ::= */ yytestcase(yyruleno==321);
- /* (322) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==322);
- /* (323) vtabarglist ::= vtabarg */ yytestcase(yyruleno==323);
- /* (324) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==324);
- /* (325) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==325);
- /* (326) anylist ::= */ yytestcase(yyruleno==326);
- /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
- /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
+ /* (309) input ::= cmdlist */ yytestcase(yyruleno==309);
+ /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310);
+ /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311);
+ /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312);
+ /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313);
+ /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314);
+ /* (315) trans_opt ::= */ yytestcase(yyruleno==315);
+ /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316);
+ /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317);
+ /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318);
+ /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319);
+ /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320);
+ /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321);
+ /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322);
+ /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323);
+ /* (324) nm ::= STRING */ yytestcase(yyruleno==324);
+ /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325);
+ /* (326) typetoken ::= typename */ yytestcase(yyruleno==326);
+ /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327);
+ /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328);
+ /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329);
+ /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330);
+ /* (331) carglist ::= */ yytestcase(yyruleno==331);
+ /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332);
+ /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333);
+ /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334);
+ /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335);
+ /* (336) tconscomma ::= */ yytestcase(yyruleno==336);
+ /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337);
+ /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338);
+ /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339);
+ /* (340) oneselect ::= values */ yytestcase(yyruleno==340);
+ /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341);
+ /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342);
+ /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343);
+ /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344);
+ /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345);
+ /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346);
+ /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347);
+ /* (348) nmnum ::= ON */ yytestcase(yyruleno==348);
+ /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349);
+ /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350);
+ /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351);
+ /* (352) foreach_clause ::= */ yytestcase(yyruleno==352);
+ /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353);
+ /* (354) trnm ::= nm */ yytestcase(yyruleno==354);
+ /* (355) tridxby ::= */ yytestcase(yyruleno==355);
+ /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356);
+ /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357);
+ /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358);
+ /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359);
+ /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360);
+ /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361);
+ /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362);
+ /* (363) anylist ::= */ yytestcase(yyruleno==363);
+ /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364);
+ /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365);
+ /* (366) with ::= */ yytestcase(yyruleno==366);
break;
/********** End reduce actions ************************************************/
};
@@ -140694,16 +150397,12 @@ static void yy_reduce(
/* It is not possible for a REDUCE to be followed by an error */
assert( yyact!=YY_ERROR_ACTION );
- if( yyact==YY_ACCEPT_ACTION ){
- yypParser->yytos += yysize;
- yy_accept(yypParser);
- }else{
- yymsp += yysize+1;
- yypParser->yytos = yymsp;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yyTraceShift(yypParser, yyact);
- }
+ yymsp += yysize+1;
+ yypParser->yytos = yymsp;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yyTraceShift(yypParser, yyact, "... then shift");
+ return yyact;
}
/*
@@ -140713,7 +150412,8 @@ static void yy_reduce(
static void yy_parse_failed(
yyParser *yypParser /* The parser */
){
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ sqlite3ParserCTX_FETCH
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
@@ -140724,7 +150424,8 @@ static void yy_parse_failed(
** parser fails */
/************ Begin %parse_failure code ***************************************/
/************ End %parse_failure code *****************************************/
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserCTX_STORE
}
#endif /* YYNOERRORRECOVERY */
@@ -140736,15 +150437,20 @@ static void yy_syntax_error(
int yymajor, /* The major type of the error token */
sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */
){
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ sqlite3ParserCTX_FETCH
#define TOKEN yyminor
/************ Begin %syntax_error code ****************************************/
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
- assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ if( TOKEN.z[0] ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ }else{
+ sqlite3ErrorMsg(pParse, "incomplete input");
+ }
/************ End %syntax_error code ******************************************/
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserCTX_STORE
}
/*
@@ -140753,7 +150459,8 @@ static void yy_syntax_error(
static void yy_accept(
yyParser *yypParser /* The parser */
){
- sqlite3ParserARG_FETCH;
+ sqlite3ParserARG_FETCH
+ sqlite3ParserCTX_FETCH
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
@@ -140767,7 +150474,8 @@ static void yy_accept(
** parser accepts */
/*********** Begin %parse_accept code *****************************************/
/*********** End %parse_accept code *******************************************/
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3ParserCTX_STORE
}
/* The main parser program.
@@ -140796,38 +150504,51 @@ SQLITE_PRIVATE void sqlite3Parser(
sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
- unsigned int yyact; /* The parser action. */
+ YYACTIONTYPE yyact; /* The parser action. */
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
int yyendofinput; /* True if we are at the end of input */
#endif
#ifdef YYERRORSYMBOL
int yyerrorhit = 0; /* True if yymajor has invoked an error */
#endif
- yyParser *yypParser; /* The parser */
+ yyParser *yypParser = (yyParser*)yyp; /* The parser */
+ sqlite3ParserCTX_FETCH
+ sqlite3ParserARG_STORE
- yypParser = (yyParser*)yyp;
assert( yypParser->yytos!=0 );
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
#endif
- sqlite3ParserARG_STORE;
+ yyact = yypParser->yytos->stateno;
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
+ if( yyact < YY_MIN_REDUCE ){
+ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
+ yyTracePrompt,yyTokenName[yymajor],yyact);
+ }else{
+ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
+ }
}
#endif
do{
- yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact <= YY_MAX_SHIFTREDUCE ){
- yy_shift(yypParser,yyact,yymajor,yyminor);
+ assert( yyact==yypParser->yytos->stateno );
+ yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
+ if( yyact >= YY_MIN_REDUCE ){
+ yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,
+ yyminor sqlite3ParserCTX_PARAM);
+ }else if( yyact <= YY_MAX_SHIFTREDUCE ){
+ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt--;
#endif
- yymajor = YYNOCODE;
- }else if( yyact <= YY_MAX_REDUCE ){
- yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
+ break;
+ }else if( yyact==YY_ACCEPT_ACTION ){
+ yypParser->yytos--;
+ yy_accept(yypParser);
+ return;
}else{
assert( yyact == YY_ERROR_ACTION );
yyminorunion.yy0 = yyminor;
@@ -140894,6 +150615,8 @@ SQLITE_PRIVATE void sqlite3Parser(
}
yypParser->yyerrcnt = 3;
yyerrorhit = 1;
+ if( yymajor==YYNOCODE ) break;
+ yyact = yypParser->yytos->stateno;
#elif defined(YYNOERRORRECOVERY)
/* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
** do any kind of error recovery. Instead, simply invoke the syntax
@@ -140904,8 +150627,7 @@ SQLITE_PRIVATE void sqlite3Parser(
*/
yy_syntax_error(yypParser,yymajor, yyminor);
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- yymajor = YYNOCODE;
-
+ break;
#else /* YYERRORSYMBOL is not defined */
/* This is what we do if the grammar does not define ERROR:
**
@@ -140927,10 +150649,10 @@ SQLITE_PRIVATE void sqlite3Parser(
yypParser->yyerrcnt = -1;
#endif
}
- yymajor = YYNOCODE;
+ break;
#endif
}
- }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
+ }while( yypParser->yytos>yypParser->yystack );
#ifndef NDEBUG
if( yyTraceFILE ){
yyStackEntry *i;
@@ -140946,6 +150668,21 @@ SQLITE_PRIVATE void sqlite3Parser(
return;
}
+/*
+** Return the fallback token corresponding to canonical token iToken, or
+** 0 if iToken has no fallback.
+*/
+SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){
+#ifdef YYFALLBACK
+ if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){
+ return yyFallback[iToken];
+ }
+#else
+ (void)iToken;
+#endif
+ return 0;
+}
+
/************** End of parse.c ***********************************************/
/************** Begin file tokenize.c ****************************************/
/*
@@ -141004,11 +150741,12 @@ SQLITE_PRIVATE void sqlite3Parser(
#define CC_TILDA 25 /* '~' */
#define CC_DOT 26 /* '.' */
#define CC_ILLEGAL 27 /* Illegal character */
+#define CC_NUL 28 /* 0x00 */
static const unsigned char aiClass[] = {
#ifdef SQLITE_ASCII
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
-/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27,
+/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27,
/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6,
@@ -141107,19 +150845,20 @@ const unsigned char ebcdicToAscii[] = {
** is substantially reduced. This is important for embedded applications
** on platforms with limited memory.
*/
-/* Hash score: 182 */
-/* zKWText[] encodes 834 bytes of keyword text in 554 bytes */
+/* Hash score: 208 */
+/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
-/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */
-/* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
-/* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */
-/* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */
-/* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */
-/* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */
-/* VACUUMVIEWINITIALLY */
-static const char zKWText[553] = {
+/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN */
+/* OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
+/* IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT */
+/* WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST */
+/* COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED */
+/* ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL */
+/* ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW */
+/* INDOWINITIALLYPRIMARY */
+static const char zKWText[613] = {
'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
@@ -141132,83 +150871,90 @@ static const char zKWText[553] = {
'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
- 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
- 'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
- 'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
- 'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
- 'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
- 'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
- 'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
- 'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
- 'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
- 'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
- 'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
- 'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
- 'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
- 'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
- 'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
- 'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
- 'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
- 'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
- 'V','I','E','W','I','N','I','T','I','A','L','L','Y',
+ 'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W',
+ 'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A',
+ 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
+ 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
+ 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
+ 'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A',
+ 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
+ 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O',
+ 'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A',
+ 'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T',
+ 'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C',
+ 'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C',
+ 'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E',
+ 'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R',
+ 'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E',
+ 'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A',
+ 'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L',
+ 'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R',
+ 'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C',
+ 'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O',
+ 'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N',
+ 'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R',
+ 'Y',
};
/* aKWHash[i] is the hash value for the i-th keyword */
static const unsigned char aKWHash[127] = {
- 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0,
- 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0,
- 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71,
- 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44,
- 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25,
- 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0,
- 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14,
- 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113,
- 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0,
- 29, 0, 86, 63, 64, 0, 20, 61, 0, 56,
+ 74, 109, 124, 72, 106, 45, 0, 0, 81, 0, 76, 61, 0,
+ 42, 12, 77, 15, 0, 123, 84, 54, 118, 125, 19, 0, 0,
+ 130, 0, 128, 121, 0, 22, 96, 0, 9, 0, 0, 115, 69,
+ 0, 67, 6, 0, 48, 93, 136, 0, 126, 104, 0, 0, 44,
+ 0, 107, 24, 0, 17, 0, 131, 53, 23, 0, 5, 62, 132,
+ 99, 0, 0, 135, 110, 60, 134, 57, 113, 55, 0, 94, 0,
+ 103, 26, 0, 102, 0, 0, 0, 98, 95, 100, 105, 117, 14,
+ 39, 116, 0, 80, 0, 133, 114, 92, 59, 0, 129, 79, 119,
+ 86, 46, 83, 0, 0, 97, 40, 122, 120, 0, 127, 0, 0,
+ 29, 0, 89, 87, 88, 0, 20, 85, 111, 56,
};
/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0
** then the i-th keyword has no more hash collisions. Otherwise,
** the next keyword with the same hash is aKWHash[i]-1. */
-static const unsigned char aKWNext[124] = {
+static const unsigned char aKWNext[136] = {
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50,
- 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38,
- 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0,
- 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34,
- 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8,
- 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37,
- 73, 83, 0, 35, 68, 0, 0,
+ 0, 43, 3, 47, 0, 0, 32, 0, 0, 0, 0, 0, 0,
+ 0, 1, 64, 0, 0, 65, 0, 41, 0, 38, 0, 0, 0,
+ 0, 0, 49, 75, 0, 0, 30, 0, 58, 0, 0, 0, 31,
+ 63, 16, 34, 10, 0, 0, 0, 0, 0, 0, 0, 11, 70,
+ 91, 0, 0, 8, 0, 108, 0, 101, 28, 52, 68, 0, 112,
+ 0, 73, 51, 0, 90, 27, 37, 0, 71, 36, 82, 0, 35,
+ 66, 25, 18, 0, 0, 78,
};
/* aKWLen[i] is the length (in bytes) of the i-th keyword */
-static const unsigned char aKWLen[124] = {
+static const unsigned char aKWLen[136] = {
7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7,
- 6, 6, 5, 6, 5, 5, 9, 7, 7, 3, 2, 4, 4,
- 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4,
- 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7,
- 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8,
- 2, 4, 4, 4, 4, 4, 2, 2, 6, 5, 8, 5, 8,
- 3, 5, 5, 6, 4, 9, 3,
+ 6, 6, 5, 6, 5, 5, 5, 7, 7, 4, 2, 7, 3,
+ 6, 4, 7, 6, 12, 6, 9, 4, 6, 4, 5, 4, 7,
+ 6, 5, 6, 7, 5, 4, 7, 3, 2, 4, 5, 9, 5,
+ 6, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12,
+ 7, 9, 8, 8, 2, 4, 9, 4, 6, 7, 9, 4, 4,
+ 2, 6, 5, 8, 4, 5, 8, 4, 3, 9, 5, 5, 6,
+ 4, 6, 2, 9, 3, 7,
};
/* aKWOffset[i] is the index into zKWText[] of the start of
** the text for the i-th keyword. */
-static const unsigned short int aKWOffset[124] = {
+static const unsigned short int aKWOffset[136] = {
0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
- 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
- 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
- 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
- 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
- 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
- 521, 524, 529, 534, 540, 544, 549,
+ 199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248,
+ 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321,
+ 328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377,
+ 381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438,
+ 438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519,
+ 523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582,
+ 588, 591, 594, 597, 602, 606,
};
/* aKWCode[i] is the parser symbol code for the i-th keyword */
-static const unsigned char aKWCode[124] = {
+static const unsigned char aKWCode[136] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
@@ -141220,20 +150966,23 @@ static const unsigned char aKWCode[124] = {
TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH,
TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP,
- TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN,
- TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW,
- TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE,
- TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN,
- TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA,
- TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN,
- TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND,
- TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST,
- TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW,
- TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS,
- TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW,
- TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT,
- TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING,
- TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL,
+ TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RANGE, TK_BETWEEN,
+ TK_NOTHING, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC,
+ TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW,
+ TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_LIKE_KW,
+ TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT,
+ TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_NOTNULL,
+ TK_NOT, TK_NO, TK_NULL, TK_WHERE, TK_RECURSIVE,
+ TK_AFTER, TK_RENAME, TK_AND, TK_DEFAULT, TK_AUTOINCR,
+ TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT,
+ TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT,
+ TK_PARTITION, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP,
+ TK_PRECEDING, TK_FAIL, TK_FILTER, TK_REPLACE, TK_FOLLOWING,
+ TK_FROM, TK_JOIN_KW, TK_IF, TK_ISNULL, TK_ORDER,
+ TK_RESTRICT, TK_OVER, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS,
+ TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM,
+ TK_VIEW, TK_WINDOW, TK_DO, TK_INITIALLY, TK_ALL,
+ TK_PRIMARY,
};
/* Check to see if z[0..n-1] is a keyword. If it is, write the
** parser symbol code for that keyword into *pType. Always
@@ -141312,72 +151061,84 @@ static int keywordCode(const char *z, int n, int *pType){
testcase( i==55 ); /* UPDATE */
testcase( i==56 ); /* BEGIN */
testcase( i==57 ); /* INNER */
- testcase( i==58 ); /* RECURSIVE */
+ testcase( i==58 ); /* RANGE */
testcase( i==59 ); /* BETWEEN */
- testcase( i==60 ); /* NOTNULL */
- testcase( i==61 ); /* NOT */
- testcase( i==62 ); /* NO */
- testcase( i==63 ); /* NULL */
- testcase( i==64 ); /* LIKE */
- testcase( i==65 ); /* CASCADE */
- testcase( i==66 ); /* ASC */
- testcase( i==67 ); /* DELETE */
- testcase( i==68 ); /* CASE */
- testcase( i==69 ); /* COLLATE */
- testcase( i==70 ); /* CREATE */
- testcase( i==71 ); /* CURRENT_DATE */
- testcase( i==72 ); /* DETACH */
- testcase( i==73 ); /* IMMEDIATE */
- testcase( i==74 ); /* JOIN */
- testcase( i==75 ); /* INSERT */
- testcase( i==76 ); /* MATCH */
- testcase( i==77 ); /* PLAN */
- testcase( i==78 ); /* ANALYZE */
- testcase( i==79 ); /* PRAGMA */
- testcase( i==80 ); /* ABORT */
- testcase( i==81 ); /* VALUES */
- testcase( i==82 ); /* VIRTUAL */
- testcase( i==83 ); /* LIMIT */
- testcase( i==84 ); /* WHEN */
- testcase( i==85 ); /* WHERE */
- testcase( i==86 ); /* RENAME */
- testcase( i==87 ); /* AFTER */
- testcase( i==88 ); /* REPLACE */
- testcase( i==89 ); /* AND */
- testcase( i==90 ); /* DEFAULT */
- testcase( i==91 ); /* AUTOINCREMENT */
- testcase( i==92 ); /* TO */
- testcase( i==93 ); /* IN */
- testcase( i==94 ); /* CAST */
- testcase( i==95 ); /* COLUMN */
- testcase( i==96 ); /* COMMIT */
- testcase( i==97 ); /* CONFLICT */
- testcase( i==98 ); /* CROSS */
- testcase( i==99 ); /* CURRENT_TIMESTAMP */
- testcase( i==100 ); /* CURRENT_TIME */
- testcase( i==101 ); /* PRIMARY */
- testcase( i==102 ); /* DEFERRED */
- testcase( i==103 ); /* DISTINCT */
- testcase( i==104 ); /* IS */
- testcase( i==105 ); /* DROP */
- testcase( i==106 ); /* FAIL */
- testcase( i==107 ); /* FROM */
- testcase( i==108 ); /* FULL */
- testcase( i==109 ); /* GLOB */
- testcase( i==110 ); /* BY */
- testcase( i==111 ); /* IF */
- testcase( i==112 ); /* ISNULL */
- testcase( i==113 ); /* ORDER */
- testcase( i==114 ); /* RESTRICT */
- testcase( i==115 ); /* RIGHT */
- testcase( i==116 ); /* ROLLBACK */
- testcase( i==117 ); /* ROW */
- testcase( i==118 ); /* UNION */
- testcase( i==119 ); /* USING */
- testcase( i==120 ); /* VACUUM */
- testcase( i==121 ); /* VIEW */
- testcase( i==122 ); /* INITIALLY */
- testcase( i==123 ); /* ALL */
+ testcase( i==60 ); /* NOTHING */
+ testcase( i==61 ); /* GLOB */
+ testcase( i==62 ); /* BY */
+ testcase( i==63 ); /* CASCADE */
+ testcase( i==64 ); /* ASC */
+ testcase( i==65 ); /* DELETE */
+ testcase( i==66 ); /* CASE */
+ testcase( i==67 ); /* COLLATE */
+ testcase( i==68 ); /* CREATE */
+ testcase( i==69 ); /* CURRENT_DATE */
+ testcase( i==70 ); /* DETACH */
+ testcase( i==71 ); /* IMMEDIATE */
+ testcase( i==72 ); /* JOIN */
+ testcase( i==73 ); /* INSERT */
+ testcase( i==74 ); /* LIKE */
+ testcase( i==75 ); /* MATCH */
+ testcase( i==76 ); /* PLAN */
+ testcase( i==77 ); /* ANALYZE */
+ testcase( i==78 ); /* PRAGMA */
+ testcase( i==79 ); /* ABORT */
+ testcase( i==80 ); /* VALUES */
+ testcase( i==81 ); /* VIRTUAL */
+ testcase( i==82 ); /* LIMIT */
+ testcase( i==83 ); /* WHEN */
+ testcase( i==84 ); /* NOTNULL */
+ testcase( i==85 ); /* NOT */
+ testcase( i==86 ); /* NO */
+ testcase( i==87 ); /* NULL */
+ testcase( i==88 ); /* WHERE */
+ testcase( i==89 ); /* RECURSIVE */
+ testcase( i==90 ); /* AFTER */
+ testcase( i==91 ); /* RENAME */
+ testcase( i==92 ); /* AND */
+ testcase( i==93 ); /* DEFAULT */
+ testcase( i==94 ); /* AUTOINCREMENT */
+ testcase( i==95 ); /* TO */
+ testcase( i==96 ); /* IN */
+ testcase( i==97 ); /* CAST */
+ testcase( i==98 ); /* COLUMN */
+ testcase( i==99 ); /* COMMIT */
+ testcase( i==100 ); /* CONFLICT */
+ testcase( i==101 ); /* CROSS */
+ testcase( i==102 ); /* CURRENT_TIMESTAMP */
+ testcase( i==103 ); /* CURRENT_TIME */
+ testcase( i==104 ); /* CURRENT */
+ testcase( i==105 ); /* PARTITION */
+ testcase( i==106 ); /* DEFERRED */
+ testcase( i==107 ); /* DISTINCT */
+ testcase( i==108 ); /* IS */
+ testcase( i==109 ); /* DROP */
+ testcase( i==110 ); /* PRECEDING */
+ testcase( i==111 ); /* FAIL */
+ testcase( i==112 ); /* FILTER */
+ testcase( i==113 ); /* REPLACE */
+ testcase( i==114 ); /* FOLLOWING */
+ testcase( i==115 ); /* FROM */
+ testcase( i==116 ); /* FULL */
+ testcase( i==117 ); /* IF */
+ testcase( i==118 ); /* ISNULL */
+ testcase( i==119 ); /* ORDER */
+ testcase( i==120 ); /* RESTRICT */
+ testcase( i==121 ); /* OVER */
+ testcase( i==122 ); /* RIGHT */
+ testcase( i==123 ); /* ROLLBACK */
+ testcase( i==124 ); /* ROWS */
+ testcase( i==125 ); /* ROW */
+ testcase( i==126 ); /* UNBOUNDED */
+ testcase( i==127 ); /* UNION */
+ testcase( i==128 ); /* USING */
+ testcase( i==129 ); /* VACUUM */
+ testcase( i==130 ); /* VIEW */
+ testcase( i==131 ); /* WINDOW */
+ testcase( i==132 ); /* DO */
+ testcase( i==133 ); /* INITIALLY */
+ testcase( i==134 ); /* ALL */
+ testcase( i==135 ); /* PRIMARY */
*pType = aKWCode[i];
break;
}
@@ -141389,7 +151150,17 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
keywordCode((char*)z, n, &id);
return id;
}
-#define SQLITE_N_KEYWORD 124
+#define SQLITE_N_KEYWORD 136
+SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
+ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;
+ *pzName = zKWText + aKWOffset[i];
+ *pnName = aKWLen[i];
+ return SQLITE_OK;
+}
+SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; }
+SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){
+ return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
+}
/************** End of keywordhash.h *****************************************/
/************** Continuing where we left off in tokenize.c *******************/
@@ -141433,11 +151204,85 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = {
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif
-/* Make the IdChar function accessible from ctime.c */
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+/* Make the IdChar function accessible from ctime.c and alter.c */
SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
-#endif
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Return the id of the next token in string (*pz). Before returning, set
+** (*pz) to point to the byte following the parsed token.
+*/
+static int getToken(const unsigned char **pz){
+ const unsigned char *z = *pz;
+ int t; /* Token type to return */
+ do {
+ z += sqlite3GetToken(z, &t);
+ }while( t==TK_SPACE );
+ if( t==TK_ID
+ || t==TK_STRING
+ || t==TK_JOIN_KW
+ || t==TK_WINDOW
+ || t==TK_OVER
+ || sqlite3ParserFallback(t)==TK_ID
+ ){
+ t = TK_ID;
+ }
+ *pz = z;
+ return t;
+}
+
+/*
+** The following three functions are called immediately after the tokenizer
+** reads the keywords WINDOW, OVER and FILTER, respectively, to determine
+** whether the token should be treated as a keyword or an SQL identifier.
+** This cannot be handled by the usual lemon %fallback method, due to
+** the ambiguity in some constructions. e.g.
+**
+** SELECT sum(x) OVER ...
+**
+** In the above, "OVER" might be a keyword, or it might be an alias for the
+** sum(x) expression. If a "%fallback ID OVER" directive were added to
+** grammar, then SQLite would always treat "OVER" as an alias, making it
+** impossible to call a window-function without a FILTER clause.
+**
+** WINDOW is treated as a keyword if:
+**
+** * the following token is an identifier, or a keyword that can fallback
+** to being an identifier, and
+** * the token after than one is TK_AS.
+**
+** OVER is a keyword if:
+**
+** * the previous token was TK_RP, and
+** * the next token is either TK_LP or an identifier.
+**
+** FILTER is a keyword if:
+**
+** * the previous token was TK_RP, and
+** * the next token is TK_LP.
+*/
+static int analyzeWindowKeyword(const unsigned char *z){
+ int t;
+ t = getToken(&z);
+ if( t!=TK_ID ) return TK_ID;
+ t = getToken(&z);
+ if( t!=TK_AS ) return TK_ID;
+ return TK_WINDOW;
+}
+static int analyzeOverKeyword(const unsigned char *z, int lastToken){
+ if( lastToken==TK_RP ){
+ int t = getToken(&z);
+ if( t==TK_LP || t==TK_ID ) return TK_OVER;
+ }
+ return TK_ID;
+}
+static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
+ if( lastToken==TK_RP && getToken(&z)==TK_LP ){
+ return TK_FILTER;
+ }
+ return TK_ID;
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** Return the length (in bytes) of the token that begins at z[0].
@@ -141706,6 +151551,10 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
i = 1;
break;
}
+ case CC_NUL: {
+ *tokenType = TK_ILLEGAL;
+ return 0;
+ }
default: {
*tokenType = TK_ILLEGAL;
return 1;
@@ -141746,9 +151595,9 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
/* sqlite3ParserTrace(stdout, "parser: "); */
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
pEngine = &sEngine;
- sqlite3ParserInit(pEngine);
+ sqlite3ParserInit(pEngine, pParse);
#else
- pEngine = sqlite3ParserAlloc(sqlite3Malloc);
+ pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse);
if( pEngine==0 ){
sqlite3OomFault(db);
return SQLITE_NOMEM_BKPT;
@@ -141759,47 +151608,64 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pParse->nVar==0 );
assert( pParse->pVList==0 );
while( 1 ){
- if( zSql[0]!=0 ){
- n = sqlite3GetToken((u8*)zSql, &tokenType);
- mxSqlLen -= n;
- if( mxSqlLen<0 ){
- pParse->rc = SQLITE_TOOBIG;
- break;
- }
- }else{
- /* Upon reaching the end of input, call the parser two more times
- ** with tokens TK_SEMI and 0, in that order. */
- if( lastTokenParsed==TK_SEMI ){
- tokenType = 0;
- }else if( lastTokenParsed==0 ){
- break;
- }else{
- tokenType = TK_SEMI;
- }
- zSql -= n;
+ n = sqlite3GetToken((u8*)zSql, &tokenType);
+ mxSqlLen -= n;
+ if( mxSqlLen<0 ){
+ pParse->rc = SQLITE_TOOBIG;
+ break;
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( tokenType>=TK_WINDOW ){
+ assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
+ || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW
+ );
+#else
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
+#endif /* SQLITE_OMIT_WINDOWFUNC */
if( db->u1.isInterrupted ){
pParse->rc = SQLITE_INTERRUPT;
break;
}
- if( tokenType==TK_ILLEGAL ){
+ if( tokenType==TK_SPACE ){
+ zSql += n;
+ continue;
+ }
+ if( zSql[0]==0 ){
+ /* Upon reaching the end of input, call the parser two more times
+ ** with tokens TK_SEMI and 0, in that order. */
+ if( lastTokenParsed==TK_SEMI ){
+ tokenType = 0;
+ }else if( lastTokenParsed==0 ){
+ break;
+ }else{
+ tokenType = TK_SEMI;
+ }
+ n = 0;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ }else if( tokenType==TK_WINDOW ){
+ assert( n==6 );
+ tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
+ }else if( tokenType==TK_OVER ){
+ assert( n==4 );
+ tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
+ }else if( tokenType==TK_FILTER ){
+ assert( n==6 );
+ tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+ }else{
sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
break;
}
- zSql += n;
- }else{
- pParse->sLastToken.z = zSql;
- pParse->sLastToken.n = n;
- sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
- lastTokenParsed = tokenType;
- zSql += n;
- if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
+ pParse->sLastToken.z = zSql;
+ pParse->sLastToken.n = n;
+ sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
+ lastTokenParsed = tokenType;
+ zSql += n;
+ if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
assert( nErr==0 );
- pParse->zTail = zSql;
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
@@ -141821,10 +151687,12 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){
*pzErrMsg = pParse->zErrMsg;
- sqlite3_log(pParse->rc, "%s", *pzErrMsg);
+ sqlite3_log(pParse->rc, "%s in \"%s\"",
+ *pzErrMsg, pParse->zTail);
pParse->zErrMsg = 0;
nErr++;
}
+ pParse->zTail = zSql;
if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
sqlite3VdbeDelete(pParse->pVdbe);
pParse->pVdbe = 0;
@@ -141840,16 +151708,18 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
sqlite3_free(pParse->apVtabLock);
#endif
- if( !IN_DECLARE_VTAB ){
+ if( !IN_SPECIAL_PARSE ){
/* If the pParse->declareVtab flag is set, do not delete any table
** structure built up in pParse->pNewTable. The calling code (see vtab.c)
** will take responsibility for freeing the Table structure.
*/
sqlite3DeleteTable(db, pParse->pNewTable);
}
+ if( !IN_RENAME_OBJECT ){
+ sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+ }
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
- sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->pVList);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
@@ -142231,6 +152101,10 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
*/
/* #include "sqlite3.h" */
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+# undef SQLITE_ENABLE_RTREE
+#endif
+
#if 0
extern "C" {
#endif /* __cplusplus */
@@ -142244,7 +152118,7 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
/************** End of rtree.h ***********************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
-#ifdef SQLITE_ENABLE_ICU
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/************** Include sqliteicu.h in the middle of main.c ******************/
/************** Begin file sqliteicu.h ***************************************/
/*
@@ -142492,6 +152366,11 @@ SQLITE_API int sqlite3_initialize(void){
sqlite3GlobalConfig.isPCacheInit = 1;
rc = sqlite3OsInit();
}
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ if( rc==SQLITE_OK ){
+ rc = sqlite3MemdbInit();
+ }
+#endif
if( rc==SQLITE_OK ){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
@@ -142524,7 +152403,7 @@ SQLITE_API int sqlite3_initialize(void){
#ifndef NDEBUG
#ifndef SQLITE_OMIT_FLOATING_POINT
/* This section of code's only "output" is via assert() statements. */
- if ( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK ){
u64 x = (((u64)1)<<63)-1;
double y;
assert(sizeof(x)==8);
@@ -142890,6 +152769,17 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
+#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ case SQLITE_CONFIG_SORTERREF_SIZE: {
+ int iVal = va_arg(ap, int);
+ if( iVal<0 ){
+ iVal = SQLITE_DEFAULT_SORTERREF_SIZE;
+ }
+ sqlite3GlobalConfig.szSorterRef = (u32)iVal;
+ break;
+ }
+#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
+
default: {
rc = SQLITE_ERROR;
break;
@@ -143070,6 +152960,8 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
+ { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
+ { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -143084,7 +152976,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
db->flags &= ~aFlagOp[i].mask;
}
if( oldFlags!=db->flags ){
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
}
if( pRes ){
*pRes = (db->flags & aFlagOp[i].mask)!=0;
@@ -143146,6 +153038,15 @@ static int binCollFunc(
}
/*
+** Return true if CollSeq is the default built-in BINARY.
+*/
+SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){
+ assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
+ || strcmp(p->zName,"BINARY")==0 );
+ return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
+}
+
+/*
** Another built-in collating sequence: NOCASE.
**
** This collating sequence is intended to be used for "case independent
@@ -143268,7 +153169,7 @@ static void disconnectAllVtab(sqlite3 *db){
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
- if( db->aDb[i].pSchema ){
+ if( pSchema ){
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
Table *pTab = (Table *)sqliteHashData(p);
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
@@ -143528,8 +153429,8 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
- if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){
- sqlite3ExpirePreparedStatements(db);
+ if( schemaChange ){
+ sqlite3ExpirePreparedStatements(db, 0);
sqlite3ResetAllSchemasOfConnection(db);
}
sqlite3BtreeLeaveAll(db);
@@ -143557,6 +153458,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
switch( rc ){
case SQLITE_OK: zName = "SQLITE_OK"; break;
case SQLITE_ERROR: zName = "SQLITE_ERROR"; break;
+ case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break;
case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break;
case SQLITE_PERM: zName = "SQLITE_PERM"; break;
case SQLITE_ABORT: zName = "SQLITE_ABORT"; break;
@@ -143569,9 +153471,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
- case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
+ case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
+ case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
@@ -143691,6 +153594,8 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
/* SQLITE_FORMAT */ 0,
/* SQLITE_RANGE */ "column index out of range",
/* SQLITE_NOTADB */ "file is not a database",
+ /* SQLITE_NOTICE */ "notification message",
+ /* SQLITE_WARNING */ "warning message",
};
const char *zErr = "unknown error";
switch( rc ){
@@ -143698,6 +153603,14 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
zErr = "abort due to ROLLBACK";
break;
}
+ case SQLITE_ROW: {
+ zErr = "another row available";
+ break;
+ }
+ case SQLITE_DONE: {
+ zErr = "no more rows available";
+ break;
+ }
default: {
rc &= 0xff;
if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
@@ -143714,21 +153627,40 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
** again until a timeout value is reached. The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
+**
+** Return non-zero to retry the lock. Return zero to stop trying
+** and cause SQLite to return SQLITE_BUSY.
*/
static int sqliteDefaultBusyCallback(
- void *ptr, /* Database connection */
- int count /* Number of times table has been busy */
+ void *ptr, /* Database connection */
+ int count, /* Number of times table has been busy */
+ sqlite3_file *pFile /* The file on which the lock occurred */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
+ /* This case is for systems that have support for sleeping for fractions of
+ ** a second. Examples: All windows systems, unix systems with usleep() */
static const u8 delays[] =
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
static const u8 totals[] =
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY ArraySize(delays)
sqlite3 *db = (sqlite3 *)ptr;
- int timeout = db->busyTimeout;
+ int tmout = db->busyTimeout;
int delay, prior;
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
+ if( count ){
+ tmout = 0;
+ sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
+ return 0;
+ }else{
+ return 1;
+ }
+ }
+#else
+ UNUSED_PARAMETER(pFile);
+#endif
assert( count>=0 );
if( count < NDELAY ){
delay = delays[count];
@@ -143737,16 +153669,19 @@ static int sqliteDefaultBusyCallback(
delay = delays[NDELAY-1];
prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
}
- if( prior + delay > timeout ){
- delay = timeout - prior;
+ if( prior + delay > tmout ){
+ delay = tmout - prior;
if( delay<=0 ) return 0;
}
sqlite3OsSleep(db->pVfs, delay*1000);
return 1;
#else
+ /* This case for unix systems that lack usleep() support. Sleeping
+ ** must be done in increments of whole seconds */
sqlite3 *db = (sqlite3 *)ptr;
- int timeout = ((sqlite3 *)ptr)->busyTimeout;
- if( (count+1)*1000 > timeout ){
+ int tmout = ((sqlite3 *)ptr)->busyTimeout;
+ UNUSED_PARAMETER(pFile);
+ if( (count+1)*1000 > tmout ){
return 0;
}
sqlite3OsSleep(db->pVfs, 1000000);
@@ -143757,14 +153692,25 @@ static int sqliteDefaultBusyCallback(
/*
** Invoke the given busy handler.
**
-** This routine is called when an operation failed with a lock.
+** This routine is called when an operation failed to acquire a
+** lock on VFS file pFile.
+**
** If this routine returns non-zero, the lock is retried. If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
int rc;
- if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
- rc = p->xFunc(p->pArg, p->nBusy);
+ if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
+ if( p->bExtraFileArg ){
+ /* Add an extra parameter with the pFile pointer to the end of the
+ ** callback argument list */
+ int (*xTra)(void*,int,sqlite3_file*);
+ xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
+ rc = xTra(p->pBusyArg, p->nBusy, pFile);
+ }else{
+ /* Legacy style busy handler callback */
+ rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
+ }
if( rc==0 ){
p->nBusy = -1;
}else{
@@ -143786,9 +153732,10 @@ SQLITE_API int sqlite3_busy_handler(
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
- db->busyHandler.xFunc = xBusy;
- db->busyHandler.pArg = pArg;
+ db->busyHandler.xBusyHandler = xBusy;
+ db->busyHandler.pBusyArg = pArg;
db->busyHandler.nBusy = 0;
+ db->busyHandler.bExtraFileArg = 0;
db->busyTimeout = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
@@ -143836,8 +153783,10 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){
- sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
+ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
+ (void*)db);
db->busyTimeout = ms;
+ db->busyHandler.bExtraFileArg = 1;
}else{
sqlite3_busy_handler(db, 0, 0);
}
@@ -143873,6 +153822,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
void (*xStep)(sqlite3_context*,int,sqlite3_value **),
void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
FuncDestructor *pDestructor
){
FuncDef *p;
@@ -143880,12 +153831,14 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
int extraFlags;
assert( sqlite3_mutex_held(db->mutex) );
- if( zFunctionName==0 ||
- (xSFunc && (xFinal || xStep)) ||
- (!xSFunc && (xFinal && !xStep)) ||
- (!xSFunc && (!xFinal && xStep)) ||
- (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
- (255<(nName = sqlite3Strlen30( zFunctionName))) ){
+ assert( xValue==0 || xSFunc==0 );
+ if( zFunctionName==0 /* Must have a valid name */
+ || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */
+ || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */
+ || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */
+ || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
+ || (255<(nName = sqlite3Strlen30( zFunctionName)))
+ ){
return SQLITE_MISUSE_BKPT;
}
@@ -143906,10 +153859,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
}else if( enc==SQLITE_ANY ){
int rc;
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
- pUserData, xSFunc, xStep, xFinal, pDestructor);
+ pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
if( rc==SQLITE_OK ){
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
- pUserData, xSFunc, xStep, xFinal, pDestructor);
+ pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
}
if( rc!=SQLITE_OK ){
return rc;
@@ -143926,14 +153879,14 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
- if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
+ if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
return SQLITE_BUSY;
}else{
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
}
}
@@ -143955,39 +153908,32 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xSFunc = xSFunc ? xSFunc : xStep;
p->xFinalize = xFinal;
+ p->xValue = xValue;
+ p->xInverse = xInverse;
p->pUserData = pUserData;
p->nArg = (u16)nArg;
return SQLITE_OK;
}
/*
-** Create new user functions.
+** Worker function used by utf-8 APIs that create new functions:
+**
+** sqlite3_create_function()
+** sqlite3_create_function_v2()
+** sqlite3_create_window_function()
*/
-#undef sqlite3_create_function
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunc,
- int nArg,
- int enc,
- void *p,
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*)
-){
- return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
- xFinal, 0);
-}
-
-SQLITE_API int sqlite3_create_function_v2(
+static int createFunctionApi(
sqlite3 *db,
const char *zFunc,
int nArg,
int enc,
void *p,
- void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
- void (*xDestroy)(void *)
+ void (*xValue)(sqlite3_context*),
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
+ void(*xDestroy)(void*)
){
int rc = SQLITE_ERROR;
FuncDestructor *pArg = 0;
@@ -143999,19 +153945,23 @@ SQLITE_API int sqlite3_create_function_v2(
#endif
sqlite3_mutex_enter(db->mutex);
if( xDestroy ){
- pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
+ pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor));
if( !pArg ){
+ sqlite3OomFault(db);
xDestroy(p);
goto out;
}
+ pArg->nRef = 0;
pArg->xDestroy = xDestroy;
pArg->pUserData = p;
}
- rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
+ rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p,
+ xSFunc, xStep, xFinal, xValue, xInverse, pArg
+ );
if( pArg && pArg->nRef==0 ){
assert( rc!=SQLITE_OK );
xDestroy(p);
- sqlite3DbFree(db, pArg);
+ sqlite3_free(pArg);
}
out:
@@ -144020,6 +153970,53 @@ SQLITE_API int sqlite3_create_function_v2(
return rc;
}
+/*
+** Create new user functions.
+*/
+#undef sqlite3_create_function
+SQLITE_API int sqlite3_create_function(
+ sqlite3 *db,
+ const char *zFunc,
+ int nArg,
+ int enc,
+ void *p,
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xFinal)(sqlite3_context*)
+){
+ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
+ xFinal, 0, 0, 0);
+}
+SQLITE_API int sqlite3_create_function_v2(
+ sqlite3 *db,
+ const char *zFunc,
+ int nArg,
+ int enc,
+ void *p,
+ void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+ void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xFinal)(sqlite3_context*),
+ void (*xDestroy)(void *)
+){
+ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
+ xFinal, 0, 0, xDestroy);
+}
+SQLITE_API int sqlite3_create_window_function(
+ sqlite3 *db,
+ const char *zFunc,
+ int nArg,
+ int enc,
+ void *p,
+ void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+ void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
+ void (*xDestroy)(void *)
+){
+ return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep,
+ xFinal, xValue, xInverse, xDestroy);
+}
+
#ifndef SQLITE_OMIT_UTF16
SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
@@ -144040,7 +154037,7 @@ SQLITE_API int sqlite3_create_function16(
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
- rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
+ rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0);
sqlite3DbFree(db, zFunc8);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -144050,6 +154047,28 @@ SQLITE_API int sqlite3_create_function16(
/*
+** The following is the implementation of an SQL function that always
+** fails with an error message stating that the function is used in the
+** wrong context. The sqlite3_overload_function() API might construct
+** SQL function that use this routine so that the functions will exist
+** for name resolution but are actually overloaded by the xFindFunction
+** method of virtual tables.
+*/
+static void sqlite3InvalidFunction(
+ sqlite3_context *context, /* The function calling context */
+ int NotUsed, /* Number of arguments to the function */
+ sqlite3_value **NotUsed2 /* Value of each argument */
+){
+ const char *zName = (const char*)sqlite3_user_data(context);
+ char *zErr;
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ zErr = sqlite3_mprintf(
+ "unable to use function %s in the requested context", zName);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
+}
+
+/*
** Declare that a function has been overloaded by a virtual table.
**
** If the function already exists as a regular global function, then
@@ -144066,7 +154085,8 @@ SQLITE_API int sqlite3_overload_function(
const char *zName,
int nArg
){
- int rc = SQLITE_OK;
+ int rc;
+ char *zCopy;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
@@ -144074,13 +154094,13 @@ SQLITE_API int sqlite3_overload_function(
}
#endif
sqlite3_mutex_enter(db->mutex);
- if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
- rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
- 0, sqlite3InvalidFunction, 0, 0, 0);
- }
- rc = sqlite3ApiExit(db, rc);
+ rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
sqlite3_mutex_leave(db->mutex);
- return rc;
+ if( rc ) return SQLITE_OK;
+ zCopy = sqlite3_mprintf(zName);
+ if( zCopy==0 ) return SQLITE_NOMEM;
+ return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
+ zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
}
#ifndef SQLITE_OMIT_TRACE
@@ -144643,7 +154663,7 @@ static int createCollation(
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
- sqlite3ExpirePreparedStatements(db);
+ sqlite3ExpirePreparedStatements(db, 0);
/* If collation sequence pColl was created directly by a call to
** sqlite3_create_collation, and not generated by synthCollSeq(),
@@ -145079,6 +155099,7 @@ static int openDatabase(
}else{
isThreadsafe = sqlite3GlobalConfig.bFullMutex;
}
+
if( flags & SQLITE_OPEN_PRIVATECACHE ){
flags &= ~SQLITE_OPEN_SHAREDCACHE;
}else if( sqlite3GlobalConfig.sharedCacheEnabled ){
@@ -145111,19 +155132,27 @@ static int openDatabase(
/* Allocate the sqlite data structure */
db = sqlite3MallocZero( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
- if( isThreadsafe ){
+ if( isThreadsafe
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ || sqlite3GlobalConfig.bCoreMutex
+#endif
+ ){
db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( db->mutex==0 ){
sqlite3_free(db);
db = 0;
goto opendb_out;
}
+ if( isThreadsafe==0 ){
+ sqlite3MutexWarnOnContention(db->mutex);
+ }
}
sqlite3_mutex_enter(db->mutex);
db->errMask = 0xff;
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
+ db->lookaside.bDisable = 1;
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
@@ -145296,7 +155325,7 @@ static int openDatabase(
}
#endif
-#ifdef SQLITE_ENABLE_ICU
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
}
@@ -145599,37 +155628,37 @@ SQLITE_API int 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){
+SQLITE_PRIVATE int sqlite3ReportError(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 );
- return reportError(SQLITE_CORRUPT, lineno, "database corruption");
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption");
}
SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_MISUSE, lineno, "misuse");
+ return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
}
SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
+ return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
char zMsg[100];
sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_CORRUPT, lineno, zMsg);
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
}
SQLITE_PRIVATE int sqlite3NomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_NOMEM, lineno, "OOM");
+ return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
}
SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+ return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
}
#endif
@@ -145822,10 +155851,11 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
}else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
*(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
rc = SQLITE_OK;
- }else if( fd->pMethods ){
- rc = sqlite3OsFileControl(fd, op, pArg);
+ }else if( op==SQLITE_FCNTL_DATA_VERSION ){
+ *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
+ rc = SQLITE_OK;
}else{
- rc = SQLITE_NOTFOUND;
+ rc = sqlite3OsFileControl(fd, op, pArg);
}
sqlite3BtreeLeave(pBtree);
}
@@ -146046,24 +156076,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
-#ifdef SQLITE_N_KEYWORD
- /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
- **
- ** If zWord is a keyword recognized by the parser, then return the
- ** number of keywords. Or if zWord is not a keyword, return 0.
- **
- ** This test feature is only available in the amalgamation since
- ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
- ** is built using separate source files.
- */
- case SQLITE_TESTCTRL_ISKEYWORD: {
- const char *zWord = va_arg(ap, const char*);
- int n = sqlite3Strlen30(zWord);
- rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
- break;
- }
-#endif
-
#ifndef SQLITE_UNTESTABLE
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
**
@@ -146107,7 +156119,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_VDBE_COVERAGE: {
#ifdef SQLITE_VDBE_COVERAGE
- typedef void (*branch_callback)(void*,int,u8,u8);
+ typedef void (*branch_callback)(void*,unsigned int,
+ unsigned char,unsigned char);
sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
#endif
@@ -146159,6 +156172,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
sqlite3_mutex_leave(db->mutex);
break;
}
+
+#if defined(YYCOVERAGE)
+ /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out)
+ **
+ ** This test control (only available when SQLite is compiled with
+ ** -DYYCOVERAGE) writes a report onto "out" that shows all
+ ** state/lookahead combinations in the parser state machine
+ ** which are never exercised. If any state is missed, make the
+ ** return code SQLITE_ERROR.
+ */
+ case SQLITE_TESTCTRL_PARSER_COVERAGE: {
+ FILE *out = va_arg(ap, FILE*);
+ if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
+ break;
+ }
+#endif /* defined(YYCOVERAGE) */
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
@@ -146278,7 +156307,7 @@ SQLITE_API int sqlite3_snapshot_get(
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
}
@@ -146313,11 +156342,29 @@ SQLITE_API int sqlite3_snapshot_open(
iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
- if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
- rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
+ if( sqlite3BtreeIsInTrans(pBt)==0 ){
+ Pager *pPager = sqlite3BtreePager(pBt);
+ int bUnlock = 0;
+ if( sqlite3BtreeIsInReadTrans(pBt) ){
+ if( db->nVdbeActive==0 ){
+ rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
+ if( rc==SQLITE_OK ){
+ bUnlock = 1;
+ rc = sqlite3BtreeCommit(pBt);
+ }
+ }
+ }else{
+ rc = SQLITE_OK;
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot);
+ }
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
- sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+ sqlite3PagerSnapshotOpen(pPager, 0);
+ }
+ if( bUnlock ){
+ sqlite3PagerSnapshotUnlock(pPager);
}
}
}
@@ -146348,7 +156395,7 @@ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
+ rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
sqlite3BtreeCommit(pBt);
@@ -147916,7 +157963,7 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
);
SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
+SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
#endif
@@ -147942,11 +157989,10 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifndef SQLITE_DISABLE_FTS3_UNICODE
-static int sqlite3FtsUnicodeFold(int, int);
-static int sqlite3FtsUnicodeIsalnum(int);
-static int sqlite3FtsUnicodeIsdiacritic(int);
+SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
+SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
+SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
#endif
-#define sqlite3Fts5UnicodeIsalnum sqlite3FtsUnicodeIsalnum
#define sqlite3Fts5UnicodeIsdiacritic sqlite3FtsUnicodeIsdiacritic
#define sqlite3Fts5UnicodeFold sqlite3FtsUnicodeFold
@@ -149487,7 +159533,7 @@ static int fts3ScanInteriorNode(
const char *zCsr = zNode; /* Cursor to iterate through node */
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
char *zBuffer = 0; /* Buffer to load terms into */
- int nAlloc = 0; /* Size of allocated buffer */
+ i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
sqlite3_int64 iChild; /* Block id of child node to descend to */
@@ -149525,14 +159571,14 @@ static int fts3ScanInteriorNode(
zCsr += fts3GetVarint32(zCsr, &nSuffix);
assert( nPrefix>=0 && nSuffix>=0 );
- if( &zCsr[nSuffix]>zEnd ){
+ if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
- if( nPrefix+nSuffix>nAlloc ){
+ if( (i64)nPrefix+nSuffix>nAlloc ){
char *zNew;
- nAlloc = (nPrefix+nSuffix) * 2;
- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
+ nAlloc = ((i64)nPrefix+nSuffix) * 2;
+ zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
if( !zNew ){
rc = SQLITE_NOMEM;
goto finish_scan;
@@ -151474,7 +161520,7 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
int rc = SQLITE_OK;
UNUSED_PARAMETER(iSavepoint);
assert( ((Fts3Table *)pVtab)->inTransaction );
- assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint );
+ assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint );
TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint );
if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){
rc = fts3SyncMethod(pVtab);
@@ -151630,7 +161676,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
#ifdef SQLITE_TEST
if( rc==SQLITE_OK ){
- rc = sqlite3Fts3ExprInitTestInterface(db);
+ rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
}
#endif
@@ -155291,34 +165337,6 @@ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){
/* #include <stdio.h> */
/*
-** Function to query the hash-table of tokenizers (see README.tokenizers).
-*/
-static int queryTestTokenizer(
- sqlite3 *db,
- const char *zName,
- const sqlite3_tokenizer_module **pp
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?)";
-
- *pp = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
- memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-/*
** Return a pointer to a buffer containing a text representation of the
** expression passed as the first argument. The buffer is obtained from
** sqlite3_malloc(). It is the responsibility of the caller to use
@@ -155385,12 +165403,12 @@ static char *exprToString(Fts3Expr *pExpr, char *zBuf){
**
** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
*/
-static void fts3ExprTest(
+static void fts3ExprTestCommon(
+ int bRebalance,
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- sqlite3_tokenizer_module const *pModule = 0;
sqlite3_tokenizer *pTokenizer = 0;
int rc;
char **azCol = 0;
@@ -155400,7 +165418,9 @@ static void fts3ExprTest(
int ii;
Fts3Expr *pExpr;
char *zBuf = 0;
- sqlite3 *db = sqlite3_context_db_handle(context);
+ Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
+ const char *zTokenizer = 0;
+ char *zErr = 0;
if( argc<3 ){
sqlite3_result_error(context,
@@ -155409,23 +165429,17 @@ static void fts3ExprTest(
return;
}
- rc = queryTestTokenizer(db,
- (const char *)sqlite3_value_text(argv[0]), &pModule);
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }else if( !pModule ){
- sqlite3_result_error(context, "No such tokenizer module", -1);
- goto exprtest_out;
- }
-
- rc = pModule->xCreate(0, 0, &pTokenizer);
- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
+ zTokenizer = (const char*)sqlite3_value_text(argv[0]);
+ rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_NOMEM ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3_result_error(context, zErr, -1);
+ }
+ sqlite3_free(zErr);
+ return;
}
- pTokenizer->pModule = pModule;
zExpr = (const char *)sqlite3_value_text(argv[1]);
nExpr = sqlite3_value_bytes(argv[1]);
@@ -155439,7 +165453,7 @@ static void fts3ExprTest(
azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
}
- if( sqlite3_user_data(context) ){
+ if( bRebalance ){
char *zDummy = 0;
rc = sqlite3Fts3ExprParse(
pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
@@ -155465,23 +165479,38 @@ static void fts3ExprTest(
sqlite3Fts3ExprFree(pExpr);
exprtest_out:
- if( pModule && pTokenizer ){
- rc = pModule->xDestroy(pTokenizer);
+ if( pTokenizer ){
+ rc = pTokenizer->pModule->xDestroy(pTokenizer);
}
sqlite3_free(azCol);
}
+static void fts3ExprTest(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ fts3ExprTestCommon(0, context, argc, argv);
+}
+static void fts3ExprTestRebalance(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ fts3ExprTestCommon(1, context, argc, argv);
+}
+
/*
** Register the query expression parser test function fts3_exprtest()
** with database connection db.
*/
-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
+SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
int rc = sqlite3_create_function(
- db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
+ db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "fts3_exprtest_rebalance",
- -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
+ -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
);
}
return rc;
@@ -159132,15 +169161,19 @@ static int fts3SegReaderNext(
** safe (no risk of overread) even if the node data is corrupted. */
pNext += fts3GetVarint32(pNext, &nPrefix);
pNext += fts3GetVarint32(pNext, &nSuffix);
- if( nPrefix<0 || nSuffix<=0
- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
+ if( nSuffix<=0
+ || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
+ || nPrefix>pReader->nTermAlloc
){
return FTS_CORRUPT_VTAB;
}
- if( nPrefix+nSuffix>pReader->nTermAlloc ){
- int nNew = (nPrefix+nSuffix)*2;
- char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
+ /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
+ ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
+ ** overflow - hence the (i64) casts. */
+ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
+ i64 nNew = ((i64)nPrefix+nSuffix)*2;
+ char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -159162,7 +169195,7 @@ static int fts3SegReaderNext(
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
+ if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
@@ -159666,6 +169699,7 @@ static int fts3WriteSegment(
sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
+ sqlite3_bind_null(pStmt, 2);
}
return rc;
}
@@ -159722,6 +169756,7 @@ static int fts3WriteSegdir(
sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
+ sqlite3_bind_null(pStmt, 6);
}
return rc;
}
@@ -161201,6 +171236,7 @@ static void fts3UpdateDocTotals(
sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC);
sqlite3_step(pStmt);
*pRC = sqlite3_reset(pStmt);
+ sqlite3_bind_null(pStmt, 2);
sqlite3_free(a);
}
@@ -161485,6 +171521,9 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
+ return SQLITE_CORRUPT_VTAB;
+ }
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -161492,6 +171531,9 @@ static int nodeReaderNext(NodeReader *p){
p->iOff += nSuffix;
if( p->iChild==0 ){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
+ if( (p->nNode-p->iOff)<p->nDoclist ){
+ return SQLITE_CORRUPT_VTAB;
+ }
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
@@ -161499,7 +171541,6 @@ static int nodeReaderNext(NodeReader *p){
}
assert( p->iOff<=p->nNode );
-
return rc;
}
@@ -162389,6 +172430,7 @@ static int fts3TruncateSegment(
sqlite3_bind_int(pChomp, 4, iIdx);
sqlite3_step(pChomp);
rc = sqlite3_reset(pChomp);
+ sqlite3_bind_null(pChomp, 2);
}
}
@@ -162468,6 +172510,7 @@ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){
sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC);
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
+ sqlite3_bind_null(pReplace, 2);
}
return rc;
@@ -163282,7 +173325,6 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
){
Fts3Table *p = (Fts3Table *)pVtab;
int rc = SQLITE_OK; /* Return Code */
- int isRemove = 0; /* True for an UPDATE or DELETE */
u32 *aSzIns = 0; /* Sizes of inserted documents */
u32 *aSzDel = 0; /* Sizes of deleted documents */
int nChng = 0; /* Net change in number of documents */
@@ -163380,7 +173422,6 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
- isRemove = 1;
}
/* If this is an INSERT or UPDATE operation, insert the new record. */
@@ -163392,7 +173433,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
rc = FTS_CORRUPT_VTAB;
}
}
- if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
+ if( rc==SQLITE_OK ){
rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
}
if( rc==SQLITE_OK ){
@@ -165564,7 +175605,6 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
*/
#ifndef SQLITE_DISABLE_FTS3_UNICODE
-#if !defined(SQLITE_AMALGAMATION) || !defined(SQLITE_ENABLE_FTS5)
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
/* #include <assert.h> */
@@ -165576,7 +175616,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
** The results are undefined if the value passed to this function
** is less than zero.
*/
-static int sqlite3FtsUnicodeIsalnum(int c){
+SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
/* Each unsigned integer in the following array corresponds to a contiguous
** range of unicode codepoints that are not either letters or numbers (i.e.
** codepoints for which this function should return 0).
@@ -165597,56 +175637,56 @@ static int sqlite3FtsUnicodeIsalnum(int c){
0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15,
0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07,
0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B,
- 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09,
- 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
- 0x00235030, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
- 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02,
- 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802,
- 0x0027F401, 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02,
- 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403,
- 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802,
- 0x002BC002, 0x002BE806, 0x002C0403, 0x002CF001, 0x002CF807,
- 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
- 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
- 0x002FCC08, 0x00300004, 0x0030F807, 0x00311803, 0x00312804,
- 0x00315402, 0x00318802, 0x0031FC01, 0x00320403, 0x0032F001,
- 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
- 0x00340004, 0x0034EC02, 0x0034F807, 0x00351803, 0x00352804,
- 0x00353C01, 0x00355C01, 0x00358802, 0x0035E401, 0x00360802,
- 0x00372801, 0x00373C06, 0x00375801, 0x00376008, 0x0037C803,
- 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09, 0x00396802,
- 0x003AC401, 0x003AD006, 0x003AEC02, 0x003B2006, 0x003C041F,
- 0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424, 0x003EF80F,
- 0x003F380D, 0x0040AC14, 0x00412806, 0x00415804, 0x00417803,
- 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C, 0x00423C01,
- 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A, 0x00500001,
- 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03, 0x005C4803,
- 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023, 0x005F6004,
- 0x005F7401, 0x0060000F, 0x00621402, 0x0062A401, 0x0064800C,
- 0x0064C00C, 0x00650001, 0x00651002, 0x00677822, 0x00685C05,
- 0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007,
- 0x006AA006, 0x006AC00F, 0x006C0005, 0x006CD011, 0x006D6823,
- 0x006E0003, 0x006E840D, 0x006F980E, 0x006FF004, 0x00709014,
- 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019, 0x0073B401,
- 0x0073C803, 0x0073DC03, 0x0077003A, 0x0077EC05, 0x007EF401,
- 0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403, 0x007FF402,
- 0x00800065, 0x0081980A, 0x0081E805, 0x00822805, 0x00828020,
- 0x00834021, 0x00840002, 0x00840C04, 0x00842002, 0x00845001,
- 0x00845803, 0x00847806, 0x00849401, 0x00849C01, 0x0084A401,
- 0x0084B801, 0x0084E802, 0x00850005, 0x00852804, 0x00853C01,
- 0x00862802, 0x00864297, 0x0091000B, 0x0092704E, 0x00940276,
- 0x009E53E0, 0x00ADD820, 0x00AE6022, 0x00AEF40C, 0x00AF2809,
- 0x00AFB004, 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802,
- 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C01A, 0x00BA001A,
- 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019,
- 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001,
- 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F,
- 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F,
- 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802, 0x02983403,
- 0x0299BC10, 0x029A7802, 0x029BC008, 0x029C0017, 0x029C8002,
- 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09,
- 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D012, 0x02A33802,
- 0x02A38012, 0x02A3E003, 0x02A3F001, 0x02A4980A, 0x02A51C0D,
+ 0x001E980B, 0x001FAC09, 0x001FD804, 0x001FF403, 0x00205804,
+ 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
+ 0x00217801, 0x00234C31, 0x0024E803, 0x0024F812, 0x00254407,
+ 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807,
+ 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802,
+ 0x0027E802, 0x0027F402, 0x00280403, 0x0028F001, 0x0028F805,
+ 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D402,
+ 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
+ 0x002B8802, 0x002BC002, 0x002BE806, 0x002C0403, 0x002CF001,
+ 0x002CF807, 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802,
+ 0x002DC001, 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804,
+ 0x002F5C01, 0x002FCC08, 0x00300005, 0x0030F807, 0x00311803,
+ 0x00312804, 0x00315402, 0x00318802, 0x0031FC01, 0x00320404,
+ 0x0032F001, 0x0032F807, 0x00331803, 0x00332804, 0x00335402,
+ 0x00338802, 0x00340004, 0x0034EC02, 0x0034F807, 0x00351803,
+ 0x00352804, 0x00353C01, 0x00355C01, 0x00358802, 0x0035E401,
+ 0x00360802, 0x00372801, 0x00373C06, 0x00375801, 0x00376008,
+ 0x0037C803, 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09,
+ 0x00396802, 0x003AC401, 0x003AD006, 0x003AEC02, 0x003B2006,
+ 0x003C041F, 0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424,
+ 0x003EF80F, 0x003F380D, 0x0040AC14, 0x00412806, 0x00415804,
+ 0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C,
+ 0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A,
+ 0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03,
+ 0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023,
+ 0x005F6004, 0x005F7401, 0x0060000F, 0x00621402, 0x0062A401,
+ 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, 0x00677822,
+ 0x00685C05, 0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01,
+ 0x006A8007, 0x006AA006, 0x006AC00F, 0x006C0005, 0x006CD011,
+ 0x006D6823, 0x006E0003, 0x006E840D, 0x006F980E, 0x006FF004,
+ 0x00709014, 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019,
+ 0x0073B401, 0x0073C803, 0x0073DC03, 0x0077003A, 0x0077EC05,
+ 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403,
+ 0x007FF402, 0x00800065, 0x0081980A, 0x0081E805, 0x00822805,
+ 0x00828020, 0x00834021, 0x00840002, 0x00840C04, 0x00842002,
+ 0x00845001, 0x00845803, 0x00847806, 0x00849401, 0x00849C01,
+ 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, 0x00852804,
+ 0x00853C01, 0x00862802, 0x00864297, 0x0091000B, 0x0092704E,
+ 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6031, 0x00AF2835,
+ 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
+ 0x00B5FC01, 0x00B7804F, 0x00B8C01F, 0x00BA001A, 0x00BA6C59,
+ 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
+ 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
+ 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
+ 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
+ 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
+ 0x029A7802, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
+ 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
+ 0x02A1D004, 0x02A20002, 0x02A2D012, 0x02A33802, 0x02A38012,
+ 0x02A3E003, 0x02A3F001, 0x02A3FC01, 0x02A4980A, 0x02A51C0D,
0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401,
0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03,
0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802,
@@ -165661,31 +175701,34 @@ static int sqlite3FtsUnicodeIsalnum(int c){
0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403, 0x04281402,
0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, 0x0429FC01,
0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407, 0x042E6404,
- 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012, 0x04440003,
- 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003, 0x0446CC0E,
+ 0x04349004, 0x043D180B, 0x043D5405, 0x04400003, 0x0440E016,
+ 0x0441FC04, 0x0442C012, 0x04433401, 0x04440003, 0x04449C0E,
+ 0x04450004, 0x04451402, 0x0445CC03, 0x04460003, 0x0446CC0E,
0x04471409, 0x04476C01, 0x04477403, 0x0448B013, 0x044AA401,
- 0x044B7C0C, 0x044C0004, 0x044CF001, 0x044CF807, 0x044D1C02,
+ 0x044B7C0C, 0x044C0004, 0x044CEC02, 0x044CF807, 0x044D1C02,
0x044D2C03, 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005,
- 0x0450D412, 0x04512C05, 0x04516C01, 0x04517401, 0x0452C014,
+ 0x0450D412, 0x04512C05, 0x04516C01, 0x04517402, 0x0452C014,
0x04531801, 0x0456BC07, 0x0456E020, 0x04577002, 0x0458C014,
- 0x0459800D, 0x045AAC0D, 0x045C740F, 0x045CF004, 0x0468040A,
- 0x0468CC07, 0x0468EC0D, 0x0469440B, 0x046A2813, 0x046A7805,
- 0x0470BC08, 0x0470E008, 0x04710405, 0x0471C002, 0x04724816,
- 0x0472A40E, 0x0474C406, 0x0474E801, 0x0474F002, 0x0474FC07,
- 0x04751C01, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
- 0x05AD1002, 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6,
- 0x07440027, 0x0744A4C0, 0x07480046, 0x074C0057, 0x075B0401,
- 0x075B6C01, 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01,
- 0x075DBC01, 0x075E2401, 0x075EA401, 0x075F0C01, 0x0760028C,
- 0x076A6C05, 0x076A840F, 0x07800007, 0x07802011, 0x07806C07,
- 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007, 0x07A57802,
- 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F,
- 0x07C3040F, 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C03D,
- 0x07C7981D, 0x07C8402C, 0x07C90009, 0x07C94002, 0x07C98006,
- 0x07CC03D5, 0x07DB800D, 0x07DBC009, 0x07DC0074, 0x07DE0055,
- 0x07E0000C, 0x07E04038, 0x07E1400A, 0x07E18028, 0x07E2401E,
- 0x07E4000C, 0x07E4402F, 0x07E5000D, 0x07E5401C, 0x07E60018,
- 0x07E70001, 0x07E74017, 0x38000401, 0x38008060, 0x380400F0,
+ 0x0459800D, 0x045AAC0D, 0x045C740F, 0x045CF004, 0x0460B010,
+ 0x0468040A, 0x0468CC07, 0x0468EC0D, 0x0469440B, 0x046A2813,
+ 0x046A7805, 0x0470BC08, 0x0470E008, 0x04710405, 0x0471C002,
+ 0x04724816, 0x0472A40E, 0x0474C406, 0x0474E801, 0x0474F002,
+ 0x0474FC07, 0x04751C01, 0x04762805, 0x04764002, 0x04764C05,
+ 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
+ 0x05AD1002, 0x05BA5C04, 0x05BD442E, 0x05BE3C04, 0x06F27008,
+ 0x074000F6, 0x07440027, 0x0744A4C0, 0x07480046, 0x074C0057,
+ 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, 0x075CD401,
+ 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, 0x075F0C01,
+ 0x0760028C, 0x076A6C05, 0x076A840F, 0x07800007, 0x07802011,
+ 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
+ 0x07A57802, 0x07B2B001, 0x07B2C001, 0x07BBC002, 0x07C0002C,
+ 0x07C0C064, 0x07C2800F, 0x07C2C40F, 0x07C3040F, 0x07C34425,
+ 0x07C4405C, 0x07C5C03D, 0x07C7981D, 0x07C8402C, 0x07C90009,
+ 0x07C94002, 0x07C98006, 0x07CC03D5, 0x07DB800D, 0x07DBC00A,
+ 0x07DC0074, 0x07DE0059, 0x07E0000C, 0x07E04038, 0x07E1400A,
+ 0x07E18028, 0x07E2401E, 0x07E4000C, 0x07E4402F, 0x07E50031,
+ 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
+ 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060, 0x380400F0,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
@@ -165714,7 +175757,7 @@ static int sqlite3FtsUnicodeIsalnum(int c){
return 1;
}
-
+#if !defined(SQLITE_AMALGAMATION) || !defined(SQLITE_ENABLE_FTS5)
/*
** If the argument is a codepoint corresponding to a lowercase letter
** in the ASCII range with a diacritic added, return the codepoint
@@ -165773,7 +175816,7 @@ static int remove_diacritic(int c){
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
-static int sqlite3FtsUnicodeIsdiacritic(int c){
+SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask0 = 0x08029FDF;
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
@@ -165792,7 +175835,7 @@ static int sqlite3FtsUnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
-static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
+SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -165817,8 +175860,8 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
} aEntry[] = {
{65, 14, 26}, {181, 66, 1}, {192, 14, 23},
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
- {313, 1, 16}, {330, 1, 46}, {376, 150, 1},
- {377, 1, 6}, {383, 138, 1}, {385, 52, 1},
+ {313, 1, 16}, {330, 1, 46}, {376, 152, 1},
+ {377, 1, 6}, {383, 140, 1}, {385, 52, 1},
{386, 1, 4}, {390, 46, 1}, {391, 0, 1},
{393, 44, 2}, {395, 0, 1}, {398, 34, 1},
{399, 40, 1}, {400, 42, 1}, {401, 0, 1},
@@ -165831,51 +175874,52 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
- {497, 2, 1}, {498, 1, 4}, {502, 156, 1},
- {503, 168, 1}, {504, 1, 40}, {544, 144, 1},
+ {497, 2, 1}, {498, 1, 4}, {502, 158, 1},
+ {503, 170, 1}, {504, 1, 40}, {544, 146, 1},
{546, 1, 18}, {570, 74, 1}, {571, 0, 1},
- {573, 142, 1}, {574, 72, 1}, {577, 0, 1},
- {579, 140, 1}, {580, 30, 1}, {581, 32, 1},
+ {573, 144, 1}, {574, 72, 1}, {577, 0, 1},
+ {579, 142, 1}, {580, 30, 1}, {581, 32, 1},
{582, 1, 10}, {837, 38, 1}, {880, 1, 4},
{886, 0, 1}, {895, 38, 1}, {902, 20, 1},
{904, 18, 3}, {908, 28, 1}, {910, 26, 2},
{913, 14, 17}, {931, 14, 9}, {962, 0, 1},
- {975, 4, 1}, {976, 174, 1}, {977, 176, 1},
- {981, 180, 1}, {982, 178, 1}, {984, 1, 24},
- {1008, 170, 1}, {1009, 172, 1}, {1012, 164, 1},
- {1013, 162, 1}, {1015, 0, 1}, {1017, 186, 1},
- {1018, 0, 1}, {1021, 144, 3}, {1024, 36, 16},
+ {975, 4, 1}, {976, 176, 1}, {977, 178, 1},
+ {981, 182, 1}, {982, 180, 1}, {984, 1, 24},
+ {1008, 172, 1}, {1009, 174, 1}, {1012, 166, 1},
+ {1013, 164, 1}, {1015, 0, 1}, {1017, 188, 1},
+ {1018, 0, 1}, {1021, 146, 3}, {1024, 36, 16},
{1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54},
{1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
{1329, 24, 38}, {4256, 70, 38}, {4295, 70, 1},
- {4301, 70, 1}, {5112, 184, 6}, {7296, 122, 1},
+ {4301, 70, 1}, {5112, 186, 6}, {7296, 122, 1},
{7297, 124, 1}, {7298, 126, 1}, {7299, 130, 2},
{7301, 128, 1}, {7302, 132, 1}, {7303, 134, 1},
- {7304, 96, 1}, {7680, 1, 150}, {7835, 166, 1},
- {7838, 116, 1}, {7840, 1, 96}, {7944, 184, 8},
- {7960, 184, 6}, {7976, 184, 8}, {7992, 184, 8},
- {8008, 184, 6}, {8025, 185, 8}, {8040, 184, 8},
- {8072, 184, 8}, {8088, 184, 8}, {8104, 184, 8},
- {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
- {8126, 120, 1}, {8136, 158, 4}, {8140, 182, 1},
- {8152, 184, 2}, {8154, 154, 2}, {8168, 184, 2},
- {8170, 152, 2}, {8172, 186, 1}, {8184, 146, 2},
- {8186, 148, 2}, {8188, 182, 1}, {8486, 118, 1},
- {8490, 112, 1}, {8491, 114, 1}, {8498, 12, 1},
- {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26},
- {11264, 24, 47}, {11360, 0, 1}, {11362, 108, 1},
- {11363, 136, 1}, {11364, 110, 1}, {11367, 1, 6},
- {11373, 104, 1}, {11374, 106, 1}, {11375, 100, 1},
- {11376, 102, 1}, {11378, 0, 1}, {11381, 0, 1},
- {11390, 98, 2}, {11392, 1, 100}, {11499, 1, 4},
- {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28},
- {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4},
- {42877, 94, 1}, {42878, 1, 10}, {42891, 0, 1},
- {42893, 86, 1}, {42896, 1, 4}, {42902, 1, 20},
- {42922, 80, 1}, {42923, 76, 1}, {42924, 78, 1},
- {42925, 82, 1}, {42926, 80, 1}, {42928, 90, 1},
- {42929, 84, 1}, {42930, 88, 1}, {42931, 68, 1},
- {42932, 1, 4}, {43888, 92, 80}, {65313, 14, 26},
+ {7304, 96, 1}, {7312, 138, 43}, {7357, 138, 3},
+ {7680, 1, 150}, {7835, 168, 1}, {7838, 116, 1},
+ {7840, 1, 96}, {7944, 186, 8}, {7960, 186, 6},
+ {7976, 186, 8}, {7992, 186, 8}, {8008, 186, 6},
+ {8025, 187, 8}, {8040, 186, 8}, {8072, 186, 8},
+ {8088, 186, 8}, {8104, 186, 8}, {8120, 186, 2},
+ {8122, 162, 2}, {8124, 184, 1}, {8126, 120, 1},
+ {8136, 160, 4}, {8140, 184, 1}, {8152, 186, 2},
+ {8154, 156, 2}, {8168, 186, 2}, {8170, 154, 2},
+ {8172, 188, 1}, {8184, 148, 2}, {8186, 150, 2},
+ {8188, 184, 1}, {8486, 118, 1}, {8490, 112, 1},
+ {8491, 114, 1}, {8498, 12, 1}, {8544, 8, 16},
+ {8579, 0, 1}, {9398, 10, 26}, {11264, 24, 47},
+ {11360, 0, 1}, {11362, 108, 1}, {11363, 136, 1},
+ {11364, 110, 1}, {11367, 1, 6}, {11373, 104, 1},
+ {11374, 106, 1}, {11375, 100, 1}, {11376, 102, 1},
+ {11378, 0, 1}, {11381, 0, 1}, {11390, 98, 2},
+ {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
+ {42560, 1, 46}, {42624, 1, 28}, {42786, 1, 14},
+ {42802, 1, 62}, {42873, 1, 4}, {42877, 94, 1},
+ {42878, 1, 10}, {42891, 0, 1}, {42893, 86, 1},
+ {42896, 1, 4}, {42902, 1, 20}, {42922, 80, 1},
+ {42923, 76, 1}, {42924, 78, 1}, {42925, 82, 1},
+ {42926, 80, 1}, {42928, 90, 1}, {42929, 84, 1},
+ {42930, 88, 1}, {42931, 68, 1}, {42932, 1, 6},
+ {43888, 92, 80}, {65313, 14, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
@@ -165886,10 +175930,10 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
23228, 23231, 23254, 23256, 23275, 23278, 26672, 30204,
35267, 54721, 54753, 54754, 54756, 54787, 54793, 54809,
57153, 57274, 57921, 58019, 58363, 59314, 59315, 59324,
- 59325, 59326, 59332, 59356, 61722, 65268, 65341, 65373,
- 65406, 65408, 65410, 65415, 65424, 65436, 65439, 65450,
- 65462, 65472, 65476, 65478, 65480, 65482, 65488, 65506,
- 65511, 65514, 65521, 65527, 65528, 65529,
+ 59325, 59326, 59332, 59356, 61722, 62528, 65268, 65341,
+ 65373, 65406, 65408, 65410, 65415, 65424, 65436, 65439,
+ 65450, 65462, 65472, 65476, 65478, 65480, 65482, 65488,
+ 65506, 65511, 65514, 65521, 65527, 65528, 65529,
};
int ret = c;
@@ -165938,17 +175982,2539 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
else if( c>=71840 && c<71872 ){
ret = c + 32;
}
+ else if( c>=93760 && c<93792 ){
+ ret = c + 32;
+ }
else if( c>=125184 && c<125218 ){
ret = c + 34;
}
return ret;
}
-#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_AMALGAMATION) || !defined(SQLITE_ENABLE_FTS5) */
+#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
/************** End of fts3_unicode2.c ***************************************/
+/************** Begin file json1.c *******************************************/
+/*
+** 2015-08-12
+**
+** 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 SQLite extension implements JSON functions. The interface is
+** modeled after MySQL JSON functions:
+**
+** https://dev.mysql.com/doc/refman/5.7/en/json.html
+**
+** For the time being, all JSON is stored as pure text. (We might add
+** a JSONB type in the future which stores a binary encoding of JSON in
+** a BLOB, but there is no support for JSONB in the current implementation.
+** This implementation parses JSON text at 250 MB/s, so it is hard to see
+** how JSONB might improve on that.)
+*/
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
+#if !defined(SQLITEINT_H)
+/* #include "sqlite3ext.h" */
+#endif
+SQLITE_EXTENSION_INIT1
+/* #include <assert.h> */
+/* #include <string.h> */
+/* #include <stdlib.h> */
+/* #include <stdarg.h> */
+
+/* Mark a function parameter as unused, to suppress nuisance compiler
+** warnings. */
+#ifndef UNUSED_PARAM
+# define UNUSED_PARAM(X) (void)(X)
+#endif
+
+#ifndef LARGEST_INT64
+# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+#endif
+
+/*
+** Versions of isspace(), isalnum() and isdigit() to which it is safe
+** to pass signed char values.
+*/
+#ifdef sqlite3Isdigit
+ /* Use the SQLite core versions if this routine is part of the
+ ** SQLite amalgamation */
+# define safe_isdigit(x) sqlite3Isdigit(x)
+# define safe_isalnum(x) sqlite3Isalnum(x)
+# define safe_isxdigit(x) sqlite3Isxdigit(x)
+#else
+ /* Use the standard library for separate compilation */
+#include <ctype.h> /* amalgamator: keep */
+# define safe_isdigit(x) isdigit((unsigned char)(x))
+# define safe_isalnum(x) isalnum((unsigned char)(x))
+# define safe_isxdigit(x) isxdigit((unsigned char)(x))
+#endif
+
+/*
+** Growing our own isspace() routine this way is twice as fast as
+** the library isspace() function, resulting in a 7% overall performance
+** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
+*/
+static const char jsonIsSpace[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
+
+#ifndef SQLITE_AMALGAMATION
+ /* Unsigned integer types. These are already defined in the sqliteInt.h,
+ ** but the definitions need to be repeated for separate compilation. */
+ typedef unsigned int u32;
+ typedef unsigned short int u16;
+ typedef unsigned char u8;
+#endif
+
+/* Objects */
+typedef struct JsonString JsonString;
+typedef struct JsonNode JsonNode;
+typedef struct JsonParse JsonParse;
+
+/* An instance of this object represents a JSON string
+** under construction. Really, this is a generic string accumulator
+** that can be and is used to create strings other than JSON.
+*/
+struct JsonString {
+ sqlite3_context *pCtx; /* Function context - put error messages here */
+ char *zBuf; /* Append JSON content here */
+ size_t nAlloc; /* Bytes of storage available in zBuf[] */
+ size_t nUsed; /* Bytes of zBuf[] currently used */
+ u8 bStatic; /* True if zBuf is static space */
+ u8 bErr; /* True if an error has been encountered */
+ char zSpace[100]; /* Initial static space */
+};
+
+/* JSON type values
+*/
+#define JSON_NULL 0
+#define JSON_TRUE 1
+#define JSON_FALSE 2
+#define JSON_INT 3
+#define JSON_REAL 4
+#define JSON_STRING 5
+#define JSON_ARRAY 6
+#define JSON_OBJECT 7
+
+/* The "subtype" set for JSON values */
+#define JSON_SUBTYPE 74 /* Ascii for "J" */
+
+/*
+** Names of the various JSON types:
+*/
+static const char jsonType[][8] = {
+ "null", "true", "false", "integer", "real", "text", "array", "object"
+};
+
+/* Bit values for the JsonNode.jnFlag field
+*/
+#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
+#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
+#define JNODE_REMOVE 0x04 /* Do not output */
+#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
+#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
+#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
+#define JNODE_LABEL 0x40 /* Is a label of an object */
+
+
+/* A single node of parsed JSON
+*/
+struct JsonNode {
+ u8 eType; /* One of the JSON_ type values */
+ u8 jnFlags; /* JNODE flags */
+ u32 n; /* Bytes of content, or number of sub-nodes */
+ union {
+ const char *zJContent; /* Content for INT, REAL, and STRING */
+ u32 iAppend; /* More terms for ARRAY and OBJECT */
+ u32 iKey; /* Key for ARRAY objects in json_tree() */
+ u32 iReplace; /* Replacement content for JNODE_REPLACE */
+ JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
+ } u;
+};
+
+/* A completely parsed JSON string
+*/
+struct JsonParse {
+ u32 nNode; /* Number of slots of aNode[] used */
+ u32 nAlloc; /* Number of slots of aNode[] allocated */
+ JsonNode *aNode; /* Array of nodes containing the parse */
+ const char *zJson; /* Original JSON string */
+ u32 *aUp; /* Index of parent of each node */
+ u8 oom; /* Set to true if out of memory */
+ u8 nErr; /* Number of errors seen */
+ u16 iDepth; /* Nesting depth */
+ int nJson; /* Length of the zJson string in bytes */
+ u32 iHold; /* Replace cache line with the lowest iHold value */
+};
+
+/*
+** Maximum nesting depth of JSON for this implementation.
+**
+** This limit is needed to avoid a stack overflow in the recursive
+** descent parser. A depth of 2000 is far deeper than any sane JSON
+** should go.
+*/
+#define JSON_MAX_DEPTH 2000
+
+/**************************************************************************
+** Utility routines for dealing with JsonString objects
+**************************************************************************/
+
+/* Set the JsonString object to an empty string
+*/
+static void jsonZero(JsonString *p){
+ p->zBuf = p->zSpace;
+ p->nAlloc = sizeof(p->zSpace);
+ p->nUsed = 0;
+ p->bStatic = 1;
+}
+
+/* Initialize the JsonString object
+*/
+static void jsonInit(JsonString *p, sqlite3_context *pCtx){
+ p->pCtx = pCtx;
+ p->bErr = 0;
+ jsonZero(p);
+}
+
+
+/* Free all allocated memory and reset the JsonString object back to its
+** initial state.
+*/
+static void jsonReset(JsonString *p){
+ if( !p->bStatic ) sqlite3_free(p->zBuf);
+ jsonZero(p);
+}
+
+
+/* Report an out-of-memory (OOM) condition
+*/
+static void jsonOom(JsonString *p){
+ p->bErr = 1;
+ sqlite3_result_error_nomem(p->pCtx);
+ jsonReset(p);
+}
+
+/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
+** Return zero on success. Return non-zero on an OOM error
+*/
+static int jsonGrow(JsonString *p, u32 N){
+ size_t nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
+ char *zNew;
+ if( p->bStatic ){
+ if( p->bErr ) return 1;
+ zNew = sqlite3_malloc(nTotal);
+ if( zNew==0 ){
+ jsonOom(p);
+ return SQLITE_NOMEM;
+ }
+ memcpy(zNew, p->zBuf, (size_t)p->nUsed);
+ p->zBuf = zNew;
+ p->bStatic = 0;
+ }else{
+ zNew = sqlite3_realloc(p->zBuf, nTotal);
+ if( zNew==0 ){
+ jsonOom(p);
+ return SQLITE_NOMEM;
+ }
+ p->zBuf = zNew;
+ }
+ p->nAlloc = nTotal;
+ return SQLITE_OK;
+}
+
+/* Append N bytes from zIn onto the end of the JsonString string.
+*/
+static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
+ if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
+ memcpy(p->zBuf+p->nUsed, zIn, N);
+ p->nUsed += N;
+}
+
+/* Append formatted text (not to exceed N bytes) to the JsonString.
+*/
+static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
+ va_list ap;
+ if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
+ va_start(ap, zFormat);
+ sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
+ va_end(ap);
+ p->nUsed += (int)strlen(p->zBuf+p->nUsed);
+}
+
+/* Append a single character
+*/
+static void jsonAppendChar(JsonString *p, char c){
+ if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
+ p->zBuf[p->nUsed++] = c;
+}
+
+/* Append a comma separator to the output buffer, if the previous
+** character is not '[' or '{'.
+*/
+static void jsonAppendSeparator(JsonString *p){
+ char c;
+ if( p->nUsed==0 ) return;
+ c = p->zBuf[p->nUsed-1];
+ if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
+}
+
+/* Append the N-byte string in zIn to the end of the JsonString string
+** under construction. Enclose the string in "..." and escape
+** any double-quotes or backslash characters contained within the
+** string.
+*/
+static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
+ u32 i;
+ if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
+ p->zBuf[p->nUsed++] = '"';
+ for(i=0; i<N; i++){
+ unsigned char c = ((unsigned const char*)zIn)[i];
+ if( c=='"' || c=='\\' ){
+ json_simple_escape:
+ if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
+ p->zBuf[p->nUsed++] = '\\';
+ }else if( c<=0x1f ){
+ static const char aSpecial[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ assert( sizeof(aSpecial)==32 );
+ assert( aSpecial['\b']=='b' );
+ assert( aSpecial['\f']=='f' );
+ assert( aSpecial['\n']=='n' );
+ assert( aSpecial['\r']=='r' );
+ assert( aSpecial['\t']=='t' );
+ if( aSpecial[c] ){
+ c = aSpecial[c];
+ goto json_simple_escape;
+ }
+ if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
+ p->zBuf[p->nUsed++] = '\\';
+ p->zBuf[p->nUsed++] = 'u';
+ p->zBuf[p->nUsed++] = '0';
+ p->zBuf[p->nUsed++] = '0';
+ p->zBuf[p->nUsed++] = '0' + (c>>4);
+ c = "0123456789abcdef"[c&0xf];
+ }
+ p->zBuf[p->nUsed++] = c;
+ }
+ p->zBuf[p->nUsed++] = '"';
+ assert( p->nUsed<p->nAlloc );
+}
+
+/*
+** Append a function parameter value to the JSON string under
+** construction.
+*/
+static void jsonAppendValue(
+ JsonString *p, /* Append to this JSON string */
+ sqlite3_value *pValue /* Value to append */
+){
+ switch( sqlite3_value_type(pValue) ){
+ case SQLITE_NULL: {
+ jsonAppendRaw(p, "null", 4);
+ break;
+ }
+ case SQLITE_INTEGER:
+ case SQLITE_FLOAT: {
+ const char *z = (const char*)sqlite3_value_text(pValue);
+ u32 n = (u32)sqlite3_value_bytes(pValue);
+ jsonAppendRaw(p, z, n);
+ break;
+ }
+ case SQLITE_TEXT: {
+ const char *z = (const char*)sqlite3_value_text(pValue);
+ u32 n = (u32)sqlite3_value_bytes(pValue);
+ if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
+ jsonAppendRaw(p, z, n);
+ }else{
+ jsonAppendString(p, z, n);
+ }
+ break;
+ }
+ default: {
+ if( p->bErr==0 ){
+ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
+ p->bErr = 2;
+ jsonReset(p);
+ }
+ break;
+ }
+ }
+}
+
+
+/* Make the JSON in p the result of the SQL function.
+*/
+static void jsonResult(JsonString *p){
+ if( p->bErr==0 ){
+ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
+ p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
+ SQLITE_UTF8);
+ jsonZero(p);
+ }
+ assert( p->bStatic );
+}
+
+/**************************************************************************
+** Utility routines for dealing with JsonNode and JsonParse objects
+**************************************************************************/
+
+/*
+** Return the number of consecutive JsonNode slots need to represent
+** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
+** OBJECT types, the number might be larger.
+**
+** Appended elements are not counted. The value returned is the number
+** by which the JsonNode counter should increment in order to go to the
+** next peer value.
+*/
+static u32 jsonNodeSize(JsonNode *pNode){
+ return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
+}
+
+/*
+** Reclaim all memory allocated by a JsonParse object. But do not
+** delete the JsonParse object itself.
+*/
+static void jsonParseReset(JsonParse *pParse){
+ sqlite3_free(pParse->aNode);
+ pParse->aNode = 0;
+ pParse->nNode = 0;
+ pParse->nAlloc = 0;
+ sqlite3_free(pParse->aUp);
+ pParse->aUp = 0;
+}
+
+/*
+** Free a JsonParse object that was obtained from sqlite3_malloc().
+*/
+static void jsonParseFree(JsonParse *pParse){
+ jsonParseReset(pParse);
+ sqlite3_free(pParse);
+}
+
+/*
+** Convert the JsonNode pNode into a pure JSON string and
+** append to pOut. Subsubstructure is also included. Return
+** the number of JsonNode objects that are encoded.
+*/
+static void jsonRenderNode(
+ JsonNode *pNode, /* The node to render */
+ JsonString *pOut, /* Write JSON here */
+ sqlite3_value **aReplace /* Replacement values */
+){
+ if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
+ if( pNode->jnFlags & JNODE_REPLACE ){
+ jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
+ return;
+ }
+ pNode = pNode->u.pPatch;
+ }
+ switch( pNode->eType ){
+ default: {
+ assert( pNode->eType==JSON_NULL );
+ jsonAppendRaw(pOut, "null", 4);
+ break;
+ }
+ case JSON_TRUE: {
+ jsonAppendRaw(pOut, "true", 4);
+ break;
+ }
+ case JSON_FALSE: {
+ jsonAppendRaw(pOut, "false", 5);
+ break;
+ }
+ case JSON_STRING: {
+ if( pNode->jnFlags & JNODE_RAW ){
+ jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
+ break;
+ }
+ /* Fall through into the next case */
+ }
+ case JSON_REAL:
+ case JSON_INT: {
+ jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+ break;
+ }
+ case JSON_ARRAY: {
+ u32 j = 1;
+ jsonAppendChar(pOut, '[');
+ for(;;){
+ while( j<=pNode->n ){
+ if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
+ jsonAppendSeparator(pOut);
+ jsonRenderNode(&pNode[j], pOut, aReplace);
+ }
+ j += jsonNodeSize(&pNode[j]);
+ }
+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+ pNode = &pNode[pNode->u.iAppend];
+ j = 1;
+ }
+ jsonAppendChar(pOut, ']');
+ break;
+ }
+ case JSON_OBJECT: {
+ u32 j = 1;
+ jsonAppendChar(pOut, '{');
+ for(;;){
+ while( j<=pNode->n ){
+ if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
+ jsonAppendSeparator(pOut);
+ jsonRenderNode(&pNode[j], pOut, aReplace);
+ jsonAppendChar(pOut, ':');
+ jsonRenderNode(&pNode[j+1], pOut, aReplace);
+ }
+ j += 1 + jsonNodeSize(&pNode[j+1]);
+ }
+ if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+ pNode = &pNode[pNode->u.iAppend];
+ j = 1;
+ }
+ jsonAppendChar(pOut, '}');
+ break;
+ }
+ }
+}
+
+/*
+** Return a JsonNode and all its descendents as a JSON string.
+*/
+static void jsonReturnJson(
+ JsonNode *pNode, /* Node to return */
+ sqlite3_context *pCtx, /* Return value for this function */
+ sqlite3_value **aReplace /* Array of replacement values */
+){
+ JsonString s;
+ jsonInit(&s, pCtx);
+ jsonRenderNode(pNode, &s, aReplace);
+ jsonResult(&s);
+ sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
+}
+
+/*
+** Make the JsonNode the return value of the function.
+*/
+static void jsonReturn(
+ JsonNode *pNode, /* Node to return */
+ sqlite3_context *pCtx, /* Return value for this function */
+ sqlite3_value **aReplace /* Array of replacement values */
+){
+ switch( pNode->eType ){
+ default: {
+ assert( pNode->eType==JSON_NULL );
+ sqlite3_result_null(pCtx);
+ break;
+ }
+ case JSON_TRUE: {
+ sqlite3_result_int(pCtx, 1);
+ break;
+ }
+ case JSON_FALSE: {
+ sqlite3_result_int(pCtx, 0);
+ break;
+ }
+ case JSON_INT: {
+ sqlite3_int64 i = 0;
+ const char *z = pNode->u.zJContent;
+ if( z[0]=='-' ){ z++; }
+ while( z[0]>='0' && z[0]<='9' ){
+ unsigned v = *(z++) - '0';
+ if( i>=LARGEST_INT64/10 ){
+ if( i>LARGEST_INT64/10 ) goto int_as_real;
+ if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
+ if( v==9 ) goto int_as_real;
+ if( v==8 ){
+ if( pNode->u.zJContent[0]=='-' ){
+ sqlite3_result_int64(pCtx, SMALLEST_INT64);
+ goto int_done;
+ }else{
+ goto int_as_real;
+ }
+ }
+ }
+ i = i*10 + v;
+ }
+ if( pNode->u.zJContent[0]=='-' ){ i = -i; }
+ sqlite3_result_int64(pCtx, i);
+ int_done:
+ break;
+ int_as_real: /* fall through to real */;
+ }
+ case JSON_REAL: {
+ double r;
+#ifdef SQLITE_AMALGAMATION
+ const char *z = pNode->u.zJContent;
+ sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
+#else
+ r = strtod(pNode->u.zJContent, 0);
+#endif
+ sqlite3_result_double(pCtx, r);
+ break;
+ }
+ case JSON_STRING: {
+#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
+ ** json_insert() and json_replace() and those routines do not
+ ** call jsonReturn() */
+ if( pNode->jnFlags & JNODE_RAW ){
+ sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
+ SQLITE_TRANSIENT);
+ }else
+#endif
+ assert( (pNode->jnFlags & JNODE_RAW)==0 );
+ if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+ /* JSON formatted without any backslash-escapes */
+ sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
+ SQLITE_TRANSIENT);
+ }else{
+ /* Translate JSON formatted string into raw text */
+ u32 i;
+ u32 n = pNode->n;
+ const char *z = pNode->u.zJContent;
+ char *zOut;
+ u32 j;
+ zOut = sqlite3_malloc( n+1 );
+ if( zOut==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ break;
+ }
+ for(i=1, j=0; i<n-1; i++){
+ char c = z[i];
+ if( c!='\\' ){
+ zOut[j++] = c;
+ }else{
+ c = z[++i];
+ if( c=='u' ){
+ u32 v = 0, k;
+ for(k=0; k<4; i++, k++){
+ assert( i<n-2 );
+ c = z[i+1];
+ assert( safe_isxdigit(c) );
+ if( c<='9' ) v = v*16 + c - '0';
+ else if( c<='F' ) v = v*16 + c - 'A' + 10;
+ else v = v*16 + c - 'a' + 10;
+ }
+ if( v==0 ) break;
+ if( v<=0x7f ){
+ zOut[j++] = (char)v;
+ }else if( v<=0x7ff ){
+ zOut[j++] = (char)(0xc0 | (v>>6));
+ zOut[j++] = 0x80 | (v&0x3f);
+ }else{
+ zOut[j++] = (char)(0xe0 | (v>>12));
+ zOut[j++] = 0x80 | ((v>>6)&0x3f);
+ zOut[j++] = 0x80 | (v&0x3f);
+ }
+ }else{
+ if( c=='b' ){
+ c = '\b';
+ }else if( c=='f' ){
+ c = '\f';
+ }else if( c=='n' ){
+ c = '\n';
+ }else if( c=='r' ){
+ c = '\r';
+ }else if( c=='t' ){
+ c = '\t';
+ }
+ zOut[j++] = c;
+ }
+ }
+ }
+ zOut[j] = 0;
+ sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
+ }
+ break;
+ }
+ case JSON_ARRAY:
+ case JSON_OBJECT: {
+ jsonReturnJson(pNode, pCtx, aReplace);
+ break;
+ }
+ }
+}
+
+/* Forward reference */
+static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
+
+/*
+** A macro to hint to the compiler that a function should not be
+** inlined.
+*/
+#if defined(__GNUC__)
+# define JSON_NOINLINE __attribute__((noinline))
+#elif defined(_MSC_VER) && _MSC_VER>=1310
+# define JSON_NOINLINE __declspec(noinline)
+#else
+# define JSON_NOINLINE
+#endif
+
+
+static JSON_NOINLINE int jsonParseAddNodeExpand(
+ JsonParse *pParse, /* Append the node to this object */
+ u32 eType, /* Node type */
+ u32 n, /* Content size or sub-node count */
+ const char *zContent /* Content */
+){
+ u32 nNew;
+ JsonNode *pNew;
+ assert( pParse->nNode>=pParse->nAlloc );
+ if( pParse->oom ) return -1;
+ nNew = pParse->nAlloc*2 + 10;
+ pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+ if( pNew==0 ){
+ pParse->oom = 1;
+ return -1;
+ }
+ pParse->nAlloc = nNew;
+ pParse->aNode = pNew;
+ assert( pParse->nNode<pParse->nAlloc );
+ return jsonParseAddNode(pParse, eType, n, zContent);
+}
+
+/*
+** Create a new JsonNode instance based on the arguments and append that
+** instance to the JsonParse. Return the index in pParse->aNode[] of the
+** new node, or -1 if a memory allocation fails.
+*/
+static int jsonParseAddNode(
+ JsonParse *pParse, /* Append the node to this object */
+ u32 eType, /* Node type */
+ u32 n, /* Content size or sub-node count */
+ const char *zContent /* Content */
+){
+ JsonNode *p;
+ if( pParse->nNode>=pParse->nAlloc ){
+ return jsonParseAddNodeExpand(pParse, eType, n, zContent);
+ }
+ p = &pParse->aNode[pParse->nNode];
+ p->eType = (u8)eType;
+ p->jnFlags = 0;
+ p->n = n;
+ p->u.zJContent = zContent;
+ return pParse->nNode++;
+}
+
+/*
+** Return true if z[] begins with 4 (or more) hexadecimal digits
+*/
+static int jsonIs4Hex(const char *z){
+ int i;
+ for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
+ return 1;
+}
+
+/*
+** Parse a single JSON value which begins at pParse->zJson[i]. Return the
+** index of the first character past the end of the value parsed.
+**
+** Return negative for a syntax error. Special cases: return -2 if the
+** first non-whitespace character is '}' and return -3 if the first
+** non-whitespace character is ']'.
+*/
+static int jsonParseValue(JsonParse *pParse, u32 i){
+ char c;
+ u32 j;
+ int iThis;
+ int x;
+ JsonNode *pNode;
+ const char *z = pParse->zJson;
+ while( safe_isspace(z[i]) ){ i++; }
+ if( (c = z[i])=='{' ){
+ /* Parse object */
+ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+ if( iThis<0 ) return -1;
+ for(j=i+1;;j++){
+ while( safe_isspace(z[j]) ){ j++; }
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+ x = jsonParseValue(pParse, j);
+ if( x<0 ){
+ pParse->iDepth--;
+ if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ return -1;
+ }
+ if( pParse->oom ) return -1;
+ pNode = &pParse->aNode[pParse->nNode-1];
+ if( pNode->eType!=JSON_STRING ) return -1;
+ pNode->jnFlags |= JNODE_LABEL;
+ j = x;
+ while( safe_isspace(z[j]) ){ j++; }
+ if( z[j]!=':' ) return -1;
+ j++;
+ x = jsonParseValue(pParse, j);
+ pParse->iDepth--;
+ if( x<0 ) return -1;
+ j = x;
+ while( safe_isspace(z[j]) ){ j++; }
+ c = z[j];
+ if( c==',' ) continue;
+ if( c!='}' ) return -1;
+ break;
+ }
+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+ return j+1;
+ }else if( c=='[' ){
+ /* Parse array */
+ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+ if( iThis<0 ) return -1;
+ for(j=i+1;;j++){
+ while( safe_isspace(z[j]) ){ j++; }
+ if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+ x = jsonParseValue(pParse, j);
+ pParse->iDepth--;
+ if( x<0 ){
+ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ return -1;
+ }
+ j = x;
+ while( safe_isspace(z[j]) ){ j++; }
+ c = z[j];
+ if( c==',' ) continue;
+ if( c!=']' ) return -1;
+ break;
+ }
+ pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+ return j+1;
+ }else if( c=='"' ){
+ /* Parse string */
+ u8 jnFlags = 0;
+ j = i+1;
+ for(;;){
+ c = z[j];
+ if( (c & ~0x1f)==0 ){
+ /* Control characters are not allowed in strings */
+ return -1;
+ }
+ if( c=='\\' ){
+ c = z[++j];
+ if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
+ || c=='n' || c=='r' || c=='t'
+ || (c=='u' && jsonIs4Hex(z+j+1)) ){
+ jnFlags = JNODE_ESCAPE;
+ }else{
+ return -1;
+ }
+ }else if( c=='"' ){
+ break;
+ }
+ j++;
+ }
+ jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
+ if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
+ return j+1;
+ }else if( c=='n'
+ && strncmp(z+i,"null",4)==0
+ && !safe_isalnum(z[i+4]) ){
+ jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+ return i+4;
+ }else if( c=='t'
+ && strncmp(z+i,"true",4)==0
+ && !safe_isalnum(z[i+4]) ){
+ jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ return i+4;
+ }else if( c=='f'
+ && strncmp(z+i,"false",5)==0
+ && !safe_isalnum(z[i+5]) ){
+ jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+ return i+5;
+ }else if( c=='-' || (c>='0' && c<='9') ){
+ /* Parse number */
+ u8 seenDP = 0;
+ u8 seenE = 0;
+ assert( '-' < '0' );
+ if( c<='0' ){
+ j = c=='-' ? i+1 : i;
+ if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+ }
+ j = i+1;
+ for(;; j++){
+ c = z[j];
+ if( c>='0' && c<='9' ) continue;
+ if( c=='.' ){
+ if( z[j-1]=='-' ) return -1;
+ if( seenDP ) return -1;
+ seenDP = 1;
+ continue;
+ }
+ if( c=='e' || c=='E' ){
+ if( z[j-1]<'0' ) return -1;
+ if( seenE ) return -1;
+ seenDP = seenE = 1;
+ c = z[j+1];
+ if( c=='+' || c=='-' ){
+ j++;
+ c = z[j+1];
+ }
+ if( c<'0' || c>'9' ) return -1;
+ continue;
+ }
+ break;
+ }
+ if( z[j-1]<'0' ) return -1;
+ jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
+ j - i, &z[i]);
+ return j;
+ }else if( c=='}' ){
+ return -2; /* End of {...} */
+ }else if( c==']' ){
+ return -3; /* End of [...] */
+ }else if( c==0 ){
+ return 0; /* End of file */
+ }else{
+ return -1; /* Syntax error */
+ }
+}
+
+/*
+** Parse a complete JSON string. Return 0 on success or non-zero if there
+** are any errors. If an error occurs, free all memory associated with
+** pParse.
+**
+** pParse is uninitialized when this routine is called.
+*/
+static int jsonParse(
+ JsonParse *pParse, /* Initialize and fill this JsonParse object */
+ sqlite3_context *pCtx, /* Report errors here */
+ const char *zJson /* Input JSON text to be parsed */
+){
+ int i;
+ memset(pParse, 0, sizeof(*pParse));
+ if( zJson==0 ) return 1;
+ pParse->zJson = zJson;
+ i = jsonParseValue(pParse, 0);
+ if( pParse->oom ) i = -1;
+ if( i>0 ){
+ assert( pParse->iDepth==0 );
+ while( safe_isspace(zJson[i]) ) i++;
+ if( zJson[i] ) i = -1;
+ }
+ if( i<=0 ){
+ if( pCtx!=0 ){
+ if( pParse->oom ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ sqlite3_result_error(pCtx, "malformed JSON", -1);
+ }
+ }
+ jsonParseReset(pParse);
+ return 1;
+ }
+ return 0;
+}
+
+/* Mark node i of pParse as being a child of iParent. Call recursively
+** to fill in all the descendants of node i.
+*/
+static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
+ JsonNode *pNode = &pParse->aNode[i];
+ u32 j;
+ pParse->aUp[i] = iParent;
+ switch( pNode->eType ){
+ case JSON_ARRAY: {
+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
+ jsonParseFillInParentage(pParse, i+j, i);
+ }
+ break;
+ }
+ case JSON_OBJECT: {
+ for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
+ pParse->aUp[i+j] = i;
+ jsonParseFillInParentage(pParse, i+j+1, i);
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+
+/*
+** Compute the parentage of all nodes in a completed parse.
+*/
+static int jsonParseFindParents(JsonParse *pParse){
+ u32 *aUp;
+ assert( pParse->aUp==0 );
+ aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+ if( aUp==0 ){
+ pParse->oom = 1;
+ return SQLITE_NOMEM;
+ }
+ jsonParseFillInParentage(pParse, 0, 0);
+ return SQLITE_OK;
+}
+
+/*
+** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
+*/
+#define JSON_CACHE_ID (-429938) /* First cache entry */
+#define JSON_CACHE_SZ 4 /* Max number of cache entries */
+
+/*
+** Obtain a complete parse of the JSON found in the first argument
+** of the argv array. Use the sqlite3_get_auxdata() cache for this
+** parse if it is available. If the cache is not available or if it
+** is no longer valid, parse the JSON again and return the new parse,
+** and also register the new parse so that it will be available for
+** future sqlite3_get_auxdata() calls.
+*/
+static JsonParse *jsonParseCached(
+ sqlite3_context *pCtx,
+ sqlite3_value **argv,
+ sqlite3_context *pErrCtx
+){
+ const char *zJson = (const char*)sqlite3_value_text(argv[0]);
+ int nJson = sqlite3_value_bytes(argv[0]);
+ JsonParse *p;
+ JsonParse *pMatch = 0;
+ int iKey;
+ int iMinKey = 0;
+ u32 iMinHold = 0xffffffff;
+ u32 iMaxHold = 0;
+ if( zJson==0 ) return 0;
+ for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
+ p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
+ if( p==0 ){
+ iMinKey = iKey;
+ break;
+ }
+ if( pMatch==0
+ && p->nJson==nJson
+ && memcmp(p->zJson,zJson,nJson)==0
+ ){
+ p->nErr = 0;
+ pMatch = p;
+ }else if( p->iHold<iMinHold ){
+ iMinHold = p->iHold;
+ iMinKey = iKey;
+ }
+ if( p->iHold>iMaxHold ){
+ iMaxHold = p->iHold;
+ }
+ }
+ if( pMatch ){
+ pMatch->nErr = 0;
+ pMatch->iHold = iMaxHold+1;
+ return pMatch;
+ }
+ p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+ if( p==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return 0;
+ }
+ memset(p, 0, sizeof(*p));
+ p->zJson = (char*)&p[1];
+ memcpy((char*)p->zJson, zJson, nJson+1);
+ if( jsonParse(p, pErrCtx, p->zJson) ){
+ sqlite3_free(p);
+ return 0;
+ }
+ p->nJson = nJson;
+ p->iHold = iMaxHold+1;
+ sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
+ (void(*)(void*))jsonParseFree);
+ return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
+}
+
+/*
+** Compare the OBJECT label at pNode against zKey,nKey. Return true on
+** a match.
+*/
+static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
+ if( pNode->jnFlags & JNODE_RAW ){
+ if( pNode->n!=nKey ) return 0;
+ return strncmp(pNode->u.zJContent, zKey, nKey)==0;
+ }else{
+ if( pNode->n!=nKey+2 ) return 0;
+ return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
+ }
+}
+
+/* forward declaration */
+static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
+
+/*
+** Search along zPath to find the node specified. Return a pointer
+** to that node, or NULL if zPath is malformed or if there is no such
+** node.
+**
+** If pApnd!=0, then try to append new nodes to complete zPath if it is
+** possible to do so and if no existing node corresponds to zPath. If
+** new nodes are appended *pApnd is set to 1.
+*/
+static JsonNode *jsonLookupStep(
+ JsonParse *pParse, /* The JSON to search */
+ u32 iRoot, /* Begin the search at this node */
+ const char *zPath, /* The path to search */
+ int *pApnd, /* Append nodes to complete path if not NULL */
+ const char **pzErr /* Make *pzErr point to any syntax error in zPath */
+){
+ u32 i, j, nKey;
+ const char *zKey;
+ JsonNode *pRoot = &pParse->aNode[iRoot];
+ if( zPath[0]==0 ) return pRoot;
+ if( zPath[0]=='.' ){
+ if( pRoot->eType!=JSON_OBJECT ) return 0;
+ zPath++;
+ if( zPath[0]=='"' ){
+ zKey = zPath + 1;
+ for(i=1; zPath[i] && zPath[i]!='"'; i++){}
+ nKey = i-1;
+ if( zPath[i] ){
+ i++;
+ }else{
+ *pzErr = zPath;
+ return 0;
+ }
+ }else{
+ zKey = zPath;
+ for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
+ nKey = i;
+ }
+ if( nKey==0 ){
+ *pzErr = zPath;
+ return 0;
+ }
+ j = 1;
+ for(;;){
+ while( j<=pRoot->n ){
+ if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
+ return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
+ }
+ j++;
+ j += jsonNodeSize(&pRoot[j]);
+ }
+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+ iRoot += pRoot->u.iAppend;
+ pRoot = &pParse->aNode[iRoot];
+ j = 1;
+ }
+ if( pApnd ){
+ u32 iStart, iLabel;
+ JsonNode *pNode;
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+ iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+ zPath += i;
+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+ if( pParse->oom ) return 0;
+ if( pNode ){
+ pRoot = &pParse->aNode[iRoot];
+ pRoot->u.iAppend = iStart - iRoot;
+ pRoot->jnFlags |= JNODE_APPEND;
+ pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
+ }
+ return pNode;
+ }
+ }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
+ if( pRoot->eType!=JSON_ARRAY ) return 0;
+ i = 0;
+ j = 1;
+ while( safe_isdigit(zPath[j]) ){
+ i = i*10 + zPath[j] - '0';
+ j++;
+ }
+ if( zPath[j]!=']' ){
+ *pzErr = zPath;
+ return 0;
+ }
+ zPath += j + 1;
+ j = 1;
+ for(;;){
+ while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
+ if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
+ j += jsonNodeSize(&pRoot[j]);
+ }
+ if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+ iRoot += pRoot->u.iAppend;
+ pRoot = &pParse->aNode[iRoot];
+ j = 1;
+ }
+ if( j<=pRoot->n ){
+ return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
+ }
+ if( i==0 && pApnd ){
+ u32 iStart;
+ JsonNode *pNode;
+ iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
+ pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+ if( pParse->oom ) return 0;
+ if( pNode ){
+ pRoot = &pParse->aNode[iRoot];
+ pRoot->u.iAppend = iStart - iRoot;
+ pRoot->jnFlags |= JNODE_APPEND;
+ }
+ return pNode;
+ }
+ }else{
+ *pzErr = zPath;
+ }
+ return 0;
+}
+
+/*
+** Append content to pParse that will complete zPath. Return a pointer
+** to the inserted node, or return NULL if the append fails.
+*/
+static JsonNode *jsonLookupAppend(
+ JsonParse *pParse, /* Append content to the JSON parse */
+ const char *zPath, /* Description of content to append */
+ int *pApnd, /* Set this flag to 1 */
+ const char **pzErr /* Make this point to any syntax error */
+){
+ *pApnd = 1;
+ if( zPath[0]==0 ){
+ jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+ return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
+ }
+ if( zPath[0]=='.' ){
+ jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+ }else if( strncmp(zPath,"[0]",3)==0 ){
+ jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+ }else{
+ return 0;
+ }
+ if( pParse->oom ) return 0;
+ return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
+}
+
+/*
+** Return the text of a syntax error message on a JSON path. Space is
+** obtained from sqlite3_malloc().
+*/
+static char *jsonPathSyntaxError(const char *zErr){
+ return sqlite3_mprintf("JSON path error near '%q'", zErr);
+}
+
+/*
+** Do a node lookup using zPath. Return a pointer to the node on success.
+** Return NULL if not found or if there is an error.
+**
+** On an error, write an error message into pCtx and increment the
+** pParse->nErr counter.
+**
+** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
+** nodes are appended.
+*/
+static JsonNode *jsonLookup(
+ JsonParse *pParse, /* The JSON to search */
+ const char *zPath, /* The path to search */
+ int *pApnd, /* Append nodes to complete path if not NULL */
+ sqlite3_context *pCtx /* Report errors here, if not NULL */
+){
+ const char *zErr = 0;
+ JsonNode *pNode = 0;
+ char *zMsg;
+
+ if( zPath==0 ) return 0;
+ if( zPath[0]!='$' ){
+ zErr = zPath;
+ goto lookup_err;
+ }
+ zPath++;
+ pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
+ if( zErr==0 ) return pNode;
+
+lookup_err:
+ pParse->nErr++;
+ assert( zErr!=0 && pCtx!=0 );
+ zMsg = jsonPathSyntaxError(zErr);
+ if( zMsg ){
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
+ }else{
+ sqlite3_result_error_nomem(pCtx);
+ }
+ return 0;
+}
+
+
+/*
+** Report the wrong number of arguments for json_insert(), json_replace()
+** or json_set().
+*/
+static void jsonWrongNumArgs(
+ sqlite3_context *pCtx,
+ const char *zFuncName
+){
+ char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
+ zFuncName);
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
+}
+
+/*
+** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
+*/
+static void jsonRemoveAllNulls(JsonNode *pNode){
+ int i, n;
+ assert( pNode->eType==JSON_OBJECT );
+ n = pNode->n;
+ for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
+ switch( pNode[i].eType ){
+ case JSON_NULL:
+ pNode[i].jnFlags |= JNODE_REMOVE;
+ break;
+ case JSON_OBJECT:
+ jsonRemoveAllNulls(&pNode[i]);
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+** SQL functions used for testing and debugging
+****************************************************************************/
+
+#ifdef SQLITE_DEBUG
+/*
+** The json_parse(JSON) function returns a string which describes
+** a parse of the JSON provided. Or it returns NULL if JSON is not
+** well-formed.
+*/
+static void jsonParseFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString s; /* Output string - not real JSON */
+ JsonParse x; /* The parse */
+ u32 i;
+
+ assert( argc==1 );
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ jsonParseFindParents(&x);
+ jsonInit(&s, ctx);
+ for(i=0; i<x.nNode; i++){
+ const char *zType;
+ if( x.aNode[i].jnFlags & JNODE_LABEL ){
+ assert( x.aNode[i].eType==JSON_STRING );
+ zType = "label";
+ }else{
+ zType = jsonType[x.aNode[i].eType];
+ }
+ jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
+ i, zType, x.aNode[i].n, x.aUp[i]);
+ if( x.aNode[i].u.zJContent!=0 ){
+ jsonAppendRaw(&s, " ", 1);
+ jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
+ }
+ jsonAppendRaw(&s, "\n", 1);
+ }
+ jsonParseReset(&x);
+ jsonResult(&s);
+}
+
+/*
+** The json_test1(JSON) function return true (1) if the input is JSON
+** text generated by another json function. It returns (0) if the input
+** is not known to be JSON.
+*/
+static void jsonTest1Func(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ UNUSED_PARAM(argc);
+ sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
+}
+#endif /* SQLITE_DEBUG */
+
+/****************************************************************************
+** Scalar SQL function implementations
+****************************************************************************/
+
+/*
+** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
+** corresponding to the SQL value input. Mostly this means putting
+** double-quotes around strings and returning the unquoted string "null"
+** when given a NULL input.
+*/
+static void jsonQuoteFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString jx;
+ UNUSED_PARAM(argc);
+
+ jsonInit(&jx, ctx);
+ jsonAppendValue(&jx, argv[0]);
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+/*
+** Implementation of the json_array(VALUE,...) function. Return a JSON
+** array that contains all values given in arguments. Or if any argument
+** is a BLOB, throw an error.
+*/
+static void jsonArrayFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ JsonString jx;
+
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '[');
+ for(i=0; i<argc; i++){
+ jsonAppendSeparator(&jx);
+ jsonAppendValue(&jx, argv[i]);
+ }
+ jsonAppendChar(&jx, ']');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
+/*
+** json_array_length(JSON)
+** json_array_length(JSON, PATH)
+**
+** Return the number of elements in the top-level JSON array.
+** Return 0 if the input is not a well-formed JSON array.
+*/
+static void jsonArrayLengthFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse *p; /* The parse */
+ sqlite3_int64 n = 0;
+ u32 i;
+ JsonNode *pNode;
+
+ p = jsonParseCached(ctx, argv, ctx);
+ if( p==0 ) return;
+ assert( p->nNode );
+ if( argc==2 ){
+ const char *zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ }else{
+ pNode = p->aNode;
+ }
+ if( pNode==0 ){
+ return;
+ }
+ if( pNode->eType==JSON_ARRAY ){
+ assert( (pNode->jnFlags & JNODE_APPEND)==0 );
+ for(i=1; i<=pNode->n; n++){
+ i += jsonNodeSize(&pNode[i]);
+ }
+ }
+ sqlite3_result_int64(ctx, n);
+}
+
+/*
+** json_extract(JSON, PATH, ...)
+**
+** Return the element described by PATH. Return NULL if there is no
+** PATH element. If there are multiple PATHs, then return a JSON array
+** with the result from each path. Throw an error if the JSON or any PATH
+** is malformed.
+*/
+static void jsonExtractFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse *p; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ JsonString jx;
+ int i;
+
+ if( argc<2 ) return;
+ p = jsonParseCached(ctx, argv, ctx);
+ if( p==0 ) return;
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '[');
+ for(i=1; i<argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ if( p->nErr ) break;
+ if( argc>2 ){
+ jsonAppendSeparator(&jx);
+ if( pNode ){
+ jsonRenderNode(pNode, &jx, 0);
+ }else{
+ jsonAppendRaw(&jx, "null", 4);
+ }
+ }else if( pNode ){
+ jsonReturn(pNode, ctx, 0);
+ }
+ }
+ if( argc>2 && i==argc ){
+ jsonAppendChar(&jx, ']');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+ }
+ jsonReset(&jx);
+}
+
+/* This is the RFC 7396 MergePatch algorithm.
+*/
+static JsonNode *jsonMergePatch(
+ JsonParse *pParse, /* The JSON parser that contains the TARGET */
+ u32 iTarget, /* Node of the TARGET in pParse */
+ JsonNode *pPatch /* The PATCH */
+){
+ u32 i, j;
+ u32 iRoot;
+ JsonNode *pTarget;
+ if( pPatch->eType!=JSON_OBJECT ){
+ return pPatch;
+ }
+ assert( iTarget>=0 && iTarget<pParse->nNode );
+ pTarget = &pParse->aNode[iTarget];
+ assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
+ if( pTarget->eType!=JSON_OBJECT ){
+ jsonRemoveAllNulls(pPatch);
+ return pPatch;
+ }
+ iRoot = iTarget;
+ for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
+ u32 nKey;
+ const char *zKey;
+ assert( pPatch[i].eType==JSON_STRING );
+ assert( pPatch[i].jnFlags & JNODE_LABEL );
+ nKey = pPatch[i].n;
+ zKey = pPatch[i].u.zJContent;
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
+ assert( pTarget[j].eType==JSON_STRING );
+ assert( pTarget[j].jnFlags & JNODE_LABEL );
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+ if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
+ if( pPatch[i+1].eType==JSON_NULL ){
+ pTarget[j+1].jnFlags |= JNODE_REMOVE;
+ }else{
+ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
+ if( pNew==0 ) return 0;
+ pTarget = &pParse->aNode[iTarget];
+ if( pNew!=&pTarget[j+1] ){
+ pTarget[j+1].u.pPatch = pNew;
+ pTarget[j+1].jnFlags |= JNODE_PATCH;
+ }
+ }
+ break;
+ }
+ }
+ if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
+ int iStart, iPatch;
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+ jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+ iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ if( pParse->oom ) return 0;
+ jsonRemoveAllNulls(pPatch);
+ pTarget = &pParse->aNode[iTarget];
+ pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
+ pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
+ iRoot = iStart;
+ pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
+ pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
+ }
+ }
+ return pTarget;
+}
+
+/*
+** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
+** object that is the result of running the RFC 7396 MergePatch() algorithm
+** on the two arguments.
+*/
+static void jsonPatchFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The JSON that is being patched */
+ JsonParse y; /* The patch */
+ JsonNode *pResult; /* The result of the merge */
+
+ UNUSED_PARAM(argc);
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
+ jsonParseReset(&x);
+ return;
+ }
+ pResult = jsonMergePatch(&x, 0, y.aNode);
+ assert( pResult!=0 || x.oom );
+ if( pResult ){
+ jsonReturnJson(pResult, ctx, 0);
+ }else{
+ sqlite3_result_error_nomem(ctx);
+ }
+ jsonParseReset(&x);
+ jsonParseReset(&y);
+}
+
+
+/*
+** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
+** object that contains all name/value given in arguments. Or if any name
+** is not a string or if any value is a BLOB, throw an error.
+*/
+static void jsonObjectFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ JsonString jx;
+ const char *z;
+ u32 n;
+
+ if( argc&1 ){
+ sqlite3_result_error(ctx, "json_object() requires an even number "
+ "of arguments", -1);
+ return;
+ }
+ jsonInit(&jx, ctx);
+ jsonAppendChar(&jx, '{');
+ for(i=0; i<argc; i+=2){
+ if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
+ sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
+ jsonReset(&jx);
+ return;
+ }
+ jsonAppendSeparator(&jx);
+ z = (const char*)sqlite3_value_text(argv[i]);
+ n = (u32)sqlite3_value_bytes(argv[i]);
+ jsonAppendString(&jx, z, n);
+ jsonAppendChar(&jx, ':');
+ jsonAppendValue(&jx, argv[i+1]);
+ }
+ jsonAppendChar(&jx, '}');
+ jsonResult(&jx);
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+
+
+/*
+** json_remove(JSON, PATH, ...)
+**
+** Remove the named elements from JSON and return the result. malformed
+** JSON or PATH arguments result in an error.
+*/
+static void jsonRemoveFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+
+ if( argc<1 ) return;
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ if( zPath==0 ) goto remove_done;
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto remove_done;
+ if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
+ }
+ if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
+ jsonReturnJson(x.aNode, ctx, 0);
+ }
+remove_done:
+ jsonParseReset(&x);
+}
+
+/*
+** json_replace(JSON, PATH, VALUE, ...)
+**
+** Replace the value at PATH with VALUE. If PATH does not already exist,
+** this routine is a no-op. If JSON or PATH is malformed, throw an error.
+*/
+static void jsonReplaceFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+
+ if( argc<1 ) return;
+ if( (argc&1)==0 ) {
+ jsonWrongNumArgs(ctx, "replace");
+ return;
+ }
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto replace_err;
+ if( pNode ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->u.iReplace = i + 1;
+ }
+ }
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
+replace_err:
+ jsonParseReset(&x);
+}
+
+/*
+** json_set(JSON, PATH, VALUE, ...)
+**
+** Set the value at PATH to VALUE. Create the PATH if it does not already
+** exist. Overwrite existing values that do exist.
+** If JSON or PATH is malformed, throw an error.
+**
+** json_insert(JSON, PATH, VALUE, ...)
+**
+** Create PATH and initialize it to VALUE. If PATH already exists, this
+** routine is a no-op. If JSON or PATH is malformed, throw an error.
+*/
+static void jsonSetFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The parse */
+ JsonNode *pNode;
+ const char *zPath;
+ u32 i;
+ int bApnd;
+ int bIsSet = *(int*)sqlite3_user_data(ctx);
+
+ if( argc<1 ) return;
+ if( (argc&1)==0 ) {
+ jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
+ return;
+ }
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ bApnd = 0;
+ pNode = jsonLookup(&x, zPath, &bApnd, ctx);
+ if( x.oom ){
+ sqlite3_result_error_nomem(ctx);
+ goto jsonSetDone;
+ }else if( x.nErr ){
+ goto jsonSetDone;
+ }else if( pNode && (bApnd || bIsSet) ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->u.iReplace = i + 1;
+ }
+ }
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
+jsonSetDone:
+ jsonParseReset(&x);
+}
+
+/*
+** json_type(JSON)
+** json_type(JSON, PATH)
+**
+** Return the top-level "type" of a JSON string. Throw an error if
+** either the JSON or PATH inputs are not well-formed.
+*/
+static void jsonTypeFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse *p; /* The parse */
+ const char *zPath;
+ JsonNode *pNode;
+
+ p = jsonParseCached(ctx, argv, ctx);
+ if( p==0 ) return;
+ if( argc==2 ){
+ zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(p, zPath, 0, ctx);
+ }else{
+ pNode = p->aNode;
+ }
+ if( pNode ){
+ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
+ }
+}
+
+/*
+** json_valid(JSON)
+**
+** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
+** Return 0 otherwise.
+*/
+static void jsonValidFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse *p; /* The parse */
+ UNUSED_PARAM(argc);
+ p = jsonParseCached(ctx, argv, 0);
+ sqlite3_result_int(ctx, p!=0);
+}
+
+
+/****************************************************************************
+** Aggregate SQL function implementations
+****************************************************************************/
+/*
+** json_group_array(VALUE)
+**
+** Return a JSON array composed of all values in the aggregate.
+*/
+static void jsonArrayStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ UNUSED_PARAM(argc);
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '[');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ jsonAppendValue(pStr, argv[0]);
+ }
+}
+static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ pStr->pCtx = ctx;
+ jsonAppendChar(pStr, ']');
+ if( pStr->bErr ){
+ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else if( isFinal ){
+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
+ pStr->nUsed--;
+ }
+ }else{
+ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+static void jsonArrayValue(sqlite3_context *ctx){
+ jsonArrayCompute(ctx, 0);
+}
+static void jsonArrayFinal(sqlite3_context *ctx){
+ jsonArrayCompute(ctx, 1);
+}
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** This method works for both json_group_array() and json_group_object().
+** It works by removing the first element of the group by searching forward
+** to the first comma (",") that is not within a string and deleting all
+** text through that comma.
+*/
+static void jsonGroupInverse(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ int i;
+ int inStr = 0;
+ char *z;
+ JsonString *pStr;
+ UNUSED_PARAM(argc);
+ UNUSED_PARAM(argv);
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+#ifdef NEVER
+ /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
+ ** always have been called to initalize it */
+ if( NEVER(!pStr) ) return;
+#endif
+ z = pStr->zBuf;
+ for(i=1; z[i]!=',' || inStr; i++){
+ assert( i<pStr->nUsed );
+ if( z[i]=='"' ){
+ inStr = !inStr;
+ }else if( z[i]=='\\' ){
+ i++;
+ }
+ }
+ pStr->nUsed -= i;
+ memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
+}
+#else
+# define jsonGroupInverse 0
+#endif
+
+
+/*
+** json_group_obj(NAME,VALUE)
+**
+** Return a JSON object composed of all names and values in the aggregate.
+*/
+static void jsonObjectStep(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString *pStr;
+ const char *z;
+ u32 n;
+ UNUSED_PARAM(argc);
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+ if( pStr ){
+ if( pStr->zBuf==0 ){
+ jsonInit(pStr, ctx);
+ jsonAppendChar(pStr, '{');
+ }else{
+ jsonAppendChar(pStr, ',');
+ pStr->pCtx = ctx;
+ }
+ z = (const char*)sqlite3_value_text(argv[0]);
+ n = (u32)sqlite3_value_bytes(argv[0]);
+ jsonAppendString(pStr, z, n);
+ jsonAppendChar(pStr, ':');
+ jsonAppendValue(pStr, argv[1]);
+ }
+}
+static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
+ JsonString *pStr;
+ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+ if( pStr ){
+ jsonAppendChar(pStr, '}');
+ if( pStr->bErr ){
+ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+ assert( pStr->bStatic );
+ }else if( isFinal ){
+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
+ pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+ pStr->bStatic = 1;
+ }else{
+ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
+ pStr->nUsed--;
+ }
+ }else{
+ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
+ }
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+}
+static void jsonObjectValue(sqlite3_context *ctx){
+ jsonObjectCompute(ctx, 0);
+}
+static void jsonObjectFinal(sqlite3_context *ctx){
+ jsonObjectCompute(ctx, 1);
+}
+
+
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/****************************************************************************
+** The json_each virtual table
+****************************************************************************/
+typedef struct JsonEachCursor JsonEachCursor;
+struct JsonEachCursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ u32 iRowid; /* The rowid */
+ u32 iBegin; /* The first node of the scan */
+ u32 i; /* Index in sParse.aNode[] of current row */
+ u32 iEnd; /* EOF when i equals or exceeds this value */
+ u8 eType; /* Type of top-level element */
+ u8 bRecursive; /* True for json_tree(). False for json_each() */
+ char *zJson; /* Input JSON */
+ char *zRoot; /* Path by which to filter zJson */
+ JsonParse sParse; /* Parse of the input JSON */
+};
+
+/* Constructor for the json_each virtual table */
+static int jsonEachConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ sqlite3_vtab *pNew;
+ int rc;
+
+/* Column numbers */
+#define JEACH_KEY 0
+#define JEACH_VALUE 1
+#define JEACH_TYPE 2
+#define JEACH_ATOM 3
+#define JEACH_ID 4
+#define JEACH_PARENT 5
+#define JEACH_FULLKEY 6
+#define JEACH_PATH 7
+#define JEACH_JSON 8
+#define JEACH_ROOT 9
+
+ UNUSED_PARAM(pzErr);
+ UNUSED_PARAM(argv);
+ UNUSED_PARAM(argc);
+ UNUSED_PARAM(pAux);
+ rc = sqlite3_declare_vtab(db,
+ "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
+ "json HIDDEN,root HIDDEN)");
+ if( rc==SQLITE_OK ){
+ pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ }
+ return rc;
+}
+
+/* destructor for json_each virtual table */
+static int jsonEachDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/* constructor for a JsonEachCursor object for json_each(). */
+static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ JsonEachCursor *pCur;
+
+ UNUSED_PARAM(p);
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/* constructor for a JsonEachCursor object for json_tree(). */
+static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ int rc = jsonEachOpenEach(p, ppCursor);
+ if( rc==SQLITE_OK ){
+ JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
+ pCur->bRecursive = 1;
+ }
+ return rc;
+}
+
+/* Reset a JsonEachCursor back to its original state. Free any memory
+** held. */
+static void jsonEachCursorReset(JsonEachCursor *p){
+ sqlite3_free(p->zJson);
+ sqlite3_free(p->zRoot);
+ jsonParseReset(&p->sParse);
+ p->iRowid = 0;
+ p->i = 0;
+ p->iEnd = 0;
+ p->eType = 0;
+ p->zJson = 0;
+ p->zRoot = 0;
+}
+
+/* Destructor for a jsonEachCursor object */
+static int jsonEachClose(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ jsonEachCursorReset(p);
+ sqlite3_free(cur);
+ return SQLITE_OK;
+}
+
+/* Return TRUE if the jsonEachCursor object has been advanced off the end
+** of the JSON object */
+static int jsonEachEof(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ return p->i >= p->iEnd;
+}
+
+/* Advance the cursor to the next element for json_tree() */
+static int jsonEachNext(sqlite3_vtab_cursor *cur){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ if( p->bRecursive ){
+ if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
+ p->i++;
+ p->iRowid++;
+ if( p->i<p->iEnd ){
+ u32 iUp = p->sParse.aUp[p->i];
+ JsonNode *pUp = &p->sParse.aNode[iUp];
+ p->eType = pUp->eType;
+ if( pUp->eType==JSON_ARRAY ){
+ if( iUp==p->i-1 ){
+ pUp->u.iKey = 0;
+ }else{
+ pUp->u.iKey++;
+ }
+ }
+ }
+ }else{
+ switch( p->eType ){
+ case JSON_ARRAY: {
+ p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
+ p->iRowid++;
+ break;
+ }
+ case JSON_OBJECT: {
+ p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
+ p->iRowid++;
+ break;
+ }
+ default: {
+ p->i = p->iEnd;
+ break;
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Append the name of the path for element i to pStr
+*/
+static void jsonEachComputePath(
+ JsonEachCursor *p, /* The cursor */
+ JsonString *pStr, /* Write the path here */
+ u32 i /* Path to this element */
+){
+ JsonNode *pNode, *pUp;
+ u32 iUp;
+ if( i==0 ){
+ jsonAppendChar(pStr, '$');
+ return;
+ }
+ iUp = p->sParse.aUp[i];
+ jsonEachComputePath(p, pStr, iUp);
+ pNode = &p->sParse.aNode[i];
+ pUp = &p->sParse.aNode[iUp];
+ if( pUp->eType==JSON_ARRAY ){
+ jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
+ }else{
+ assert( pUp->eType==JSON_OBJECT );
+ if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
+ assert( pNode->eType==JSON_STRING );
+ assert( pNode->jnFlags & JNODE_LABEL );
+ jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
+ }
+}
+
+/* Return the value of a column */
+static int jsonEachColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ JsonNode *pThis = &p->sParse.aNode[p->i];
+ switch( i ){
+ case JEACH_KEY: {
+ if( p->i==0 ) break;
+ if( p->eType==JSON_OBJECT ){
+ jsonReturn(pThis, ctx, 0);
+ }else if( p->eType==JSON_ARRAY ){
+ u32 iKey;
+ if( p->bRecursive ){
+ if( p->iRowid==0 ) break;
+ iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
+ }else{
+ iKey = p->iRowid;
+ }
+ sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
+ }
+ break;
+ }
+ case JEACH_VALUE: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ jsonReturn(pThis, ctx, 0);
+ break;
+ }
+ case JEACH_TYPE: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
+ break;
+ }
+ case JEACH_ATOM: {
+ if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+ if( pThis->eType>=JSON_ARRAY ) break;
+ jsonReturn(pThis, ctx, 0);
+ break;
+ }
+ case JEACH_ID: {
+ sqlite3_result_int64(ctx,
+ (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
+ break;
+ }
+ case JEACH_PARENT: {
+ if( p->i>p->iBegin && p->bRecursive ){
+ sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
+ }
+ break;
+ }
+ case JEACH_FULLKEY: {
+ JsonString x;
+ jsonInit(&x, ctx);
+ if( p->bRecursive ){
+ jsonEachComputePath(p, &x, p->i);
+ }else{
+ if( p->zRoot ){
+ jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
+ }else{
+ jsonAppendChar(&x, '$');
+ }
+ if( p->eType==JSON_ARRAY ){
+ jsonPrintf(30, &x, "[%d]", p->iRowid);
+ }else if( p->eType==JSON_OBJECT ){
+ jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
+ }
+ }
+ jsonResult(&x);
+ break;
+ }
+ case JEACH_PATH: {
+ if( p->bRecursive ){
+ JsonString x;
+ jsonInit(&x, ctx);
+ jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
+ jsonResult(&x);
+ break;
+ }
+ /* For json_each() path and root are the same so fall through
+ ** into the root case */
+ }
+ default: {
+ const char *zRoot = p->zRoot;
+ if( zRoot==0 ) zRoot = "$";
+ sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
+ break;
+ }
+ case JEACH_JSON: {
+ assert( i==JEACH_JSON );
+ sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Return the current rowid value */
+static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ *pRowid = p->iRowid;
+ return SQLITE_OK;
+}
+
+/* The query strategy is to look for an equality constraint on the json
+** column. Without such a constraint, the table cannot operate. idxNum is
+** 1 if the constraint is found, 3 if the constraint and zRoot are found,
+** and 0 otherwise.
+*/
+static int jsonEachBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i;
+ int jsonIdx = -1;
+ int rootIdx = -1;
+ const struct sqlite3_index_constraint *pConstraint;
+
+ UNUSED_PARAM(tab);
+ pConstraint = pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ switch( pConstraint->iColumn ){
+ case JEACH_JSON: jsonIdx = i; break;
+ case JEACH_ROOT: rootIdx = i; break;
+ default: /* no-op */ break;
+ }
+ }
+ if( jsonIdx<0 ){
+ pIdxInfo->idxNum = 0;
+ pIdxInfo->estimatedCost = 1e99;
+ }else{
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
+ if( rootIdx<0 ){
+ pIdxInfo->idxNum = 1;
+ }else{
+ pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
+ pIdxInfo->idxNum = 3;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* Start a search on a new JSON string */
+static int jsonEachFilter(
+ sqlite3_vtab_cursor *cur,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ JsonEachCursor *p = (JsonEachCursor*)cur;
+ const char *z;
+ const char *zRoot = 0;
+ size_t n;
+
+ UNUSED_PARAM(idxStr);
+ UNUSED_PARAM(argc);
+ jsonEachCursorReset(p);
+ if( idxNum==0 ) return SQLITE_OK;
+ z = (const char*)sqlite3_value_text(argv[0]);
+ if( z==0 ) return SQLITE_OK;
+ n = (size_t)sqlite3_value_bytes(argv[0]);
+ p->zJson = sqlite3_malloc( n+1 );
+ if( p->zJson==0 ) return SQLITE_NOMEM;
+ memcpy(p->zJson, z, n+1);
+ if( jsonParse(&p->sParse, 0, p->zJson) ){
+ int rc = SQLITE_NOMEM;
+ if( p->sParse.oom==0 ){
+ sqlite3_free(cur->pVtab->zErrMsg);
+ cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
+ if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
+ }
+ jsonEachCursorReset(p);
+ return rc;
+ }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
+ jsonEachCursorReset(p);
+ return SQLITE_NOMEM;
+ }else{
+ JsonNode *pNode = 0;
+ if( idxNum==3 ){
+ const char *zErr = 0;
+ zRoot = (const char*)sqlite3_value_text(argv[1]);
+ if( zRoot==0 ) return SQLITE_OK;
+ n = (size_t)sqlite3_value_bytes(argv[1]);
+ p->zRoot = sqlite3_malloc( n+1 );
+ if( p->zRoot==0 ) return SQLITE_NOMEM;
+ memcpy(p->zRoot, zRoot, n+1);
+ if( zRoot[0]!='$' ){
+ zErr = zRoot;
+ }else{
+ pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
+ }
+ if( zErr ){
+ sqlite3_free(cur->pVtab->zErrMsg);
+ cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
+ jsonEachCursorReset(p);
+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ }else if( pNode==0 ){
+ return SQLITE_OK;
+ }
+ }else{
+ pNode = p->sParse.aNode;
+ }
+ p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
+ p->eType = pNode->eType;
+ if( p->eType>=JSON_ARRAY ){
+ pNode->u.iKey = 0;
+ p->iEnd = p->i + pNode->n + 1;
+ if( p->bRecursive ){
+ p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
+ if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
+ p->i--;
+ }
+ }else{
+ p->i++;
+ }
+ }else{
+ p->iEnd = p->i+1;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/* The methods of the json_each virtual table */
+static const sqlite3_module jsonEachModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ jsonEachConnect, /* xConnect */
+ jsonEachBestIndex, /* xBestIndex */
+ jsonEachDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ jsonEachOpenEach, /* xOpen - open a cursor */
+ jsonEachClose, /* xClose - close a cursor */
+ jsonEachFilter, /* xFilter - configure scan constraints */
+ jsonEachNext, /* xNext - advance a cursor */
+ jsonEachEof, /* xEof - check for end of scan */
+ jsonEachColumn, /* xColumn - read data */
+ jsonEachRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+
+/* The methods of the json_tree virtual table. */
+static const sqlite3_module jsonTreeModule = {
+ 0, /* iVersion */
+ 0, /* xCreate */
+ jsonEachConnect, /* xConnect */
+ jsonEachBestIndex, /* xBestIndex */
+ jsonEachDisconnect, /* xDisconnect */
+ 0, /* xDestroy */
+ jsonEachOpenTree, /* xOpen - open a cursor */
+ jsonEachClose, /* xClose - close a cursor */
+ jsonEachFilter, /* xFilter - configure scan constraints */
+ jsonEachNext, /* xNext - advance a cursor */
+ jsonEachEof, /* xEof - check for end of scan */
+ jsonEachColumn, /* xColumn - read data */
+ jsonEachRowid, /* xRowid - read data */
+ 0, /* xUpdate */
+ 0, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/****************************************************************************
+** The following routines are the only publically visible identifiers in this
+** file. Call the following routines in order to register the various SQL
+** functions and the virtual table implemented by this file.
+****************************************************************************/
+
+SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
+ int rc = SQLITE_OK;
+ unsigned int i;
+ static const struct {
+ const char *zName;
+ int nArg;
+ int flag;
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+ } aFunc[] = {
+ { "json", 1, 0, jsonRemoveFunc },
+ { "json_array", -1, 0, jsonArrayFunc },
+ { "json_array_length", 1, 0, jsonArrayLengthFunc },
+ { "json_array_length", 2, 0, jsonArrayLengthFunc },
+ { "json_extract", -1, 0, jsonExtractFunc },
+ { "json_insert", -1, 0, jsonSetFunc },
+ { "json_object", -1, 0, jsonObjectFunc },
+ { "json_patch", 2, 0, jsonPatchFunc },
+ { "json_quote", 1, 0, jsonQuoteFunc },
+ { "json_remove", -1, 0, jsonRemoveFunc },
+ { "json_replace", -1, 0, jsonReplaceFunc },
+ { "json_set", -1, 1, jsonSetFunc },
+ { "json_type", 1, 0, jsonTypeFunc },
+ { "json_type", 2, 0, jsonTypeFunc },
+ { "json_valid", 1, 0, jsonValidFunc },
+
+#if SQLITE_DEBUG
+ /* DEBUG and TESTING functions */
+ { "json_parse", 1, 0, jsonParseFunc },
+ { "json_test1", 1, 0, jsonTest1Func },
+#endif
+ };
+ static const struct {
+ const char *zName;
+ int nArg;
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+ void (*xFinal)(sqlite3_context*);
+ void (*xValue)(sqlite3_context*);
+ } aAgg[] = {
+ { "json_group_array", 1,
+ jsonArrayStep, jsonArrayFinal, jsonArrayValue },
+ { "json_group_object", 2,
+ jsonObjectStep, jsonObjectFinal, jsonObjectValue },
+ };
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ static const struct {
+ const char *zName;
+ const sqlite3_module *pModule;
+ } aMod[] = {
+ { "json_each", &jsonEachModule },
+ { "json_tree", &jsonTreeModule },
+ };
+#endif
+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC,
+ (void*)&aFunc[i].flag,
+ aFunc[i].xFunc, 0, 0);
+ }
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
+ SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+ aAgg[i].xStep, aAgg[i].xFinal,
+ aAgg[i].xValue, jsonGroupInverse, 0);
+ }
+#endif
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+ }
+#endif
+ return rc;
+}
+
+
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_json_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return sqlite3Json1Init(db);
+}
+#endif
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
+
+/************** End of json1.c ***********************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
@@ -165976,14 +178542,15 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
**
** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
-** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
+** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
**
** The data for each node of the r-tree structure is stored in the %_node
** table. For each node that is not the root node of the r-tree, there is
** an entry in the %_parent table associating the node with its parent.
** And for each row of data in the table, there is an entry in the %_rowid
** table that maps from the entries rowid to the id of the node that it
-** is stored on.
+** is stored on. If the r-tree contains auxiliary columns, those are stored
+** on the end of the %_rowid table.
**
** The root node of an r-tree always exists, even if the r-tree table is
** empty. The nodeno of the root node is always 1. All other nodes in the
@@ -166004,7 +178571,8 @@ static int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
** child page.
*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
+#if !defined(SQLITE_CORE) \
+ || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
#ifndef SQLITE_CORE
/* #include "sqlite3ext.h" */
@@ -166045,6 +178613,9 @@ typedef struct RtreeSearchPoint RtreeSearchPoint;
/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
#define RTREE_MAX_DIMENSIONS 5
+/* Maximum number of auxiliary columns */
+#define RTREE_MAX_AUX_COLUMN 100
+
/* Size of hash table Rtree.aHash. This hash table is not expected to
** ever contain very many entries, so a fixed number of buckets is
** used.
@@ -166073,12 +178644,16 @@ struct Rtree {
u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
u8 nBytesPerCell; /* Bytes consumed per cell */
u8 inWrTrans; /* True if inside write transaction */
+ u8 nAux; /* # of auxiliary columns in %_rowid */
+ u8 nAuxNotNull; /* Number of initial not-null aux columns */
int iDepth; /* Current depth of the r-tree structure */
char *zDb; /* Name of database containing r-tree table */
char *zName; /* Name of r-tree table */
u32 nBusy; /* Current number of users of this structure */
i64 nRowEst; /* Estimated number of rows in this table */
u32 nCursor; /* Number of open cursors */
+ u32 nNodeRef; /* Number RtreeNodes with positive nRef */
+ char *zReadAuxSql; /* SQL for statement to read aux data */
/* List of nodes removed during a CondenseTree operation. List is
** linked together via the pointer normally used for hash chains -
@@ -166105,6 +178680,9 @@ struct Rtree {
sqlite3_stmt *pWriteParent;
sqlite3_stmt *pDeleteParent;
+ /* Statement for writing to the "aux:" fields, if there are any */
+ sqlite3_stmt *pWriteAux;
+
RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
};
@@ -166161,7 +178739,7 @@ struct RtreeSearchPoint {
** The smallest possible node-size is (512-64)==448 bytes. And the largest
** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
** Therefore all non-root nodes must contain at least 3 entries. Since
-** 2^40 is greater than 2^64, an r-tree structure always has a depth of
+** 3^40 is greater than 2^64, an r-tree structure always has a depth of
** 40 or less.
*/
#define RTREE_MAX_DEPTH 40
@@ -166181,6 +178759,7 @@ struct RtreeCursor {
sqlite3_vtab_cursor base; /* Base class. Must be first */
u8 atEOF; /* True if at end of search */
u8 bPoint; /* True if sPoint is valid */
+ u8 bAuxValid; /* True if pReadAux is valid */
int iStrategy; /* Copy of idxNum search parameter */
int nConstraint; /* Number of entries in aConstraint */
RtreeConstraint *aConstraint; /* Search constraints. */
@@ -166188,6 +178767,7 @@ struct RtreeCursor {
int nPoint; /* Number of slots used in aPoint[] */
int mxLevel; /* iLevel value for root of the tree */
RtreeSearchPoint *aPoint; /* Priority queue for search points */
+ sqlite3_stmt *pReadAux; /* Statement to read aux-data */
RtreeSearchPoint sPoint; /* Cached next search point */
RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */
u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */
@@ -166474,6 +179054,7 @@ static int writeInt64(u8 *p, i64 i){
*/
static void nodeReference(RtreeNode *p){
if( p ){
+ assert( p->nRef>0 );
p->nRef++;
}
}
@@ -166541,6 +179122,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
pNode->zData = (u8 *)&pNode[1];
pNode->nRef = 1;
+ pRtree->nNodeRef++;
pNode->pParent = pParent;
pNode->isDirty = 1;
nodeReference(pParent);
@@ -166574,10 +179156,10 @@ static int nodeAcquire(
/* Check if the requested node is already in the hash table. If so,
** increase its reference count and return it.
*/
- if( (pNode = nodeHashLookup(pRtree, iNode)) ){
+ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
if( pParent && !pNode->pParent ){
- nodeReference(pParent);
+ pParent->nRef++;
pNode->pParent = pParent;
}
pNode->nRef++;
@@ -166616,6 +179198,7 @@ static int nodeAcquire(
pNode->pParent = pParent;
pNode->zData = (u8 *)&pNode[1];
pNode->nRef = 1;
+ pRtree->nNodeRef++;
pNode->iNode = iNode;
pNode->isDirty = 0;
pNode->pNext = 0;
@@ -166656,7 +179239,10 @@ static int nodeAcquire(
}
*ppNode = pNode;
}else{
- sqlite3_free(pNode);
+ if( pNode ){
+ pRtree->nNodeRef--;
+ sqlite3_free(pNode);
+ }
*ppNode = 0;
}
@@ -166736,6 +179322,7 @@ static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){
sqlite3_step(p);
pNode->isDirty = 0;
rc = sqlite3_reset(p);
+ sqlite3_bind_null(p, 2);
if( pNode->iNode==0 && rc==SQLITE_OK ){
pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
nodeHashInsert(pRtree, pNode);
@@ -166752,8 +179339,10 @@ static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){
int rc = SQLITE_OK;
if( pNode ){
assert( pNode->nRef>0 );
+ assert( pRtree->nNodeRef>0 );
pNode->nRef--;
if( pNode->nRef==0 ){
+ pRtree->nNodeRef--;
if( pNode->iNode==1 ){
pRtree->iDepth = -1;
}
@@ -166870,8 +179459,9 @@ static void rtreeRelease(Rtree *pRtree){
pRtree->nBusy--;
if( pRtree->nBusy==0 ){
pRtree->inWrTrans = 0;
- pRtree->nCursor = 0;
+ assert( pRtree->nCursor==0 );
nodeBlobReset(pRtree);
+ assert( pRtree->nNodeRef==0 );
sqlite3_finalize(pRtree->pWriteNode);
sqlite3_finalize(pRtree->pDeleteNode);
sqlite3_finalize(pRtree->pReadRowid);
@@ -166880,6 +179470,8 @@ static void rtreeRelease(Rtree *pRtree){
sqlite3_finalize(pRtree->pReadParent);
sqlite3_finalize(pRtree->pWriteParent);
sqlite3_finalize(pRtree->pDeleteParent);
+ sqlite3_finalize(pRtree->pWriteAux);
+ sqlite3_free(pRtree->zReadAuxSql);
sqlite3_free(pRtree);
}
}
@@ -166968,6 +179560,7 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
RtreeCursor *pCsr = (RtreeCursor *)cur;
assert( pRtree->nCursor>0 );
freeCursorConstraints(pCsr);
+ sqlite3_finalize(pCsr->pReadAux);
sqlite3_free(pCsr->aPoint);
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr);
@@ -167339,7 +179932,7 @@ static RtreeSearchPoint *rtreeSearchPointNew(
if( ii<RTREE_CACHE_SZ ){
assert( pCur->aNode[ii]==0 );
pCur->aNode[ii] = pCur->aNode[0];
- }else{
+ }else{
nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
}
pCur->aNode[0] = 0;
@@ -167510,6 +180103,10 @@ static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
/* Move to the next entry that matches the configured constraints. */
RTREE_QUEUE_TRACE(pCsr, "POP-Nx:");
+ if( pCsr->bAuxValid ){
+ pCsr->bAuxValid = 0;
+ sqlite3_reset(pCsr->pReadAux);
+ }
rtreeSearchPointPop(pCsr);
rc = rtreeStepToLeaf(pCsr);
return rc;
@@ -167544,7 +180141,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
if( p==0 ) return SQLITE_OK;
if( i==0 ){
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
- }else{
+ }else if( i<=pRtree->nDim2 ){
nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
@@ -167555,7 +180152,27 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
assert( pRtree->eCoordType==RTREE_COORD_INT32 );
sqlite3_result_int(ctx, c.i);
}
- }
+ }else{
+ if( !pCsr->bAuxValid ){
+ if( pCsr->pReadAux==0 ){
+ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
+ &pCsr->pReadAux, 0);
+ if( rc ) return rc;
+ }
+ sqlite3_bind_int64(pCsr->pReadAux, 1,
+ nodeGetRowid(pRtree, pNode, p->iCell));
+ rc = sqlite3_step(pCsr->pReadAux);
+ if( rc==SQLITE_ROW ){
+ pCsr->bAuxValid = 1;
+ }else{
+ sqlite3_reset(pCsr->pReadAux);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+ }
+ }
+ sqlite3_result_value(ctx,
+ sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1));
+ }
return SQLITE_OK;
}
@@ -167633,14 +180250,17 @@ static int rtreeFilter(
int ii;
int rc = SQLITE_OK;
int iCell = 0;
+ sqlite3_stmt *pStmt;
rtreeReference(pRtree);
/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
freeCursorConstraints(pCsr);
sqlite3_free(pCsr->aPoint);
+ pStmt = pCsr->pReadAux;
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
+ pCsr->pReadAux = pStmt;
pCsr->iStrategy = idxNum;
if( idxNum==1 ){
@@ -167803,10 +180423,14 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
*/
pIdxInfo->estimatedCost = 30.0;
pIdxInfo->estimatedRows = 1;
+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
return SQLITE_OK;
}
- if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
+ if( p->usable
+ && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
+ || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
+ ){
u8 op;
switch( p->op ){
case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
@@ -167973,7 +180597,7 @@ static int ChooseLeaf(
){
int rc;
int ii;
- RtreeNode *pNode;
+ RtreeNode *pNode = 0;
rc = nodeAcquire(pRtree, 1, 0, &pNode);
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
@@ -168379,7 +181003,7 @@ static int SplitNode(
}else{
pLeft = pNode;
pRight = nodeNew(pRtree, pLeft->pParent);
- nodeReference(pLeft);
+ pLeft->nRef++;
}
if( !pLeft || !pRight ){
@@ -168788,7 +181412,7 @@ static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
/*
** Select a currently unused rowid for a new r-tree record.
*/
-static int newRowid(Rtree *pRtree, i64 *piRowid){
+static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){
int rc;
sqlite3_bind_null(pRtree->pWriteRowid, 1);
sqlite3_bind_null(pRtree->pWriteRowid, 2);
@@ -168848,7 +181472,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
*/
if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
int rc2;
- RtreeNode *pChild;
+ RtreeNode *pChild = 0;
i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
if( rc==SQLITE_OK ){
@@ -168869,6 +181493,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
rc = reinsertNodeContent(pRtree, pLeaf);
}
pRtree->pDeleted = pLeaf->pNext;
+ pRtree->nNodeRef--;
sqlite3_free(pLeaf);
}
@@ -168965,7 +181590,7 @@ static int rtreeConstraintError(Rtree *pRtree, int iCol){
static int rtreeUpdate(
sqlite3_vtab *pVtab,
int nData,
- sqlite3_value **azData,
+ sqlite3_value **aData,
sqlite_int64 *pRowid
){
Rtree *pRtree = (Rtree *)pVtab;
@@ -168973,6 +181598,12 @@ static int rtreeUpdate(
RtreeCell cell; /* New cell to insert if nData>1 */
int bHaveRowid = 0; /* Set to 1 after new rowid is determined */
+ if( pRtree->nNodeRef ){
+ /* Unable to write to the btree while another cursor is reading from it,
+ ** since the write might do a rebalance which would disrupt the read
+ ** cursor. */
+ return SQLITE_LOCKED_VTAB;
+ }
rtreeReference(pRtree);
assert(nData>=1);
@@ -168991,8 +181622,10 @@ static int rtreeUpdate(
*/
if( nData>1 ){
int ii;
+ int nn = nData - 4;
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
+ if( nn > pRtree->nDim2 ) nn = pRtree->nDim2;
+ /* Populate the cell.aCoord[] array. The first coordinate is aData[3].
**
** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
** with "column" that are interpreted as table constraints.
@@ -169000,13 +181633,12 @@ static int rtreeUpdate(
** This problem was discovered after years of use, so we silently ignore
** these kinds of misdeclared tables to avoid breaking any legacy.
*/
- assert( nData<=(pRtree->nDim2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<nData-4; ii+=2){
- cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
- cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
+ for(ii=0; ii<nn; ii+=2){
+ cell.aCoord[ii].f = rtreeValueDown(aData[ii+3]);
+ cell.aCoord[ii+1].f = rtreeValueUp(aData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = rtreeConstraintError(pRtree, ii+1);
goto constraint;
@@ -169015,9 +181647,9 @@ static int rtreeUpdate(
}else
#endif
{
- for(ii=0; ii<nData-4; ii+=2){
- cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
- cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
+ for(ii=0; ii<nn; ii+=2){
+ cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]);
+ cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
rc = rtreeConstraintError(pRtree, ii+1);
goto constraint;
@@ -169027,10 +181659,10 @@ static int rtreeUpdate(
/* If a rowid value was supplied, check if it is already present in
** the table. If so, the constraint has failed. */
- if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){
- cell.iRowid = sqlite3_value_int64(azData[2]);
- if( sqlite3_value_type(azData[0])==SQLITE_NULL
- || sqlite3_value_int64(azData[0])!=cell.iRowid
+ if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){
+ cell.iRowid = sqlite3_value_int64(aData[2]);
+ if( sqlite3_value_type(aData[0])==SQLITE_NULL
+ || sqlite3_value_int64(aData[0])!=cell.iRowid
){
int steprc;
sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
@@ -169049,16 +181681,16 @@ static int rtreeUpdate(
}
}
- /* If azData[0] is not an SQL NULL value, it is the rowid of a
+ /* If aData[0] is not an SQL NULL value, it is the rowid of a
** record to delete from the r-tree table. The following block does
** just that.
*/
- if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
- rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0]));
+ if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){
+ rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0]));
}
- /* If the azData[] array contains more than one element, elements
- ** (azData[2]..azData[argc-1]) contain a new record to insert into
+ /* If the aData[] array contains more than one element, elements
+ ** (aData[2]..aData[argc-1]) contain a new record to insert into
** the r-tree structure.
*/
if( rc==SQLITE_OK && nData>1 ){
@@ -169067,7 +181699,7 @@ static int rtreeUpdate(
/* Figure out the rowid of the new row. */
if( bHaveRowid==0 ){
- rc = newRowid(pRtree, &cell.iRowid);
+ rc = rtreeNewRowid(pRtree, &cell.iRowid);
}
*pRowid = cell.iRowid;
@@ -169083,6 +181715,16 @@ static int rtreeUpdate(
rc = rc2;
}
}
+ if( pRtree->nAux ){
+ sqlite3_stmt *pUp = pRtree->pWriteAux;
+ int jj;
+ sqlite3_bind_int64(pUp, 1, *pRowid);
+ for(jj=0; jj<pRtree->nAux; jj++){
+ sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
+ }
+ sqlite3_step(pUp);
+ rc = sqlite3_reset(pUp);
+ }
}
constraint:
@@ -169149,7 +181791,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
*/
static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
Rtree *pRtree = (Rtree *)pVtab;
- int iwt = pRtree->inWrTrans;
+ u8 iwt = pRtree->inWrTrans;
UNUSED_PARAMETER(iSavepoint);
pRtree->inWrTrans = 0;
nodeBlobReset(pRtree);
@@ -169239,18 +181881,18 @@ static int rtreeSqlInit(
#define N_STATEMENT 8
static const char *const azSql[N_STATEMENT] = {
/* Write the xxx_node table */
- "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
+ "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)",
+ "DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1",
/* Read and write the xxx_rowid table */
- "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
+ "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = ?1",
+ "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(?1, ?2)",
+ "DELETE FROM '%q'.'%q_rowid' WHERE rowid = ?1",
/* Read and write the xxx_parent table */
- "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
+ "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
+ "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
+ "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
};
sqlite3_stmt **appStmt[N_STATEMENT];
int i;
@@ -169258,14 +181900,25 @@ static int rtreeSqlInit(
pRtree->db = db;
if( isCreate ){
- char *zCreate = sqlite3_mprintf(
-"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
-"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
-"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,"
- " parentnode INTEGER);"
-"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
- zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
- );
+ char *zCreate;
+ sqlite3_str *p = sqlite3_str_new(db);
+ int ii;
+ sqlite3_str_appendf(p,
+ "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno",
+ zDb, zPrefix);
+ for(ii=0; ii<pRtree->nAux; ii++){
+ sqlite3_str_appendf(p,",a%d",ii);
+ }
+ sqlite3_str_appendf(p,
+ ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);",
+ zDb, zPrefix);
+ sqlite3_str_appendf(p,
+ "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);",
+ zDb, zPrefix);
+ sqlite3_str_appendf(p,
+ "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))",
+ zDb, zPrefix, pRtree->iNodeSize);
+ zCreate = sqlite3_str_finish(p);
if( !zCreate ){
return SQLITE_NOMEM;
}
@@ -169287,7 +181940,17 @@ static int rtreeSqlInit(
rc = rtreeQueryStat1(db, pRtree);
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
- char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
+ char *zSql;
+ const char *zFormat;
+ if( i!=3 || pRtree->nAux==0 ){
+ zFormat = azSql[i];
+ }else {
+ /* An UPSERT is very slightly slower than REPLACE, but it is needed
+ ** if there are auxiliary columns */
+ zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
+ "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
+ }
+ zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
if( zSql ){
rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
appStmt[i], 0);
@@ -169296,6 +181959,36 @@ static int rtreeSqlInit(
}
sqlite3_free(zSql);
}
+ if( pRtree->nAux ){
+ pRtree->zReadAuxSql = sqlite3_mprintf(
+ "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1",
+ zDb, zPrefix);
+ if( pRtree->zReadAuxSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_str *p = sqlite3_str_new(db);
+ int ii;
+ char *zSql;
+ sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
+ for(ii=0; ii<pRtree->nAux; ii++){
+ if( ii ) sqlite3_str_append(p, ",", 1);
+ if( ii<pRtree->nAuxNotNull ){
+ sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
+ }else{
+ sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
+ }
+ }
+ sqlite3_str_appendf(p, " WHERE rowid=?1");
+ zSql = sqlite3_str_finish(p);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
+ &pRtree->pWriteAux, 0);
+ sqlite3_free(zSql);
+ }
+ }
+ }
return rc;
}
@@ -169398,17 +182091,22 @@ static int rtreeInit(
int nDb; /* Length of string argv[1] */
int nName; /* Length of string argv[2] */
int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32);
+ sqlite3_str *pSql;
+ char *zSql;
+ int ii = 4;
+ int iErr;
const char *const aErrMsg[] = {
0, /* 0 */
"Wrong number of columns for an rtree table", /* 1 */
"Too few columns for an rtree table", /* 2 */
- "Too many columns for an rtree table" /* 3 */
+ "Too many columns for an rtree table", /* 3 */
+ "Auxiliary rtree columns must be last" /* 4 */
};
- int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
- if( aErrMsg[iErr] ){
- *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
+ assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */
+ if( argc>RTREE_MAX_AUX_COLUMN+3 ){
+ *pzErr = sqlite3_mprintf("%s", aErrMsg[3]);
return SQLITE_ERROR;
}
@@ -169426,53 +182124,73 @@ static int rtreeInit(
pRtree->base.pModule = &rtreeModule;
pRtree->zDb = (char *)&pRtree[1];
pRtree->zName = &pRtree->zDb[nDb+1];
- pRtree->nDim = (u8)((argc-4)/2);
- pRtree->nDim2 = pRtree->nDim*2;
- pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
pRtree->eCoordType = (u8)eCoordType;
memcpy(pRtree->zDb, argv[1], nDb);
memcpy(pRtree->zName, argv[2], nName);
- /* Figure out the node size to use. */
- rc = getNodeSize(db, pRtree, isCreate, pzErr);
/* Create/Connect to the underlying relational database schema. If
** that is successful, call sqlite3_declare_vtab() to configure
** the r-tree table schema.
*/
- if( rc==SQLITE_OK ){
- if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ pSql = sqlite3_str_new(db);
+ sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
+ for(ii=4; ii<argc; ii++){
+ if( argv[ii][0]=='+' ){
+ pRtree->nAux++;
+ sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
+ }else if( pRtree->nAux>0 ){
+ break;
}else{
- char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
- char *zTmp;
- int ii;
- for(ii=4; zSql && ii<argc; ii++){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
- sqlite3_free(zTmp);
- }
- if( zSql ){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s);", zTmp);
- sqlite3_free(zTmp);
- }
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }
- sqlite3_free(zSql);
+ pRtree->nDim2++;
+ sqlite3_str_appendf(pSql, ",%s", argv[ii]);
}
}
+ sqlite3_str_appendf(pSql, ");");
+ zSql = sqlite3_str_finish(pSql);
+ if( !zSql ){
+ rc = SQLITE_NOMEM;
+ }else if( ii<argc ){
+ *pzErr = sqlite3_mprintf("%s", aErrMsg[4]);
+ rc = SQLITE_ERROR;
+ }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+ sqlite3_free(zSql);
+ if( rc ) goto rtreeInit_fail;
+ pRtree->nDim = pRtree->nDim2/2;
+ if( pRtree->nDim<1 ){
+ iErr = 2;
+ }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){
+ iErr = 3;
+ }else if( pRtree->nDim2 % 2 ){
+ iErr = 1;
+ }else{
+ iErr = 0;
+ }
+ if( iErr ){
+ *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
+ goto rtreeInit_fail;
+ }
+ pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
- if( rc==SQLITE_OK ){
- *ppVtab = (sqlite3_vtab *)pRtree;
- }else{
- assert( *ppVtab==0 );
- assert( pRtree->nBusy==1 );
- rtreeRelease(pRtree);
+ /* Figure out the node size to use. */
+ rc = getNodeSize(db, pRtree, isCreate, pzErr);
+ if( rc ) goto rtreeInit_fail;
+ rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
+ if( rc ){
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ goto rtreeInit_fail;
}
+
+ *ppVtab = (sqlite3_vtab *)pRtree;
+ return SQLITE_OK;
+
+rtreeInit_fail:
+ if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
+ assert( *ppVtab==0 );
+ assert( pRtree->nBusy==1 );
+ rtreeRelease(pRtree);
return rc;
}
@@ -169561,6 +182279,2141 @@ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
}
/*
+** Context object passed between the various routines that make up the
+** implementation of integrity-check function rtreecheck().
+*/
+typedef struct RtreeCheck RtreeCheck;
+struct RtreeCheck {
+ sqlite3 *db; /* Database handle */
+ const char *zDb; /* Database containing rtree table */
+ const char *zTab; /* Name of rtree table */
+ int bInt; /* True for rtree_i32 table */
+ int nDim; /* Number of dimensions for this rtree tbl */
+ sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */
+ sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */
+ int nLeaf; /* Number of leaf cells in table */
+ int nNonLeaf; /* Number of non-leaf cells in table */
+ int rc; /* Return code */
+ char *zReport; /* Message to report */
+ int nErr; /* Number of lines in zReport */
+};
+
+#define RTREE_CHECK_MAX_ERROR 100
+
+/*
+** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error,
+** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code.
+*/
+static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){
+ int rc = sqlite3_reset(pStmt);
+ if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc;
+}
+
+/*
+** The second and subsequent arguments to this function are a format string
+** and printf style arguments. This function formats the string and attempts
+** to compile it as an SQL statement.
+**
+** If successful, a pointer to the new SQL statement is returned. Otherwise,
+** NULL is returned and an error code left in RtreeCheck.rc.
+*/
+static sqlite3_stmt *rtreeCheckPrepare(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ const char *zFmt, ... /* Format string and trailing args */
+){
+ va_list ap;
+ char *z;
+ sqlite3_stmt *pRet = 0;
+
+ va_start(ap, zFmt);
+ z = sqlite3_vmprintf(zFmt, ap);
+
+ if( pCheck->rc==SQLITE_OK ){
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0);
+ }
+ }
+
+ sqlite3_free(z);
+ va_end(ap);
+ return pRet;
+}
+
+/*
+** The second and subsequent arguments to this function are a printf()
+** style format string and arguments. This function formats the string and
+** appends it to the report being accumuated in pCheck.
+*/
+static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){
+ char *z = sqlite3_vmprintf(zFmt, ap);
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ pCheck->zReport = sqlite3_mprintf("%z%s%z",
+ pCheck->zReport, (pCheck->zReport ? "\n" : ""), z
+ );
+ if( pCheck->zReport==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }
+ }
+ pCheck->nErr++;
+ }
+ va_end(ap);
+}
+
+/*
+** This function is a no-op if there is already an error code stored
+** in the RtreeCheck object indicated by the first argument. NULL is
+** returned in this case.
+**
+** Otherwise, the contents of rtree table node iNode are loaded from
+** the database and copied into a buffer obtained from sqlite3_malloc().
+** If no error occurs, a pointer to the buffer is returned and (*pnNode)
+** is set to the size of the buffer in bytes.
+**
+** Or, if an error does occur, NULL is returned and an error code left
+** in the RtreeCheck object. The final value of *pnNode is undefined in
+** this case.
+*/
+static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
+ u8 *pRet = 0; /* Return value */
+
+ assert( pCheck->rc==SQLITE_OK );
+ if( pCheck->pGetNode==0 ){
+ pCheck->pGetNode = rtreeCheckPrepare(pCheck,
+ "SELECT data FROM %Q.'%q_node' WHERE nodeno=?",
+ pCheck->zDb, pCheck->zTab
+ );
+ }
+
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_bind_int64(pCheck->pGetNode, 1, iNode);
+ if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
+ int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
+ const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
+ pRet = sqlite3_malloc(nNode);
+ if( pRet==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pRet, pNode, nNode);
+ *pnNode = nNode;
+ }
+ }
+ rtreeCheckReset(pCheck, pCheck->pGetNode);
+ if( pCheck->rc==SQLITE_OK && pRet==0 ){
+ rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode);
+ }
+ }
+
+ return pRet;
+}
+
+/*
+** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
+** (if bLeaf==1) table contains a specified entry. The schemas of the
+** two tables are:
+**
+** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
+**
+** In both cases, this function checks that there exists an entry with
+** IPK value iKey and the second column set to iVal.
+**
+*/
+static void rtreeCheckMapping(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ int bLeaf, /* True for a leaf cell, false for interior */
+ i64 iKey, /* Key for mapping */
+ i64 iVal /* Expected value for mapping */
+){
+ int rc;
+ sqlite3_stmt *pStmt;
+ const char *azSql[2] = {
+ "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1",
+ "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1"
+ };
+
+ assert( bLeaf==0 || bLeaf==1 );
+ if( pCheck->aCheckMapping[bLeaf]==0 ){
+ pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck,
+ azSql[bLeaf], pCheck->zDb, pCheck->zTab
+ );
+ }
+ if( pCheck->rc!=SQLITE_OK ) return;
+
+ pStmt = pCheck->aCheckMapping[bLeaf];
+ sqlite3_bind_int64(pStmt, 1, iKey);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_DONE ){
+ rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table",
+ iKey, iVal, (bLeaf ? "%_rowid" : "%_parent")
+ );
+ }else if( rc==SQLITE_ROW ){
+ i64 ii = sqlite3_column_int64(pStmt, 0);
+ if( ii!=iVal ){
+ rtreeCheckAppendMsg(pCheck,
+ "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)",
+ iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal
+ );
+ }
+ }
+ rtreeCheckReset(pCheck, pStmt);
+}
+
+/*
+** Argument pCell points to an array of coordinates stored on an rtree page.
+** This function checks that the coordinates are internally consistent (no
+** x1>x2 conditions) and adds an error message to the RtreeCheck object
+** if they are not.
+**
+** Additionally, if pParent is not NULL, then it is assumed to point to
+** the array of coordinates on the parent page that bound the page
+** containing pCell. In this case it is also verified that the two
+** sets of coordinates are mutually consistent and an error message added
+** to the RtreeCheck object if they are not.
+*/
+static void rtreeCheckCellCoord(
+ RtreeCheck *pCheck,
+ i64 iNode, /* Node id to use in error messages */
+ int iCell, /* Cell number to use in error messages */
+ u8 *pCell, /* Pointer to cell coordinates */
+ u8 *pParent /* Pointer to parent coordinates */
+){
+ RtreeCoord c1, c2;
+ RtreeCoord p1, p2;
+ int i;
+
+ for(i=0; i<pCheck->nDim; i++){
+ readCoord(&pCell[4*2*i], &c1);
+ readCoord(&pCell[4*(2*i + 1)], &c2);
+
+ /* printf("%e, %e\n", c1.u.f, c2.u.f); */
+ if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){
+ rtreeCheckAppendMsg(pCheck,
+ "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode
+ );
+ }
+
+ if( pParent ){
+ readCoord(&pParent[4*2*i], &p1);
+ readCoord(&pParent[4*(2*i + 1)], &p2);
+
+ if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f)
+ || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f)
+ ){
+ rtreeCheckAppendMsg(pCheck,
+ "Dimension %d of cell %d on node %lld is corrupt relative to parent"
+ , i, iCell, iNode
+ );
+ }
+ }
+ }
+}
+
+/*
+** Run rtreecheck() checks on node iNode, which is at depth iDepth within
+** the r-tree structure. Argument aParent points to the array of coordinates
+** that bound node iNode on the parent node.
+**
+** If any problems are discovered, an error message is appended to the
+** report accumulated in the RtreeCheck object.
+*/
+static void rtreeCheckNode(
+ RtreeCheck *pCheck,
+ int iDepth, /* Depth of iNode (0==leaf) */
+ u8 *aParent, /* Buffer containing parent coords */
+ i64 iNode /* Node to check */
+){
+ u8 *aNode = 0;
+ int nNode = 0;
+
+ assert( iNode==1 || aParent!=0 );
+ assert( pCheck->nDim>0 );
+
+ aNode = rtreeCheckGetNode(pCheck, iNode, &nNode);
+ if( aNode ){
+ if( nNode<4 ){
+ rtreeCheckAppendMsg(pCheck,
+ "Node %lld is too small (%d bytes)", iNode, nNode
+ );
+ }else{
+ int nCell; /* Number of cells on page */
+ int i; /* Used to iterate through cells */
+ if( aParent==0 ){
+ iDepth = readInt16(aNode);
+ if( iDepth>RTREE_MAX_DEPTH ){
+ rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth);
+ sqlite3_free(aNode);
+ return;
+ }
+ }
+ nCell = readInt16(&aNode[2]);
+ if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){
+ rtreeCheckAppendMsg(pCheck,
+ "Node %lld is too small for cell count of %d (%d bytes)",
+ iNode, nCell, nNode
+ );
+ }else{
+ for(i=0; i<nCell; i++){
+ u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)];
+ i64 iVal = readInt64(pCell);
+ rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent);
+
+ if( iDepth>0 ){
+ rtreeCheckMapping(pCheck, 0, iVal, iNode);
+ rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal);
+ pCheck->nNonLeaf++;
+ }else{
+ rtreeCheckMapping(pCheck, 1, iVal, iNode);
+ pCheck->nLeaf++;
+ }
+ }
+ }
+ }
+ sqlite3_free(aNode);
+ }
+}
+
+/*
+** The second argument to this function must be either "_rowid" or
+** "_parent". This function checks that the number of entries in the
+** %_rowid or %_parent table is exactly nExpect. If not, it adds
+** an error message to the report in the RtreeCheck object indicated
+** by the first argument.
+*/
+static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_stmt *pCount;
+ pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'",
+ pCheck->zDb, pCheck->zTab, zTbl
+ );
+ if( pCount ){
+ if( sqlite3_step(pCount)==SQLITE_ROW ){
+ i64 nActual = sqlite3_column_int64(pCount, 0);
+ if( nActual!=nExpect ){
+ rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table"
+ " - expected %lld, actual %lld" , zTbl, nExpect, nActual
+ );
+ }
+ }
+ pCheck->rc = sqlite3_finalize(pCount);
+ }
+ }
+}
+
+/*
+** This function does the bulk of the work for the rtree integrity-check.
+** It is called by rtreecheck(), which is the SQL function implementation.
+*/
+static int rtreeCheckTable(
+ sqlite3 *db, /* Database handle to access db through */
+ const char *zDb, /* Name of db ("main", "temp" etc.) */
+ const char *zTab, /* Name of rtree table to check */
+ char **pzReport /* OUT: sqlite3_malloc'd report text */
+){
+ RtreeCheck check; /* Common context for various routines */
+ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */
+ int bEnd = 0; /* True if transaction should be closed */
+ int nAux = 0; /* Number of extra columns. */
+
+ /* Initialize the context object */
+ memset(&check, 0, sizeof(check));
+ check.db = db;
+ check.zDb = zDb;
+ check.zTab = zTab;
+
+ /* If there is not already an open transaction, open one now. This is
+ ** to ensure that the queries run as part of this integrity-check operate
+ ** on a consistent snapshot. */
+ if( sqlite3_get_autocommit(db) ){
+ check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
+ bEnd = 1;
+ }
+
+ /* Find the number of auxiliary columns */
+ if( check.rc==SQLITE_OK ){
+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
+ if( pStmt ){
+ nAux = sqlite3_column_count(pStmt) - 2;
+ sqlite3_finalize(pStmt);
+ }
+ check.rc = SQLITE_OK;
+ }
+
+ /* Find number of dimensions in the rtree table. */
+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
+ if( pStmt ){
+ int rc;
+ check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;
+ if( check.nDim<1 ){
+ rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
+ }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER);
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_CORRUPT ) check.rc = rc;
+ }
+
+ /* Do the actual integrity-check */
+ if( check.nDim>=1 ){
+ if( check.rc==SQLITE_OK ){
+ rtreeCheckNode(&check, 0, 0, 1);
+ }
+ rtreeCheckCount(&check, "_rowid", check.nLeaf);
+ rtreeCheckCount(&check, "_parent", check.nNonLeaf);
+ }
+
+ /* Finalize SQL statements used by the integrity-check */
+ sqlite3_finalize(check.pGetNode);
+ sqlite3_finalize(check.aCheckMapping[0]);
+ sqlite3_finalize(check.aCheckMapping[1]);
+
+ /* If one was opened, close the transaction */
+ if( bEnd ){
+ int rc = sqlite3_exec(db, "END", 0, 0, 0);
+ if( check.rc==SQLITE_OK ) check.rc = rc;
+ }
+ *pzReport = check.zReport;
+ return check.rc;
+}
+
+/*
+** Usage:
+**
+** rtreecheck(<rtree-table>);
+** rtreecheck(<database>, <rtree-table>);
+**
+** Invoking this SQL function runs an integrity-check on the named rtree
+** table. The integrity-check verifies the following:
+**
+** 1. For each cell in the r-tree structure (%_node table), that:
+**
+** a) for each dimension, (coord1 <= coord2).
+**
+** b) unless the cell is on the root node, that the cell is bounded
+** by the parent cell on the parent node.
+**
+** c) for leaf nodes, that there is an entry in the %_rowid
+** table corresponding to the cell's rowid value that
+** points to the correct node.
+**
+** d) for cells on non-leaf nodes, that there is an entry in the
+** %_parent table mapping from the cell's child node to the
+** node that it resides on.
+**
+** 2. That there are the same number of entries in the %_rowid table
+** as there are leaf cells in the r-tree structure, and that there
+** is a leaf cell that corresponds to each entry in the %_rowid table.
+**
+** 3. That there are the same number of entries in the %_parent table
+** as there are non-leaf cells in the r-tree structure, and that
+** there is a non-leaf cell that corresponds to each entry in the
+** %_parent table.
+*/
+static void rtreecheck(
+ sqlite3_context *ctx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ if( nArg!=1 && nArg!=2 ){
+ sqlite3_result_error(ctx,
+ "wrong number of arguments to function rtreecheck()", -1
+ );
+ }else{
+ int rc;
+ char *zReport = 0;
+ const char *zDb = (const char*)sqlite3_value_text(apArg[0]);
+ const char *zTab;
+ if( nArg==1 ){
+ zTab = zDb;
+ zDb = "main";
+ }else{
+ zTab = (const char*)sqlite3_value_text(apArg[1]);
+ }
+ rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(ctx, rc);
+ }
+ sqlite3_free(zReport);
+ }
+}
+
+/* Conditionally include the geopoly code */
+#ifdef SQLITE_ENABLE_GEOPOLY
+/************** Include geopoly.c in the middle of rtree.c *******************/
+/************** Begin file geopoly.c *****************************************/
+/*
+** 2018-05-25
+**
+** 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 an alternative R-Tree virtual table that
+** uses polygons to express the boundaries of 2-dimensional objects.
+**
+** This file is #include-ed onto the end of "rtree.c" so that it has
+** access to all of the R-Tree internals.
+*/
+/* #include <stdlib.h> */
+
+/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
+#ifdef GEOPOLY_ENABLE_DEBUG
+ static int geo_debug = 0;
+# define GEODEBUG(X) if(geo_debug)printf X
+#else
+# define GEODEBUG(X)
+#endif
+
+#ifndef JSON_NULL /* The following stuff repeats things found in json1 */
+/*
+** Versions of isspace(), isalnum() and isdigit() to which it is safe
+** to pass signed char values.
+*/
+#ifdef sqlite3Isdigit
+ /* Use the SQLite core versions if this routine is part of the
+ ** SQLite amalgamation */
+# define safe_isdigit(x) sqlite3Isdigit(x)
+# define safe_isalnum(x) sqlite3Isalnum(x)
+# define safe_isxdigit(x) sqlite3Isxdigit(x)
+#else
+ /* Use the standard library for separate compilation */
+#include <ctype.h> /* amalgamator: keep */
+# define safe_isdigit(x) isdigit((unsigned char)(x))
+# define safe_isalnum(x) isalnum((unsigned char)(x))
+# define safe_isxdigit(x) isxdigit((unsigned char)(x))
+#endif
+
+/*
+** Growing our own isspace() routine this way is twice as fast as
+** the library isspace() function.
+*/
+static const char geopolyIsSpace[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x])
+#endif /* JSON NULL - back to original code */
+
+/* Compiler and version */
+#ifndef GCC_VERSION
+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
+#else
+# define GCC_VERSION 0
+#endif
+#endif
+#ifndef MSVC_VERSION
+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define MSVC_VERSION _MSC_VER
+#else
+# define MSVC_VERSION 0
+#endif
+#endif
+
+/* Datatype for coordinates
+*/
+typedef float GeoCoord;
+
+/*
+** Internal representation of a polygon.
+**
+** The polygon consists of a sequence of vertexes. There is a line
+** segment between each pair of vertexes, and one final segment from
+** the last vertex back to the first. (This differs from the GeoJSON
+** standard in which the final vertex is a repeat of the first.)
+**
+** The polygon follows the right-hand rule. The area to the right of
+** each segment is "outside" and the area to the left is "inside".
+**
+** The on-disk representation consists of a 4-byte header followed by
+** the values. The 4-byte header is:
+**
+** encoding (1 byte) 0=big-endian, 1=little-endian
+** nvertex (3 bytes) Number of vertexes as a big-endian integer
+*/
+typedef struct GeoPoly GeoPoly;
+struct GeoPoly {
+ int nVertex; /* Number of vertexes */
+ unsigned char hdr[4]; /* Header for on-disk representation */
+ GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
+};
+
+/*
+** State of a parse of a GeoJSON input.
+*/
+typedef struct GeoParse GeoParse;
+struct GeoParse {
+ const unsigned char *z; /* Unparsed input */
+ int nVertex; /* Number of vertexes in a[] */
+ int nAlloc; /* Space allocated to a[] */
+ int nErr; /* Number of errors encountered */
+ GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */
+};
+
+/* Do a 4-byte byte swap */
+static void geopolySwab32(unsigned char *a){
+ unsigned char t = a[0];
+ a[0] = a[3];
+ a[3] = t;
+ t = a[1];
+ a[1] = a[2];
+ a[2] = t;
+}
+
+/* Skip whitespace. Return the next non-whitespace character. */
+static char geopolySkipSpace(GeoParse *p){
+ while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
+ return p->z[0];
+}
+
+/* Parse out a number. Write the value into *pVal if pVal!=0.
+** return non-zero on success and zero if the next token is not a number.
+*/
+static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
+ char c = geopolySkipSpace(p);
+ const unsigned char *z = p->z;
+ int j = 0;
+ int seenDP = 0;
+ int seenE = 0;
+ if( c=='-' ){
+ j = 1;
+ c = z[j];
+ }
+ if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
+ for(;; j++){
+ c = z[j];
+ if( c>='0' && c<='9' ) continue;
+ if( c=='.' ){
+ if( z[j-1]=='-' ) return 0;
+ if( seenDP ) return 0;
+ seenDP = 1;
+ continue;
+ }
+ if( c=='e' || c=='E' ){
+ if( z[j-1]<'0' ) return 0;
+ if( seenE ) return -1;
+ seenDP = seenE = 1;
+ c = z[j+1];
+ if( c=='+' || c=='-' ){
+ j++;
+ c = z[j+1];
+ }
+ if( c<'0' || c>'9' ) return 0;
+ continue;
+ }
+ break;
+ }
+ if( z[j-1]<'0' ) return 0;
+ if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
+ p->z += j;
+ return 1;
+}
+
+/*
+** If the input is a well-formed JSON array of coordinates with at least
+** four coordinates and where each coordinate is itself a two-value array,
+** then convert the JSON into a GeoPoly object and return a pointer to
+** that object.
+**
+** If any error occurs, return NULL.
+*/
+static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
+ GeoParse s;
+ int rc = SQLITE_OK;
+ memset(&s, 0, sizeof(s));
+ s.z = z;
+ if( geopolySkipSpace(&s)=='[' ){
+ s.z++;
+ while( geopolySkipSpace(&s)=='[' ){
+ int ii = 0;
+ char c;
+ s.z++;
+ if( s.nVertex>=s.nAlloc ){
+ GeoCoord *aNew;
+ s.nAlloc = s.nAlloc*2 + 16;
+ aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 );
+ if( aNew==0 ){
+ rc = SQLITE_NOMEM;
+ s.nErr++;
+ break;
+ }
+ s.a = aNew;
+ }
+ while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){
+ ii++;
+ if( ii==2 ) s.nVertex++;
+ c = geopolySkipSpace(&s);
+ s.z++;
+ if( c==',' ) continue;
+ if( c==']' && ii>=2 ) break;
+ s.nErr++;
+ rc = SQLITE_ERROR;
+ goto parse_json_err;
+ }
+ if( geopolySkipSpace(&s)==',' ){
+ s.z++;
+ continue;
+ }
+ break;
+ }
+ if( geopolySkipSpace(&s)==']'
+ && s.nVertex>=4
+ && s.a[0]==s.a[s.nVertex*2-2]
+ && s.a[1]==s.a[s.nVertex*2-1]
+ && (s.z++, geopolySkipSpace(&s)==0)
+ ){
+ int nByte;
+ GeoPoly *pOut;
+ int x = 1;
+ s.nVertex--; /* Remove the redundant vertex at the end */
+ nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
+ pOut = sqlite3_malloc64( nByte );
+ x = 1;
+ if( pOut==0 ) goto parse_json_err;
+ pOut->nVertex = s.nVertex;
+ memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
+ pOut->hdr[0] = *(unsigned char*)&x;
+ pOut->hdr[1] = (s.nVertex>>16)&0xff;
+ pOut->hdr[2] = (s.nVertex>>8)&0xff;
+ pOut->hdr[3] = s.nVertex&0xff;
+ sqlite3_free(s.a);
+ if( pRc ) *pRc = SQLITE_OK;
+ return pOut;
+ }else{
+ s.nErr++;
+ rc = SQLITE_ERROR;
+ }
+ }
+parse_json_err:
+ if( pRc ) *pRc = rc;
+ sqlite3_free(s.a);
+ return 0;
+}
+
+/*
+** Given a function parameter, try to interpret it as a polygon, either
+** in the binary format or JSON text. Compute a GeoPoly object and
+** return a pointer to that object. Or if the input is not a well-formed
+** polygon, put an error message in sqlite3_context and return NULL.
+*/
+static GeoPoly *geopolyFuncParam(
+ sqlite3_context *pCtx, /* Context for error messages */
+ sqlite3_value *pVal, /* The value to decode */
+ int *pRc /* Write error here */
+){
+ GeoPoly *p = 0;
+ int nByte;
+ if( sqlite3_value_type(pVal)==SQLITE_BLOB
+ && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
+ ){
+ const unsigned char *a = sqlite3_value_blob(pVal);
+ int nVertex;
+ nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
+ if( (a[0]==0 || a[0]==1)
+ && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
+ ){
+ p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) );
+ if( p==0 ){
+ if( pRc ) *pRc = SQLITE_NOMEM;
+ if( pCtx ) sqlite3_result_error_nomem(pCtx);
+ }else{
+ int x = 1;
+ p->nVertex = nVertex;
+ memcpy(p->hdr, a, nByte);
+ if( a[0] != *(unsigned char*)&x ){
+ int ii;
+ for(ii=0; ii<nVertex*2; ii++){
+ geopolySwab32((unsigned char*)&p->a[ii]);
+ }
+ p->hdr[0] ^= 1;
+ }
+ }
+ }
+ if( pRc ) *pRc = SQLITE_OK;
+ return p;
+ }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){
+ const unsigned char *zJson = sqlite3_value_text(pVal);
+ if( zJson==0 ){
+ if( pRc ) *pRc = SQLITE_NOMEM;
+ return 0;
+ }
+ return geopolyParseJson(zJson, pRc);
+ }else{
+ if( pRc ) *pRc = SQLITE_ERROR;
+ return 0;
+ }
+}
+
+/*
+** Implementation of the geopoly_blob(X) function.
+**
+** If the input is a well-formed Geopoly BLOB or JSON string
+** then return the BLOB representation of the polygon. Otherwise
+** return NULL.
+*/
+static void geopolyBlobFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ sqlite3_result_blob(context, p->hdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** SQL function: geopoly_json(X)
+**
+** Interpret X as a polygon and render it as a JSON array
+** of coordinates. Or, if X is not a valid polygon, return NULL.
+*/
+static void geopolyJsonFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ sqlite3_str *x = sqlite3_str_new(db);
+ int i;
+ sqlite3_str_append(x, "[", 1);
+ for(i=0; i<p->nVertex; i++){
+ sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
+ }
+ sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
+ sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** SQL function: geopoly_svg(X, ....)
+**
+** Interpret X as a polygon and render it as a SVG <polyline>.
+** Additional arguments are added as attributes to the <polyline>.
+*/
+static void geopolySvgFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ sqlite3 *db = sqlite3_context_db_handle(context);
+ sqlite3_str *x = sqlite3_str_new(db);
+ int i;
+ char cSep = '\'';
+ sqlite3_str_appendf(x, "<polyline points=");
+ for(i=0; i<p->nVertex; i++){
+ sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]);
+ cSep = ' ';
+ }
+ sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
+ for(i=1; i<argc; i++){
+ const char *z = (const char*)sqlite3_value_text(argv[i]);
+ if( z && z[0] ){
+ sqlite3_str_appendf(x, " %s", z);
+ }
+ }
+ sqlite3_str_appendf(x, "></polyline>");
+ sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** SQL Function: geopoly_xform(poly, A, B, C, D, E, F)
+**
+** Transform and/or translate a polygon as follows:
+**
+** x1 = A*x0 + B*y0 + E
+** y1 = C*x0 + D*y0 + F
+**
+** For a translation:
+**
+** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset)
+**
+** Rotate by R around the point (0,0):
+**
+** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0)
+*/
+static void geopolyXformFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ double A = sqlite3_value_double(argv[1]);
+ double B = sqlite3_value_double(argv[2]);
+ double C = sqlite3_value_double(argv[3]);
+ double D = sqlite3_value_double(argv[4]);
+ double E = sqlite3_value_double(argv[5]);
+ double F = sqlite3_value_double(argv[6]);
+ GeoCoord x1, y1, x0, y0;
+ int ii;
+ if( p ){
+ for(ii=0; ii<p->nVertex; ii++){
+ x0 = p->a[ii*2];
+ y0 = p->a[ii*2+1];
+ x1 = (GeoCoord)(A*x0 + B*y0 + E);
+ y1 = (GeoCoord)(C*x0 + D*y0 + F);
+ p->a[ii*2] = x1;
+ p->a[ii*2+1] = y1;
+ }
+ sqlite3_result_blob(context, p->hdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Implementation of the geopoly_area(X) function.
+**
+** If the input is a well-formed Geopoly BLOB then return the area
+** enclosed by the polygon. If the polygon circulates clockwise instead
+** of counterclockwise (as it should) then return the negative of the
+** enclosed area. Otherwise return NULL.
+*/
+static void geopolyAreaFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ double rArea = 0.0;
+ int ii;
+ for(ii=0; ii<p->nVertex-1; ii++){
+ rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
+ * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
+ * 0.5;
+ }
+ rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
+ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
+ * 0.5;
+ sqlite3_result_double(context, rArea);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** If pPoly is a polygon, compute its bounding box. Then:
+**
+** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
+** (2) otherwise, compute a GeoPoly for the bounding box and return the
+** new GeoPoly
+**
+** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from
+** the bounding box in aCoord and return a pointer to that GeoPoly.
+*/
+static GeoPoly *geopolyBBox(
+ sqlite3_context *context, /* For recording the error */
+ sqlite3_value *pPoly, /* The polygon */
+ RtreeCoord *aCoord, /* Results here */
+ int *pRc /* Error code here */
+){
+ GeoPoly *pOut = 0;
+ GeoPoly *p;
+ float mnX, mxX, mnY, mxY;
+ if( pPoly==0 && aCoord!=0 ){
+ p = 0;
+ mnX = aCoord[0].f;
+ mxX = aCoord[1].f;
+ mnY = aCoord[2].f;
+ mxY = aCoord[3].f;
+ goto geopolyBboxFill;
+ }else{
+ p = geopolyFuncParam(context, pPoly, pRc);
+ }
+ if( p ){
+ int ii;
+ mnX = mxX = p->a[0];
+ mnY = mxY = p->a[1];
+ for(ii=1; ii<p->nVertex; ii++){
+ double r = p->a[ii*2];
+ if( r<mnX ) mnX = (float)r;
+ else if( r>mxX ) mxX = (float)r;
+ r = p->a[ii*2+1];
+ if( r<mnY ) mnY = (float)r;
+ else if( r>mxY ) mxY = (float)r;
+ }
+ if( pRc ) *pRc = SQLITE_OK;
+ if( aCoord==0 ){
+ geopolyBboxFill:
+ pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
+ if( pOut==0 ){
+ sqlite3_free(p);
+ if( context ) sqlite3_result_error_nomem(context);
+ if( pRc ) *pRc = SQLITE_NOMEM;
+ return 0;
+ }
+ pOut->nVertex = 4;
+ ii = 1;
+ pOut->hdr[0] = *(unsigned char*)&ii;
+ pOut->hdr[1] = 0;
+ pOut->hdr[2] = 0;
+ pOut->hdr[3] = 4;
+ pOut->a[0] = mnX;
+ pOut->a[1] = mnY;
+ pOut->a[2] = mxX;
+ pOut->a[3] = mnY;
+ pOut->a[4] = mxX;
+ pOut->a[5] = mxY;
+ pOut->a[6] = mnX;
+ pOut->a[7] = mxY;
+ }else{
+ sqlite3_free(p);
+ aCoord[0].f = mnX;
+ aCoord[1].f = mxX;
+ aCoord[2].f = mnY;
+ aCoord[3].f = mxY;
+ }
+ }
+ return pOut;
+}
+
+/*
+** Implementation of the geopoly_bbox(X) SQL function.
+*/
+static void geopolyBBoxFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0);
+ if( p ){
+ sqlite3_result_blob(context, p->hdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+ }
+}
+
+/*
+** State vector for the geopoly_group_bbox() aggregate function.
+*/
+typedef struct GeoBBox GeoBBox;
+struct GeoBBox {
+ int isInit;
+ RtreeCoord a[4];
+};
+
+
+/*
+** Implementation of the geopoly_group_bbox(X) aggregate SQL function.
+*/
+static void geopolyBBoxStep(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ RtreeCoord a[4];
+ int rc = SQLITE_OK;
+ (void)geopolyBBox(context, argv[0], a, &rc);
+ if( rc==SQLITE_OK ){
+ GeoBBox *pBBox;
+ pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox));
+ if( pBBox==0 ) return;
+ if( pBBox->isInit==0 ){
+ pBBox->isInit = 1;
+ memcpy(pBBox->a, a, sizeof(RtreeCoord)*4);
+ }else{
+ if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0];
+ if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1];
+ if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2];
+ if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3];
+ }
+ }
+}
+static void geopolyBBoxFinal(
+ sqlite3_context *context
+){
+ GeoPoly *p;
+ GeoBBox *pBBox;
+ pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0);
+ if( pBBox==0 ) return;
+ p = geopolyBBox(context, 0, pBBox->a, 0);
+ if( p ){
+ sqlite3_result_blob(context, p->hdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+ }
+}
+
+
+/*
+** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2).
+** Returns:
+**
+** +2 x0,y0 is on the line segement
+**
+** +1 x0,y0 is beneath line segment
+**
+** 0 x0,y0 is not on or beneath the line segment or the line segment
+** is vertical and x0,y0 is not on the line segment
+**
+** The left-most coordinate min(x1,x2) is not considered to be part of
+** the line segment for the purposes of this analysis.
+*/
+static int pointBeneathLine(
+ double x0, double y0,
+ double x1, double y1,
+ double x2, double y2
+){
+ double y;
+ if( x0==x1 && y0==y1 ) return 2;
+ if( x1<x2 ){
+ if( x0<=x1 || x0>x2 ) return 0;
+ }else if( x1>x2 ){
+ if( x0<=x2 || x0>x1 ) return 0;
+ }else{
+ /* Vertical line segment */
+ if( x0!=x1 ) return 0;
+ if( y0<y1 && y0<y2 ) return 0;
+ if( y0>y1 && y0>y2 ) return 0;
+ return 2;
+ }
+ y = y1 + (y2-y1)*(x0-x1)/(x2-x1);
+ if( y0==y ) return 2;
+ if( y0<y ) return 1;
+ return 0;
+}
+
+/*
+** SQL function: geopoly_contains_point(P,X,Y)
+**
+** Return +2 if point X,Y is within polygon P.
+** Return +1 if point X,Y is on the polygon boundary.
+** Return 0 if point X,Y is outside the polygon
+*/
+static void geopolyContainsPointFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
+ double x0 = sqlite3_value_double(argv[1]);
+ double y0 = sqlite3_value_double(argv[2]);
+ int v = 0;
+ int cnt = 0;
+ int ii;
+ if( p1==0 ) return;
+ for(ii=0; ii<p1->nVertex-1; ii++){
+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
+ p1->a[ii*2+2],p1->a[ii*2+3]);
+ if( v==2 ) break;
+ cnt += v;
+ }
+ if( v!=2 ){
+ v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
+ p1->a[0],p1->a[1]);
+ }
+ if( v==2 ){
+ sqlite3_result_int(context, 1);
+ }else if( ((v+cnt)&1)==0 ){
+ sqlite3_result_int(context, 0);
+ }else{
+ sqlite3_result_int(context, 2);
+ }
+ sqlite3_free(p1);
+}
+
+/* Forward declaration */
+static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
+
+/*
+** SQL function: geopoly_within(P1,P2)
+**
+** Return +2 if P1 and P2 are the same polygon
+** Return +1 if P2 is contained within P1
+** Return 0 if any part of P2 is on the outside of P1
+**
+*/
+static void geopolyWithinFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
+ GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
+ if( p1 && p2 ){
+ int x = geopolyOverlap(p1, p2);
+ if( x<0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
+ }
+ }
+ sqlite3_free(p1);
+ sqlite3_free(p2);
+}
+
+/* Objects used by the overlap algorihm. */
+typedef struct GeoEvent GeoEvent;
+typedef struct GeoSegment GeoSegment;
+typedef struct GeoOverlap GeoOverlap;
+struct GeoEvent {
+ double x; /* X coordinate at which event occurs */
+ int eType; /* 0 for ADD, 1 for REMOVE */
+ GeoSegment *pSeg; /* The segment to be added or removed */
+ GeoEvent *pNext; /* Next event in the sorted list */
+};
+struct GeoSegment {
+ double C, B; /* y = C*x + B */
+ double y; /* Current y value */
+ float y0; /* Initial y value */
+ unsigned char side; /* 1 for p1, 2 for p2 */
+ unsigned int idx; /* Which segment within the side */
+ GeoSegment *pNext; /* Next segment in a list sorted by y */
+};
+struct GeoOverlap {
+ GeoEvent *aEvent; /* Array of all events */
+ GeoSegment *aSegment; /* Array of all segments */
+ int nEvent; /* Number of events */
+ int nSegment; /* Number of segments */
+};
+
+/*
+** Add a single segment and its associated events.
+*/
+static void geopolyAddOneSegment(
+ GeoOverlap *p,
+ GeoCoord x0,
+ GeoCoord y0,
+ GeoCoord x1,
+ GeoCoord y1,
+ unsigned char side,
+ unsigned int idx
+){
+ GeoSegment *pSeg;
+ GeoEvent *pEvent;
+ if( x0==x1 ) return; /* Ignore vertical segments */
+ if( x0>x1 ){
+ GeoCoord t = x0;
+ x0 = x1;
+ x1 = t;
+ t = y0;
+ y0 = y1;
+ y1 = t;
+ }
+ pSeg = p->aSegment + p->nSegment;
+ p->nSegment++;
+ pSeg->C = (y1-y0)/(x1-x0);
+ pSeg->B = y1 - x1*pSeg->C;
+ pSeg->y0 = y0;
+ pSeg->side = side;
+ pSeg->idx = idx;
+ pEvent = p->aEvent + p->nEvent;
+ p->nEvent++;
+ pEvent->x = x0;
+ pEvent->eType = 0;
+ pEvent->pSeg = pSeg;
+ pEvent = p->aEvent + p->nEvent;
+ p->nEvent++;
+ pEvent->x = x1;
+ pEvent->eType = 1;
+ pEvent->pSeg = pSeg;
+}
+
+
+
+/*
+** Insert all segments and events for polygon pPoly.
+*/
+static void geopolyAddSegments(
+ GeoOverlap *p, /* Add segments to this Overlap object */
+ GeoPoly *pPoly, /* Take all segments from this polygon */
+ unsigned char side /* The side of pPoly */
+){
+ unsigned int i;
+ GeoCoord *x;
+ for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
+ x = pPoly->a + (i*2);
+ geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
+ }
+ x = pPoly->a + (i*2);
+ geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
+}
+
+/*
+** Merge two lists of sorted events by X coordinate
+*/
+static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){
+ GeoEvent head, *pLast;
+ head.pNext = 0;
+ pLast = &head;
+ while( pRight && pLeft ){
+ if( pRight->x <= pLeft->x ){
+ pLast->pNext = pRight;
+ pLast = pRight;
+ pRight = pRight->pNext;
+ }else{
+ pLast->pNext = pLeft;
+ pLast = pLeft;
+ pLeft = pLeft->pNext;
+ }
+ }
+ pLast->pNext = pRight ? pRight : pLeft;
+ return head.pNext;
+}
+
+/*
+** Sort an array of nEvent event objects into a list.
+*/
+static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){
+ int mx = 0;
+ int i, j;
+ GeoEvent *p;
+ GeoEvent *a[50];
+ for(i=0; i<nEvent; i++){
+ p = &aEvent[i];
+ p->pNext = 0;
+ for(j=0; j<mx && a[j]; j++){
+ p = geopolyEventMerge(a[j], p);
+ a[j] = 0;
+ }
+ a[j] = p;
+ if( j>=mx ) mx = j+1;
+ }
+ p = 0;
+ for(i=0; i<mx; i++){
+ p = geopolyEventMerge(a[i], p);
+ }
+ return p;
+}
+
+/*
+** Merge two lists of sorted segments by Y, and then by C.
+*/
+static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){
+ GeoSegment head, *pLast;
+ head.pNext = 0;
+ pLast = &head;
+ while( pRight && pLeft ){
+ double r = pRight->y - pLeft->y;
+ if( r==0.0 ) r = pRight->C - pLeft->C;
+ if( r<0.0 ){
+ pLast->pNext = pRight;
+ pLast = pRight;
+ pRight = pRight->pNext;
+ }else{
+ pLast->pNext = pLeft;
+ pLast = pLeft;
+ pLeft = pLeft->pNext;
+ }
+ }
+ pLast->pNext = pRight ? pRight : pLeft;
+ return head.pNext;
+}
+
+/*
+** Sort a list of GeoSegments in order of increasing Y and in the event of
+** a tie, increasing C (slope).
+*/
+static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
+ int mx = 0;
+ int i;
+ GeoSegment *p;
+ GeoSegment *a[50];
+ while( pList ){
+ p = pList;
+ pList = pList->pNext;
+ p->pNext = 0;
+ for(i=0; i<mx && a[i]; i++){
+ p = geopolySegmentMerge(a[i], p);
+ a[i] = 0;
+ }
+ a[i] = p;
+ if( i>=mx ) mx = i+1;
+ }
+ p = 0;
+ for(i=0; i<mx; i++){
+ p = geopolySegmentMerge(a[i], p);
+ }
+ return p;
+}
+
+/*
+** Determine the overlap between two polygons
+*/
+static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
+ int nVertex = p1->nVertex + p2->nVertex + 2;
+ GeoOverlap *p;
+ int nByte;
+ GeoEvent *pThisEvent;
+ double rX;
+ int rc = 0;
+ int needSort = 0;
+ GeoSegment *pActive = 0;
+ GeoSegment *pSeg;
+ unsigned char aOverlap[4];
+
+ nByte = sizeof(GeoEvent)*nVertex*2
+ + sizeof(GeoSegment)*nVertex
+ + sizeof(GeoOverlap);
+ p = sqlite3_malloc( nByte );
+ if( p==0 ) return -1;
+ p->aEvent = (GeoEvent*)&p[1];
+ p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
+ p->nEvent = p->nSegment = 0;
+ geopolyAddSegments(p, p1, 1);
+ geopolyAddSegments(p, p2, 2);
+ pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
+ rX = pThisEvent->x==0.0 ? -1.0 : 0.0;
+ memset(aOverlap, 0, sizeof(aOverlap));
+ while( pThisEvent ){
+ if( pThisEvent->x!=rX ){
+ GeoSegment *pPrev = 0;
+ int iMask = 0;
+ GEODEBUG(("Distinct X: %g\n", pThisEvent->x));
+ rX = pThisEvent->x;
+ if( needSort ){
+ GEODEBUG(("SORT\n"));
+ pActive = geopolySortSegmentsByYAndC(pActive);
+ needSort = 0;
+ }
+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
+ if( pPrev ){
+ if( pPrev->y!=pSeg->y ){
+ GEODEBUG(("MASK: %d\n", iMask));
+ aOverlap[iMask] = 1;
+ }
+ }
+ iMask ^= pSeg->side;
+ pPrev = pSeg;
+ }
+ pPrev = 0;
+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
+ double y = pSeg->C*rX + pSeg->B;
+ GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y));
+ pSeg->y = y;
+ if( pPrev ){
+ if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){
+ rc = 1;
+ GEODEBUG(("Crossing: %d.%d and %d.%d\n",
+ pPrev->side, pPrev->idx,
+ pSeg->side, pSeg->idx));
+ goto geopolyOverlapDone;
+ }else if( pPrev->y!=pSeg->y ){
+ GEODEBUG(("MASK: %d\n", iMask));
+ aOverlap[iMask] = 1;
+ }
+ }
+ iMask ^= pSeg->side;
+ pPrev = pSeg;
+ }
+ }
+ GEODEBUG(("%s %d.%d C=%g B=%g\n",
+ pThisEvent->eType ? "RM " : "ADD",
+ pThisEvent->pSeg->side, pThisEvent->pSeg->idx,
+ pThisEvent->pSeg->C,
+ pThisEvent->pSeg->B));
+ if( pThisEvent->eType==0 ){
+ /* Add a segment */
+ pSeg = pThisEvent->pSeg;
+ pSeg->y = pSeg->y0;
+ pSeg->pNext = pActive;
+ pActive = pSeg;
+ needSort = 1;
+ }else{
+ /* Remove a segment */
+ if( pActive==pThisEvent->pSeg ){
+ pActive = pActive->pNext;
+ }else{
+ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
+ if( pSeg->pNext==pThisEvent->pSeg ){
+ pSeg->pNext = pSeg->pNext->pNext;
+ break;
+ }
+ }
+ }
+ }
+ pThisEvent = pThisEvent->pNext;
+ }
+ if( aOverlap[3]==0 ){
+ rc = 0;
+ }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){
+ rc = 3;
+ }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){
+ rc = 2;
+ }else if( aOverlap[1]==0 && aOverlap[2]==0 ){
+ rc = 4;
+ }else{
+ rc = 1;
+ }
+
+geopolyOverlapDone:
+ sqlite3_free(p);
+ return rc;
+}
+
+/*
+** SQL function: geopoly_overlap(P1,P2)
+**
+** Determine whether or not P1 and P2 overlap. Return value:
+**
+** 0 The two polygons are disjoint
+** 1 They overlap
+** 2 P1 is completely contained within P2
+** 3 P2 is completely contained within P1
+** 4 P1 and P2 are the same polygon
+** NULL Either P1 or P2 or both are not valid polygons
+*/
+static void geopolyOverlapFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
+ GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
+ if( p1 && p2 ){
+ int x = geopolyOverlap(p1, p2);
+ if( x<0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3_result_int(context, x);
+ }
+ }
+ sqlite3_free(p1);
+ sqlite3_free(p2);
+}
+
+/*
+** Enable or disable debugging output
+*/
+static void geopolyDebugFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+#ifdef GEOPOLY_ENABLE_DEBUG
+ geo_debug = sqlite3_value_int(argv[0]);
+#endif
+}
+
+/*
+** This function is the implementation of both the xConnect and xCreate
+** methods of the geopoly virtual table.
+**
+** argv[0] -> module name
+** argv[1] -> database name
+** argv[2] -> table name
+** argv[...] -> column names...
+*/
+static int geopolyInit(
+ sqlite3 *db, /* Database connection */
+ void *pAux, /* One of the RTREE_COORD_* constants */
+ int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */
+ sqlite3_vtab **ppVtab, /* OUT: New virtual table */
+ char **pzErr, /* OUT: Error message, if any */
+ int isCreate /* True for xCreate, false for xConnect */
+){
+ int rc = SQLITE_OK;
+ Rtree *pRtree;
+ int nDb; /* Length of string argv[1] */
+ int nName; /* Length of string argv[2] */
+ sqlite3_str *pSql;
+ char *zSql;
+ int ii;
+
+ sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
+
+ /* Allocate the sqlite3_vtab structure */
+ nDb = (int)strlen(argv[1]);
+ nName = (int)strlen(argv[2]);
+ pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+ if( !pRtree ){
+ return SQLITE_NOMEM;
+ }
+ memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
+ pRtree->nBusy = 1;
+ pRtree->base.pModule = &rtreeModule;
+ pRtree->zDb = (char *)&pRtree[1];
+ pRtree->zName = &pRtree->zDb[nDb+1];
+ pRtree->eCoordType = RTREE_COORD_REAL32;
+ pRtree->nDim = 2;
+ pRtree->nDim2 = 4;
+ memcpy(pRtree->zDb, argv[1], nDb);
+ memcpy(pRtree->zName, argv[2], nName);
+
+
+ /* Create/Connect to the underlying relational database schema. If
+ ** that is successful, call sqlite3_declare_vtab() to configure
+ ** the r-tree table schema.
+ */
+ pSql = sqlite3_str_new(db);
+ sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape");
+ pRtree->nAux = 1; /* Add one for _shape */
+ pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */
+ for(ii=3; ii<argc; ii++){
+ pRtree->nAux++;
+ sqlite3_str_appendf(pSql, ",%s", argv[ii]);
+ }
+ sqlite3_str_appendf(pSql, ");");
+ zSql = sqlite3_str_finish(pSql);
+ if( !zSql ){
+ rc = SQLITE_NOMEM;
+ }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+ sqlite3_free(zSql);
+ if( rc ) goto geopolyInit_fail;
+ pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
+
+ /* Figure out the node size to use. */
+ rc = getNodeSize(db, pRtree, isCreate, pzErr);
+ if( rc ) goto geopolyInit_fail;
+ rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
+ if( rc ){
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ goto geopolyInit_fail;
+ }
+
+ *ppVtab = (sqlite3_vtab *)pRtree;
+ return SQLITE_OK;
+
+geopolyInit_fail:
+ if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
+ assert( *ppVtab==0 );
+ assert( pRtree->nBusy==1 );
+ rtreeRelease(pRtree);
+ return rc;
+}
+
+
+/*
+** GEOPOLY virtual table module xCreate method.
+*/
+static int geopolyCreate(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
+}
+
+/*
+** GEOPOLY virtual table module xConnect method.
+*/
+static int geopolyConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
+}
+
+
+/*
+** GEOPOLY virtual table module xFilter method.
+**
+** Query plans:
+**
+** 1 rowid lookup
+** 2 search for objects overlapping the same bounding box
+** that contains polygon argv[0]
+** 3 search for objects overlapping the same bounding box
+** that contains polygon argv[0]
+** 4 full table scan
+*/
+static int geopolyFilter(
+ sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */
+ int idxNum, /* Query plan */
+ const char *idxStr, /* Not Used */
+ int argc, sqlite3_value **argv /* Parameters to the query plan */
+){
+ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
+ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
+ RtreeNode *pRoot = 0;
+ int rc = SQLITE_OK;
+ int iCell = 0;
+ sqlite3_stmt *pStmt;
+
+ rtreeReference(pRtree);
+
+ /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
+ freeCursorConstraints(pCsr);
+ sqlite3_free(pCsr->aPoint);
+ pStmt = pCsr->pReadAux;
+ memset(pCsr, 0, sizeof(RtreeCursor));
+ pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
+ pCsr->pReadAux = pStmt;
+
+ pCsr->iStrategy = idxNum;
+ if( idxNum==1 ){
+ /* Special case - lookup by rowid. */
+ RtreeNode *pLeaf; /* Leaf on which the required cell resides */
+ RtreeSearchPoint *p; /* Search point for the leaf */
+ i64 iRowid = sqlite3_value_int64(argv[0]);
+ i64 iNode = 0;
+ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
+ if( rc==SQLITE_OK && pLeaf!=0 ){
+ p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
+ assert( p!=0 ); /* Always returns pCsr->sPoint */
+ pCsr->aNode[0] = pLeaf;
+ p->id = iNode;
+ p->eWithin = PARTLY_WITHIN;
+ rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
+ p->iCell = (u8)iCell;
+ RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
+ }else{
+ pCsr->atEOF = 1;
+ }
+ }else{
+ /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
+ ** with the configured constraints.
+ */
+ rc = nodeAcquire(pRtree, 1, 0, &pRoot);
+ if( rc==SQLITE_OK && idxNum<=3 ){
+ RtreeCoord bbox[4];
+ RtreeConstraint *p;
+ assert( argc==1 );
+ geopolyBBox(0, argv[0], bbox, &rc);
+ if( rc ){
+ goto geopoly_filter_end;
+ }
+ pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
+ pCsr->nConstraint = 4;
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4);
+ memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
+ if( idxNum==2 ){
+ /* Overlap query */
+ p->op = 'B';
+ p->iCoord = 0;
+ p->u.rValue = bbox[1].f;
+ p++;
+ p->op = 'D';
+ p->iCoord = 1;
+ p->u.rValue = bbox[0].f;
+ p++;
+ p->op = 'B';
+ p->iCoord = 2;
+ p->u.rValue = bbox[3].f;
+ p++;
+ p->op = 'D';
+ p->iCoord = 3;
+ p->u.rValue = bbox[2].f;
+ }else{
+ /* Within query */
+ p->op = 'D';
+ p->iCoord = 0;
+ p->u.rValue = bbox[0].f;
+ p++;
+ p->op = 'B';
+ p->iCoord = 1;
+ p->u.rValue = bbox[1].f;
+ p++;
+ p->op = 'D';
+ p->iCoord = 2;
+ p->u.rValue = bbox[2].f;
+ p++;
+ p->op = 'B';
+ p->iCoord = 3;
+ p->u.rValue = bbox[3].f;
+ }
+ }
+ }
+ if( rc==SQLITE_OK ){
+ RtreeSearchPoint *pNew;
+ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ goto geopoly_filter_end;
+ }
+ pNew->id = 1;
+ pNew->iCell = 0;
+ pNew->eWithin = PARTLY_WITHIN;
+ assert( pCsr->bPoint==1 );
+ pCsr->aNode[0] = pRoot;
+ pRoot = 0;
+ RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
+ rc = rtreeStepToLeaf(pCsr);
+ }
+ }
+
+geopoly_filter_end:
+ nodeRelease(pRtree, pRoot);
+ rtreeRelease(pRtree);
+ return rc;
+}
+
+/*
+** Rtree virtual table module xBestIndex method. There are three
+** table scan strategies to choose from (in order from most to
+** least desirable):
+**
+** idxNum idxStr Strategy
+** ------------------------------------------------
+** 1 "rowid" Direct lookup by rowid.
+** 2 "rtree" R-tree overlap query using geopoly_overlap()
+** 3 "rtree" R-tree within query using geopoly_within()
+** 4 "fullscan" full-table scan.
+** ------------------------------------------------
+*/
+static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ int ii;
+ int iRowidTerm = -1;
+ int iFuncTerm = -1;
+ int idxNum = 0;
+
+ for(ii=0; ii<pIdxInfo->nConstraint; ii++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
+ if( !p->usable ) continue;
+ if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ iRowidTerm = ii;
+ break;
+ }
+ if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
+ /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap()
+ ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within().
+ ** See geopolyFindFunction() */
+ iFuncTerm = ii;
+ idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2;
+ }
+ }
+
+ if( iRowidTerm>=0 ){
+ pIdxInfo->idxNum = 1;
+ pIdxInfo->idxStr = "rowid";
+ pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
+ pIdxInfo->estimatedCost = 30.0;
+ pIdxInfo->estimatedRows = 1;
+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
+ return SQLITE_OK;
+ }
+ if( iFuncTerm>=0 ){
+ pIdxInfo->idxNum = idxNum;
+ pIdxInfo->idxStr = "rtree";
+ pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0;
+ pIdxInfo->estimatedCost = 300.0;
+ pIdxInfo->estimatedRows = 10;
+ return SQLITE_OK;
+ }
+ pIdxInfo->idxNum = 4;
+ pIdxInfo->idxStr = "fullscan";
+ pIdxInfo->estimatedCost = 3000000.0;
+ pIdxInfo->estimatedRows = 100000;
+ return SQLITE_OK;
+}
+
+
+/*
+** GEOPOLY virtual table module xColumn method.
+*/
+static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
+ Rtree *pRtree = (Rtree *)cur->pVtab;
+ RtreeCursor *pCsr = (RtreeCursor *)cur;
+ RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
+ int rc = SQLITE_OK;
+ RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
+
+ if( rc ) return rc;
+ if( p==0 ) return SQLITE_OK;
+ if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK;
+ if( i<=pRtree->nAux ){
+ if( !pCsr->bAuxValid ){
+ if( pCsr->pReadAux==0 ){
+ rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
+ &pCsr->pReadAux, 0);
+ if( rc ) return rc;
+ }
+ sqlite3_bind_int64(pCsr->pReadAux, 1,
+ nodeGetRowid(pRtree, pNode, p->iCell));
+ rc = sqlite3_step(pCsr->pReadAux);
+ if( rc==SQLITE_ROW ){
+ pCsr->bAuxValid = 1;
+ }else{
+ sqlite3_reset(pCsr->pReadAux);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ return rc;
+ }
+ }
+ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2));
+ }
+ return SQLITE_OK;
+}
+
+
+/*
+** The xUpdate method for GEOPOLY module virtual tables.
+**
+** For DELETE:
+**
+** argv[0] = the rowid to be deleted
+**
+** For INSERT:
+**
+** argv[0] = SQL NULL
+** argv[1] = rowid to insert, or an SQL NULL to select automatically
+** argv[2] = _shape column
+** argv[3] = first application-defined column....
+**
+** For UPDATE:
+**
+** argv[0] = rowid to modify. Never NULL
+** argv[1] = rowid after the change. Never NULL
+** argv[2] = new value for _shape
+** argv[3] = new value for first application-defined column....
+*/
+static int geopolyUpdate(
+ sqlite3_vtab *pVtab,
+ int nData,
+ sqlite3_value **aData,
+ sqlite_int64 *pRowid
+){
+ Rtree *pRtree = (Rtree *)pVtab;
+ int rc = SQLITE_OK;
+ RtreeCell cell; /* New cell to insert if nData>1 */
+ i64 oldRowid; /* The old rowid */
+ int oldRowidValid; /* True if oldRowid is valid */
+ i64 newRowid; /* The new rowid */
+ int newRowidValid; /* True if newRowid is valid */
+ int coordChange = 0; /* Change in coordinates */
+
+ if( pRtree->nNodeRef ){
+ /* Unable to write to the btree while another cursor is reading from it,
+ ** since the write might do a rebalance which would disrupt the read
+ ** cursor. */
+ return SQLITE_LOCKED_VTAB;
+ }
+ rtreeReference(pRtree);
+ assert(nData>=1);
+
+ oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;;
+ oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0;
+ newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL;
+ newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0;
+ cell.iRowid = newRowid;
+
+ if( nData>1 /* not a DELETE */
+ && (!oldRowidValid /* INSERT */
+ || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
+ || oldRowid!=newRowid) /* Rowid change */
+ ){
+ geopolyBBox(0, aData[2], cell.aCoord, &rc);
+ if( rc ){
+ if( rc==SQLITE_ERROR ){
+ pVtab->zErrMsg =
+ sqlite3_mprintf("_shape does not contain a valid polygon");
+ }
+ goto geopoly_update_end;
+ }
+ coordChange = 1;
+
+ /* If a rowid value was supplied, check if it is already present in
+ ** the table. If so, the constraint has failed. */
+ if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){
+ int steprc;
+ sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
+ steprc = sqlite3_step(pRtree->pReadRowid);
+ rc = sqlite3_reset(pRtree->pReadRowid);
+ if( SQLITE_ROW==steprc ){
+ if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
+ rc = rtreeDeleteRowid(pRtree, cell.iRowid);
+ }else{
+ rc = rtreeConstraintError(pRtree, 0);
+ }
+ }
+ }
+ }
+
+ /* If aData[0] is not an SQL NULL value, it is the rowid of a
+ ** record to delete from the r-tree table. The following block does
+ ** just that.
+ */
+ if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){
+ rc = rtreeDeleteRowid(pRtree, oldRowid);
+ }
+
+ /* If the aData[] array contains more than one element, elements
+ ** (aData[2]..aData[argc-1]) contain a new record to insert into
+ ** the r-tree structure.
+ */
+ if( rc==SQLITE_OK && nData>1 && coordChange ){
+ /* Insert the new record into the r-tree */
+ RtreeNode *pLeaf = 0;
+ if( !newRowidValid ){
+ rc = rtreeNewRowid(pRtree, &cell.iRowid);
+ }
+ *pRowid = cell.iRowid;
+ if( rc==SQLITE_OK ){
+ rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
+ }
+ if( rc==SQLITE_OK ){
+ int rc2;
+ pRtree->iReinsertHeight = -1;
+ rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
+ rc2 = nodeRelease(pRtree, pLeaf);
+ if( rc==SQLITE_OK ){
+ rc = rc2;
+ }
+ }
+ }
+
+ /* Change the data */
+ if( rc==SQLITE_OK && nData>1 ){
+ sqlite3_stmt *pUp = pRtree->pWriteAux;
+ int jj;
+ int nChange = 0;
+ sqlite3_bind_int64(pUp, 1, cell.iRowid);
+ assert( pRtree->nAux>=1 );
+ if( sqlite3_value_nochange(aData[2]) ){
+ sqlite3_bind_null(pUp, 2);
+ }else{
+ sqlite3_bind_value(pUp, 2, aData[2]);
+ nChange = 1;
+ }
+ for(jj=1; jj<pRtree->nAux; jj++){
+ nChange++;
+ sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
+ }
+ if( nChange ){
+ sqlite3_step(pUp);
+ rc = sqlite3_reset(pUp);
+ }
+ }
+
+geopoly_update_end:
+ rtreeRelease(pRtree);
+ return rc;
+}
+
+/*
+** Report that geopoly_overlap() is an overloaded function suitable
+** for use in xBestIndex.
+*/
+static int geopolyFindFunction(
+ sqlite3_vtab *pVtab,
+ int nArg,
+ const char *zName,
+ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+ void **ppArg
+){
+ if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){
+ *pxFunc = geopolyOverlapFunc;
+ *ppArg = 0;
+ return SQLITE_INDEX_CONSTRAINT_FUNCTION;
+ }
+ if( sqlite3_stricmp(zName, "geopoly_within")==0 ){
+ *pxFunc = geopolyWithinFunc;
+ *ppArg = 0;
+ return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
+ }
+ return 0;
+}
+
+
+static sqlite3_module geopolyModule = {
+ 2, /* iVersion */
+ geopolyCreate, /* xCreate - create a table */
+ geopolyConnect, /* xConnect - connect to an existing table */
+ geopolyBestIndex, /* xBestIndex - Determine search strategy */
+ rtreeDisconnect, /* xDisconnect - Disconnect from a table */
+ rtreeDestroy, /* xDestroy - Drop a table */
+ rtreeOpen, /* xOpen - open a cursor */
+ rtreeClose, /* xClose - close a cursor */
+ geopolyFilter, /* xFilter - configure scan constraints */
+ rtreeNext, /* xNext - advance a cursor */
+ rtreeEof, /* xEof */
+ geopolyColumn, /* xColumn - read data */
+ rtreeRowid, /* xRowid - read data */
+ geopolyUpdate, /* xUpdate - write data */
+ rtreeBeginTransaction, /* xBegin - begin transaction */
+ rtreeEndTransaction, /* xSync - sync transaction */
+ rtreeEndTransaction, /* xCommit - commit transaction */
+ rtreeEndTransaction, /* xRollback - rollback transaction */
+ geopolyFindFunction, /* xFindFunction - function overloading */
+ rtreeRename, /* xRename - rename the table */
+ rtreeSavepoint, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
+};
+
+static int sqlite3_geopoly_init(sqlite3 *db){
+ int rc = SQLITE_OK;
+ static const struct {
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+ int nArg;
+ const char *zName;
+ } aFunc[] = {
+ { geopolyAreaFunc, 1, "geopoly_area" },
+ { geopolyBlobFunc, 1, "geopoly_blob" },
+ { geopolyJsonFunc, 1, "geopoly_json" },
+ { geopolySvgFunc, -1, "geopoly_svg" },
+ { geopolyWithinFunc, 2, "geopoly_within" },
+ { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
+ { geopolyOverlapFunc, 2, "geopoly_overlap" },
+ { geopolyDebugFunc, 1, "geopoly_debug" },
+ { geopolyBBoxFunc, 1, "geopoly_bbox" },
+ { geopolyXformFunc, 7, "geopoly_xform" },
+ };
+ static const struct {
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+ void (*xFinal)(sqlite3_context*);
+ const char *zName;
+ } aAgg[] = {
+ { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
+ };
+ int i;
+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
+ SQLITE_UTF8, 0,
+ aFunc[i].xFunc, 0, 0);
+ }
+ for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
+ 0, aAgg[i].xStep, aAgg[i].xFinal);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0);
+ }
+ return rc;
+}
+
+/************** End of geopoly.c *********************************************/
+/************** Continuing where we left off in rtree.c **********************/
+#endif
+
+/*
** Register the r-tree module with database handle db. This creates the
** virtual table module "rtree" and the debugging/analysis scalar
** function "rtreenode".
@@ -169574,6 +184427,9 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
}
if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0);
+ }
+ if( rc==SQLITE_OK ){
#ifdef SQLITE_RTREE_INT_ONLY
void *c = (void *)RTREE_COORD_INT32;
#else
@@ -169585,6 +184441,11 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
void *c = (void *)RTREE_COORD_INT32;
rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
}
+#ifdef SQLITE_ENABLE_GEOPOLY
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_geopoly_init(db);
+ }
+#endif
return rc;
}
@@ -169759,7 +184620,9 @@ SQLITE_API int sqlite3_rtree_init(
** provide case-independent matching.
*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+#if !defined(SQLITE_CORE) \
+ || defined(SQLITE_ENABLE_ICU) \
+ || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/* Include ICU headers */
#include <unicode/utypes.h>
@@ -169777,6 +184640,26 @@ SQLITE_API int sqlite3_rtree_init(
#endif
/*
+** This function is called when an ICU function called from within
+** the implementation of an SQL scalar function returns an error.
+**
+** The scalar function context passed as the first argument is
+** loaded with an error message based on the following two args.
+*/
+static void icuFunctionError(
+ sqlite3_context *pCtx, /* SQLite scalar function context */
+ const char *zName, /* Name of ICU function that failed */
+ UErrorCode e /* Error code returned by ICU function */
+){
+ char zBuf[128];
+ sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
+ zBuf[127] = '\0';
+ sqlite3_result_error(pCtx, zBuf, -1);
+}
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+
+/*
** Maximum length (in bytes) of the pattern in a LIKE or GLOB
** operator.
*/
@@ -169956,24 +184839,6 @@ static void icuLikeFunc(
}
/*
-** This function is called when an ICU function called from within
-** the implementation of an SQL scalar function returns an error.
-**
-** The scalar function context passed as the first argument is
-** loaded with an error message based on the following two args.
-*/
-static void icuFunctionError(
- sqlite3_context *pCtx, /* SQLite scalar function context */
- const char *zName, /* Name of ICU function that failed */
- UErrorCode e /* Error code returned by ICU function */
-){
- char zBuf[128];
- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
- zBuf[127] = '\0';
- sqlite3_result_error(pCtx, zBuf, -1);
-}
-
-/*
** Function to delete compiled regexp objects. Registered as
** a destructor function with sqlite3_set_auxdata().
*/
@@ -170138,6 +185003,8 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
assert( 0 ); /* Unreachable */
}
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
+
/*
** Collation sequence destructor function. The pCtx argument points to
** a UCollator structure previously allocated using ucol_open().
@@ -170232,6 +185099,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} scalars[] = {
{"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation},
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
{"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc},
{"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
{"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
@@ -170243,10 +185111,10 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
{"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
{"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
{"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
};
int rc = SQLITE_OK;
int i;
-
for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
const struct IcuScalar *p = &scalars[i];
@@ -171303,6 +186171,10 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
**
** RBU_STATE_OALSZ:
** Valid if STAGE==1. The size in bytes of the *-oal file.
+**
+** RBU_STATE_DATATBL:
+** Only valid if STAGE==1. The RBU database name of the table
+** currently being read.
*/
#define RBU_STATE_STAGE 1
#define RBU_STATE_TBL 2
@@ -171313,6 +186185,7 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
#define RBU_STATE_COOKIE 7
#define RBU_STATE_OALSZ 8
#define RBU_STATE_PHASEONESTEP 9
+#define RBU_STATE_DATATBL 10
#define RBU_STAGE_OAL 1
#define RBU_STAGE_MOVE 2
@@ -171355,6 +186228,7 @@ typedef sqlite3_int64 i64;
struct RbuState {
int eStage;
char *zTbl;
+ char *zDataTbl;
char *zIdx;
i64 iWalCksum;
int nRow;
@@ -172956,7 +187830,7 @@ static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){
int iCid = sqlite3_column_int(pXInfo, 1);
int bDesc = sqlite3_column_int(pXInfo, 3);
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
- zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma,
+ zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma,
iCid, pIter->azTblType[iCid], zCollate
);
zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
@@ -173017,7 +187891,7 @@ static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){
** "PRIMARY KEY" to the imposter table column declaration. */
zPk = "PRIMARY KEY ";
}
- zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s",
+ zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s",
zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
(pIter->abNotNull[iCol] ? " NOT NULL" : "")
);
@@ -173418,6 +188292,7 @@ static sqlite3 *rbuOpenDbhandle(
static void rbuFreeState(RbuState *p){
if( p ){
sqlite3_free(p->zTbl);
+ sqlite3_free(p->zDataTbl);
sqlite3_free(p->zIdx);
sqlite3_free(p);
}
@@ -173488,6 +188363,10 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
break;
+ case RBU_STATE_DATATBL:
+ pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+ break;
+
default:
rc = SQLITE_CORRUPT;
break;
@@ -174262,7 +189141,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
"(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
- "(%d, %lld) ",
+ "(%d, %lld), "
+ "(%d, %Q) ",
p->zStateDb,
RBU_STATE_STAGE, eStage,
RBU_STATE_TBL, p->objiter.zTbl,
@@ -174272,7 +189152,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
RBU_STATE_CKPT, p->iWalCksum,
RBU_STATE_COOKIE, (i64)pFd->iCookie,
RBU_STATE_OALSZ, p->iOalSz,
- RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
+ RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
+ RBU_STATE_DATATBL, p->objiter.zDataTbl
)
);
assert( pInsert==0 || rc==SQLITE_OK );
@@ -174528,7 +189409,8 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup
|| rbuStrCompare(pIter->zIdx, pState->zIdx)
- || rbuStrCompare(pIter->zTbl, pState->zTbl)
+ || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl))
+ || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl))
)){
rc = rbuObjIterNext(p, pIter);
}
@@ -176451,7 +191333,7 @@ static void statSizeAndOffset(StatCursor *pCsr){
*/
fd = sqlite3PagerFile(pPager);
x[0] = pCsr->iPageno;
- if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
+ if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
pCsr->iOffset = x[0];
pCsr->szPage = (int)x[1];
}
@@ -176777,17 +191659,24 @@ struct DbpageCursor {
sqlite3_vtab_cursor base; /* Base class. Must be first */
int pgno; /* Current page number */
int mxPgno; /* Last page to visit on this scan */
+ Pager *pPager; /* Pager being read/written */
+ DbPage *pPage1; /* Page 1 of the database */
+ int iDb; /* Index of database to analyze */
+ int szPage; /* Size of each page in bytes */
};
struct DbpageTable {
sqlite3_vtab base; /* Base class. Must be first */
sqlite3 *db; /* The database */
- Pager *pPager; /* Pager being read/written */
- int iDb; /* Index of database to analyze */
- int szPage; /* Size of each page in bytes */
- int nPage; /* Number of pages in the file */
};
+/* Columns */
+#define DBPAGE_COLUMN_PGNO 0
+#define DBPAGE_COLUMN_DATA 1
+#define DBPAGE_COLUMN_SCHEMA 2
+
+
+
/*
** Connect to or create a dbpagevfs virtual table.
*/
@@ -176800,19 +191689,7 @@ static int dbpageConnect(
){
DbpageTable *pTab = 0;
int rc = SQLITE_OK;
- int iDb;
- if( argc>=4 ){
- Token nm;
- sqlite3TokenInit(&nm, (char*)argv[3]);
- iDb = sqlite3FindDb(db, &nm);
- if( iDb<0 ){
- *pzErr = sqlite3_mprintf("no such schema: %s", argv[3]);
- return SQLITE_ERROR;
- }
- }else{
- iDb = 0;
- }
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
if( rc==SQLITE_OK ){
@@ -176822,11 +191699,8 @@ static int dbpageConnect(
assert( rc==SQLITE_OK || pTab==0 );
if( rc==SQLITE_OK ){
- Btree *pBt = db->aDb[iDb].pBt;
memset(pTab, 0, sizeof(DbpageTable));
pTab->db = db;
- pTab->iDb = iDb;
- pTab->pPager = pBt ? sqlite3BtreePager(pBt) : 0;
}
*ppVtab = (sqlite3_vtab*)pTab;
@@ -176844,24 +191718,55 @@ static int dbpageDisconnect(sqlite3_vtab *pVtab){
/*
** idxNum:
**
-** 0 full table scan
-** 1 pgno=?1
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
*/
static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int i;
- pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
+ int iPlan = 0;
+
+ /* If there is a schema= constraint, it must be honored. Report a
+ ** ridiculously large estimated cost if the schema= constraint is
+ ** unavailable
+ */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
+ if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
+ if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( !p->usable ){
+ /* No solution. Use the default SQLITE_BIG_DBL cost */
+ pIdxInfo->estimatedRows = 0x7fffffff;
+ return SQLITE_OK;
+ }
+ iPlan = 2;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
+ /* If we reach this point, it means that either there is no schema=
+ ** constraint (in which case we use the "main" schema) or else the
+ ** schema constraint was accepted. Lower the estimated cost accordingly
+ */
+ pIdxInfo->estimatedCost = 1.0e6;
+
+ /* Check for constraints against pgno */
for(i=0; i<pIdxInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
pIdxInfo->estimatedRows = 1;
pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
pIdxInfo->estimatedCost = 1.0;
- pIdxInfo->idxNum = 1;
- pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
+ iPlan |= 1;
break;
}
}
+ pIdxInfo->idxNum = iPlan;
+
if( pIdxInfo->nOrderBy>=1
&& pIdxInfo->aOrderBy[0].iColumn<=0
&& pIdxInfo->aOrderBy[0].desc==0
@@ -176895,6 +191800,7 @@ static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
*/
static int dbpageClose(sqlite3_vtab_cursor *pCursor){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
sqlite3_free(pCsr);
return SQLITE_OK;
}
@@ -176914,6 +191820,16 @@ static int dbpageEof(sqlite3_vtab_cursor *pCursor){
return pCsr->pgno > pCsr->mxPgno;
}
+/*
+** idxNum:
+**
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
+**
+** idxStr is not used
+*/
static int dbpageFilter(
sqlite3_vtab_cursor *pCursor,
int idxNum, const char *idxStr,
@@ -176921,23 +191837,42 @@ static int dbpageFilter(
){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
- int rc = SQLITE_OK;
- Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
+ int rc;
+ sqlite3 *db = pTab->db;
+ Btree *pBt;
- pTab->szPage = sqlite3BtreeGetPageSize(pBt);
- pTab->nPage = sqlite3BtreeLastPage(pBt);
- if( idxNum==1 ){
- pCsr->pgno = sqlite3_value_int(argv[0]);
- if( pCsr->pgno<1 || pCsr->pgno>pTab->nPage ){
+ /* Default setting is no rows of result */
+ pCsr->pgno = 1;
+ pCsr->mxPgno = 0;
+
+ if( idxNum & 2 ){
+ const char *zSchema;
+ assert( argc>=1 );
+ zSchema = (const char*)sqlite3_value_text(argv[0]);
+ pCsr->iDb = sqlite3FindDbName(db, zSchema);
+ if( pCsr->iDb<0 ) return SQLITE_OK;
+ }else{
+ pCsr->iDb = 0;
+ }
+ pBt = db->aDb[pCsr->iDb].pBt;
+ if( pBt==0 ) return SQLITE_OK;
+ pCsr->pPager = sqlite3BtreePager(pBt);
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+ pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
+ if( idxNum & 1 ){
+ assert( argc>(idxNum>>1) );
+ pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]);
+ if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
pCsr->pgno = 1;
pCsr->mxPgno = 0;
}else{
pCsr->mxPgno = pCsr->pgno;
}
}else{
- pCsr->pgno = 1;
- pCsr->mxPgno = pTab->nPage;
+ assert( pCsr->pgno==1 );
}
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
+ rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0);
return rc;
}
@@ -176947,7 +191882,6 @@ static int dbpageColumn(
int i
){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
- DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
int rc = SQLITE_OK;
switch( i ){
case 0: { /* pgno */
@@ -176956,9 +191890,9 @@ static int dbpageColumn(
}
case 1: { /* data */
DbPage *pDbPage = 0;
- rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
+ rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
- sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage,
+ sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage,
SQLITE_TRANSIENT);
}
sqlite3PagerUnref(pDbPage);
@@ -176966,7 +191900,7 @@ static int dbpageColumn(
}
default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
- sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC);
+ sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC);
break;
}
}
@@ -176986,37 +191920,51 @@ static int dbpageUpdate(
sqlite_int64 *pRowid
){
DbpageTable *pTab = (DbpageTable *)pVtab;
- int pgno;
+ Pgno pgno;
DbPage *pDbPage = 0;
int rc = SQLITE_OK;
char *zErr = 0;
+ const char *zSchema;
+ int iDb;
+ Btree *pBt;
+ Pager *pPager;
+ int szPage;
if( argc==1 ){
zErr = "cannot delete";
goto update_fail;
}
pgno = sqlite3_value_int(argv[0]);
- if( pgno<1 || pgno>pTab->nPage ){
- zErr = "bad page number";
+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
+ zErr = "cannot insert";
goto update_fail;
}
- if( sqlite3_value_int(argv[1])!=pgno ){
- zErr = "cannot insert";
+ zSchema = (const char*)sqlite3_value_text(argv[4]);
+ iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
+ if( iDb<0 ){
+ zErr = "no such schema";
+ goto update_fail;
+ }
+ pBt = pTab->db->aDb[iDb].pBt;
+ if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
+ zErr = "bad page number";
goto update_fail;
}
+ szPage = sqlite3BtreeGetPageSize(pBt);
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
- || sqlite3_value_bytes(argv[3])!=pTab->szPage
+ || sqlite3_value_bytes(argv[3])!=szPage
){
zErr = "bad page value";
goto update_fail;
}
- rc = sqlite3PagerGet(pTab->pPager, pgno, (DbPage**)&pDbPage, 0);
+ pPager = sqlite3BtreePager(pBt);
+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pDbPage);
if( rc==SQLITE_OK ){
memcpy(sqlite3PagerGetData(pDbPage),
sqlite3_value_blob(argv[3]),
- pTab->szPage);
+ szPage);
}
}
sqlite3PagerUnref(pDbPage);
@@ -177028,11 +191976,27 @@ update_fail:
return SQLITE_ERROR;
}
+/* Since we do not know in advance which database files will be
+** written by the sqlite_dbpage virtual table, start a write transaction
+** on them all.
+*/
+static int dbpageBegin(sqlite3_vtab *pVtab){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ sqlite3 *db = pTab->db;
+ int i;
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0);
+ }
+ return SQLITE_OK;
+}
+
+
/*
** Invoke this routine to register the "dbpage" virtual table module
*/
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
- static sqlite3_module dbpage_module = {
+ static const sqlite3_module dbpage_module = {
0, /* iVersion */
dbpageConnect, /* xCreate */
dbpageConnect, /* xConnect */
@@ -177047,7 +192011,7 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
dbpageColumn, /* xColumn - read data */
dbpageRowid, /* xRowid - read data */
dbpageUpdate, /* xUpdate */
- 0, /* xBegin */
+ dbpageBegin, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
@@ -177113,6 +192077,7 @@ struct sqlite3_session {
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_value *pZeroBlob; /* Value containing X'' */
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 */
@@ -177134,7 +192099,7 @@ struct SessionBuffer {
** sqlite3changeset_start_strm()).
*/
struct SessionInput {
- int bNoDiscard; /* If true, discard no data */
+ int bNoDiscard; /* If true, do not discard in InputBuffer() */
int iCurrent; /* Offset in aData[] of current change */
int iNext; /* Offset in aData[] of next change */
u8 *aData; /* Pointer to buffer containing changeset */
@@ -177180,6 +192145,7 @@ struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
int nCol; /* Number of columns in table zName */
+ int bStat1; /* True if this is sqlite_stat1 */
const char **azCol; /* Column names */
u8 *abPK; /* Array of primary key flags */
int nEntry; /* Total number of entries in hash table */
@@ -177297,8 +192263,8 @@ struct SessionTable {
** 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.
+** with PRIMARY KEY columns are omitted. 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".
@@ -177563,6 +192529,7 @@ static int sessionPreupdateHash(
h = sessionHashAppendBlob(h, n, z);
}else{
assert( eType==SQLITE_NULL );
+ assert( pTab->bStat1==0 || i!=1 );
*pbNullPK = 1;
}
}
@@ -177580,7 +192547,7 @@ static int sessionPreupdateHash(
static int sessionSerialLen(u8 *a){
int e = *a;
int n;
- if( e==0 ) return 1;
+ if( e==0 || e==0xFF ) return 1;
if( e==SQLITE_NULL ) return 1;
if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
return sessionVarintGet(&a[1], &n) + 1 + n;
@@ -177660,7 +192627,7 @@ static int sessionChangeEqual(
int n1 = sessionSerialLen(a1);
int n2 = sessionSerialLen(a2);
- if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
+ if( n1!=n2 || memcmp(a1, a2, n1) ){
return 0;
}
a1 += n1;
@@ -177901,9 +192868,8 @@ static int sessionPreupdateEqual(
}else{
z = sqlite3_value_blob(pVal);
}
- if( memcmp(a, z, n) ) return 0;
+ if( n>0 && memcmp(a, z, n) ) return 0;
a += n;
- break;
}
}
}
@@ -177959,9 +192925,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
/*
** 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.
+** zThis, in schema zDb.
**
** 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
@@ -177982,9 +192946,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
** *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.
+** be freed using sqlite3_free() by the caller
*/
static int sessionTableInfo(
sqlite3 *db, /* Database connection */
@@ -178009,7 +192971,23 @@ static int sessionTableInfo(
assert( pazCol && pabPK );
nThis = sqlite3Strlen30(zThis);
- zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+ if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
+ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
+ zPragma = sqlite3_mprintf(
+ "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
+ "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
+ "SELECT 2, 'stat', '', 0, '', 0"
+ );
+ }else if( rc==SQLITE_ERROR ){
+ zPragma = sqlite3_mprintf("");
+ }else{
+ return rc;
+ }
+ }else{
+ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+ }
if( !zPragma ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
@@ -178101,12 +193079,56 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
break;
}
}
+ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
+ pTab->bStat1 = 1;
+ }
}
}
return (pSession->rc || pTab->abPK==0);
}
/*
+** Versions of the four methods in object SessionHook for use with the
+** sqlite_stat1 table. The purpose of this is to substitute a zero-length
+** blob each time a NULL value is read from the "idx" column of the
+** sqlite_stat1 table.
+*/
+typedef struct SessionStat1Ctx SessionStat1Ctx;
+struct SessionStat1Ctx {
+ SessionHook hook;
+ sqlite3_session *pSession;
+};
+static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1Count(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xCount(p->hook.pCtx);
+}
+static int sessionStat1Depth(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xDepth(p->hook.pCtx);
+}
+
+
+/*
** 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.
@@ -178122,6 +193144,7 @@ static void sessionPreupdateOneChange(
int iHash;
int bNull = 0;
int rc = SQLITE_OK;
+ SessionStat1Ctx stat1 = {0};
if( pSession->rc ) return;
@@ -178141,6 +193164,25 @@ static void sessionPreupdateOneChange(
return;
}
+ if( pTab->bStat1 ){
+ stat1.hook = pSession->hook;
+ stat1.pSession = pSession;
+ pSession->hook.pCtx = (void*)&stat1;
+ pSession->hook.xNew = sessionStat1New;
+ pSession->hook.xOld = sessionStat1Old;
+ pSession->hook.xCount = sessionStat1Count;
+ pSession->hook.xDepth = sessionStat1Depth;
+ if( pSession->pZeroBlob==0 ){
+ sqlite3_value *p = sqlite3ValueNew(0);
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ goto error_out;
+ }
+ sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
+ pSession->pZeroBlob = p;
+ }
+ }
+
/* 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. */
@@ -178230,6 +193272,9 @@ static void sessionPreupdateOneChange(
/* If an error has occurred, mark the session object as failed. */
error_out:
+ if( pTab->bStat1 ){
+ pSession->hook = stat1.hook;
+ }
if( rc!=SQLITE_OK ){
pSession->rc = rc;
}
@@ -178566,7 +193611,6 @@ SQLITE_API int sqlite3session_diff(
if( abPK[i] ) bHasPk = 1;
}
}
-
}
sqlite3_free((char*)azCol);
if( bMismatch ){
@@ -178692,6 +193736,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
}
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
+ sqlite3ValueFree(pSession->pZeroBlob);
/* Delete all attached table objects. And the contents of their
** associated hash-tables. */
@@ -179159,28 +194204,42 @@ static int sessionSelectStmt(
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
- int i;
- const char *zSep = "";
- SessionBuffer buf = {0, 0, 0};
+ char *zSql = 0;
+ int nSql = -1;
- 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( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
+ zSql = sqlite3_mprintf(
+ "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
+ "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
+ );
+ if( zSql==0 ) rc = SQLITE_NOMEM;
+ }else{
+ 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, " IS ?", &rc);
+ sessionAppendInteger(&buf, i+1, &rc);
+ zSep = " AND ";
+ }
}
+ zSql = (char*)buf.aBuf;
+ nSql = buf.nBuf;
}
+
if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
+ rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
- sqlite3_free(buf.aBuf);
+ sqlite3_free(zSql);
return rc;
}
@@ -179563,7 +194622,7 @@ SQLITE_API int sqlite3changeset_start_strm(
** 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 ){
+ if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
int nMove = pIn->buf.nBuf - pIn->iNext;
assert( nMove>=0 );
if( nMove>0 ){
@@ -179691,13 +194750,16 @@ static int sessionReadRecord(
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( pIn->iNext>=pIn->nData ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ 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 ){
@@ -179707,10 +194769,14 @@ static int sessionReadRecord(
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);
+ if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
+ rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
+ pIn->iNext += nByte;
+ }
}
- pIn->iNext += nByte;
}
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
sqlite3_int64 v = sessionGetI64(aVal);
@@ -179750,8 +194816,19 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
rc = sessionInputBuffer(pIn, 9);
if( rc==SQLITE_OK ){
nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
- rc = sessionInputBuffer(pIn, nRead+nCol+100);
- nRead += nCol;
+ /* The hard upper limit for the number of columns in an SQLite
+ ** database table is, according to sqliteLimit.h, 32676. So
+ ** consider any table-header that purports to have more than 65536
+ ** columns to be corrupt. This is convenient because otherwise,
+ ** if the (nCol>65536) condition below were omitted, a sufficiently
+ ** large value for nCol may cause nRead to wrap around and become
+ ** negative. Leading to a crash. */
+ if( nCol<0 || nCol>65536 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ rc = sessionInputBuffer(pIn, nRead+nCol+100);
+ nRead += nCol;
+ }
}
while( rc==SQLITE_OK ){
@@ -179828,11 +194905,15 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
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( p->nCol>0 ){
+ nCopy -= nVarint;
+ p->in.iNext += nVarint;
+ nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
+ p->tblhdr.nBuf = 0;
+ sessionBufferGrow(&p->tblhdr, nByte, &rc);
+ }else{
+ rc = SQLITE_CORRUPT_BKPT;
+ }
}
if( rc==SQLITE_OK ){
@@ -179867,7 +194948,8 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
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 *pnRec, /* If non-NULL, store size of record here */
+ int *pbNew /* If non-NULL, true if new table */
){
int i;
u8 op;
@@ -179902,6 +194984,7 @@ static int sessionChangesetNext(
op = p->in.aData[p->in.iNext++];
while( op=='T' || op=='P' ){
+ if( pbNew ) *pbNew = 1;
p->bPatchset = (op=='P');
if( sessionChangesetReadTblhdr(p) ) return p->rc;
if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
@@ -179910,6 +194993,13 @@ static int sessionChangesetNext(
op = p->in.aData[p->in.iNext++];
}
+ if( p->zTab==0 ){
+ /* The first record in the changeset is not a table header. Must be a
+ ** corrupt changeset. */
+ assert( p->in.iNext==1 );
+ return (p->rc = SQLITE_CORRUPT_BKPT);
+ }
+
p->op = op;
p->bIndirect = p->in.aData[p->in.iNext++];
if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
@@ -179952,9 +195042,9 @@ static int sessionChangesetNext(
** 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];
+ if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
p->apValue[i+p->nCol] = 0;
}
}
@@ -179973,7 +195063,7 @@ static int sessionChangesetNext(
** callback by changeset_apply().
*/
SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
- return sessionChangesetNext(p, 0, 0);
+ return sessionChangesetNext(p, 0, 0, 0);
}
/*
@@ -180349,9 +195439,11 @@ struct SessionApplyCtx {
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 bStat1; /* True if table is sqlite_stat1 */
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
+ SessionBuffer rebase; /* Rebase information (if any) here */
+ int bRebaseStarted; /* If table header is already in rebase */
};
/*
@@ -180519,6 +195611,7 @@ static int sessionUpdateRow(
return rc;
}
+
/*
** Formulate and prepare an SQL statement to query table zTab by primary
** key. Assuming the following table structure:
@@ -180580,6 +195673,46 @@ static int sessionInsertRow(
return rc;
}
+static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
+ return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
+}
+
+/*
+** Prepare statements for applying changes to the sqlite_stat1 table.
+** These are similar to those created by sessionSelectRow(),
+** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
+** other tables.
+*/
+static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
+ int rc = sessionSelectRow(db, "sqlite_stat1", p);
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pInsert,
+ "INSERT INTO main.sqlite_stat1 VALUES(?1, "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
+ "?3)"
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pUpdate,
+ "UPDATE main.sqlite_stat1 SET "
+ "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
+ "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
+ "stat = CASE WHEN ?8 THEN ?9 ELSE stat END "
+ "WHERE tbl=?1 AND idx IS "
+ "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
+ "AND (?10 OR ?8=0 OR stat IS ?7)"
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pDelete,
+ "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
+ "AND (?4 OR stat IS ?3)"
+ );
+ }
+ return rc;
+}
+
/*
** A wrapper around sqlite3_bind_value() that detects an extra problem.
** See comments in the body of this function for details.
@@ -180637,7 +195770,13 @@ static int sessionBindRow(
if( !abPK || abPK[i] ){
sqlite3_value *pVal;
(void)xValue(pIter, i, &pVal);
- rc = sessionBindValue(pStmt, i+1, pVal);
+ if( pVal==0 ){
+ /* The value in the changeset was "undefined". This indicates a
+ ** corrupt changeset blob. */
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ rc = sessionBindValue(pStmt, i+1, pVal);
+ }
}
}
return rc;
@@ -180686,6 +195825,54 @@ static int sessionSeekToRow(
}
/*
+** This function is called from within sqlite3changset_apply_v2() when
+** a conflict is encountered and resolved using conflict resolution
+** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
+** It adds a conflict resolution record to the buffer in
+** SessionApplyCtx.rebase, which will eventually be returned to the caller
+** of apply_v2() as the "rebase" buffer.
+**
+** Return SQLITE_OK if successful, or an SQLite error code otherwise.
+*/
+static int sessionRebaseAdd(
+ SessionApplyCtx *p, /* Apply context */
+ int eType, /* Conflict resolution (OMIT or REPLACE) */
+ sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
+){
+ int rc = SQLITE_OK;
+ int i;
+ int eOp = pIter->op;
+ if( p->bRebaseStarted==0 ){
+ /* Append a table-header to the rebase buffer */
+ const char *zTab = pIter->zTab;
+ sessionAppendByte(&p->rebase, 'T', &rc);
+ sessionAppendVarint(&p->rebase, p->nCol, &rc);
+ sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
+ sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
+ p->bRebaseStarted = 1;
+ }
+
+ assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
+ assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
+
+ sessionAppendByte(&p->rebase,
+ (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
+ );
+ sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
+ for(i=0; i<p->nCol; i++){
+ sqlite3_value *pVal = 0;
+ if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
+ sqlite3changeset_old(pIter, i, &pVal);
+ }else{
+ sqlite3changeset_new(pIter, i, &pVal);
+ }
+ sessionAppendValue(&p->rebase, pVal, &rc);
+ }
+
+ return rc;
+}
+
+/*
** Invoke the conflict handler for the change that the changeset iterator
** currently points to.
**
@@ -180760,7 +195947,7 @@ static int sessionConflictHandler(
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;
+ return SQLITE_OK;
}else{
/* No other row with the new.* primary key. */
res = xConflict(pCtx, eType+1, pIter);
@@ -180786,6 +195973,9 @@ static int sessionConflictHandler(
rc = SQLITE_MISUSE;
break;
}
+ if( rc==SQLITE_OK ){
+ rc = sessionRebaseAdd(p, res, pIter);
+ }
}
return rc;
@@ -180910,11 +196100,25 @@ static int sessionApplyOneOp(
}else{
assert( op==SQLITE_INSERT );
- rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
- if( rc!=SQLITE_OK ) return rc;
+ if( p->bStat1 ){
+ /* Check if there is a conflicting row. For sqlite_stat1, this needs
+ ** to be done using a SELECT, as there is no PRIMARY KEY in the
+ ** database schema to throw an exception if a duplicate is inserted. */
+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_CONSTRAINT;
+ sqlite3_reset(p->pSelect);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_step(p->pInsert);
+ rc = sqlite3_reset(p->pInsert);
+ }
- sqlite3_step(p->pInsert);
- rc = sqlite3_reset(p->pInsert);
if( (rc&0xff)==SQLITE_CONSTRAINT ){
rc = sessionConflictHandler(
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
@@ -180947,42 +196151,42 @@ static int sessionApplyOneWithRetry(
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 ){
+ if( rc==SQLITE_OK ){
+ /* 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( rc==SQLITE_OK ){
- rc = sqlite3_exec(db, "RELEASE replace_op", 0, 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);
+ }
}
}
@@ -181058,10 +196262,12 @@ static int sessionChangesetApply(
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
- void *pCtx /* First argument passed to xConflict */
+ void *pCtx, /* First argument passed to xConflict */
+ void **ppRebase, int *pnRebase, /* OUT: Rebase information */
+ int flags /* SESSION_APPLY_XXX flags */
){
int schemaMismatch = 0;
- int rc; /* Return code */
+ int rc = SQLITE_OK; /* Return code */
const char *zTab = 0; /* Name of current table */
int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
SessionApplyCtx sApply; /* changeset_apply() context object */
@@ -181072,7 +196278,9 @@ static int sessionChangesetApply(
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( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
+ 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);
}
@@ -181096,9 +196304,18 @@ static int sessionChangesetApply(
sqlite3_finalize(sApply.pUpdate);
sqlite3_finalize(sApply.pInsert);
sqlite3_finalize(sApply.pSelect);
- memset(&sApply, 0, sizeof(sApply));
sApply.db = db;
+ sApply.pDelete = 0;
+ sApply.pUpdate = 0;
+ sApply.pInsert = 0;
+ sApply.pSelect = 0;
+ sApply.nCol = 0;
+ sApply.azCol = 0;
+ sApply.abPK = 0;
+ sApply.bStat1 = 0;
sApply.bDeferConstraints = 1;
+ sApply.bRebaseStarted = 0;
+ memset(&sApply.constraints, 0, sizeof(SessionBuffer));
/* If an xFilter() callback was specified, invoke it now. If the
** xFilter callback returns zero, skip this table. If it returns
@@ -181147,12 +196364,20 @@ static int sessionChangesetApply(
}
else{
sApply.nCol = nCol;
- if((rc = sessionSelectRow(db, zTab, &sApply))
- || (rc = sessionUpdateRow(db, zTab, &sApply))
- || (rc = sessionDeleteRow(db, zTab, &sApply))
- || (rc = sessionInsertRow(db, zTab, &sApply))
- ){
- break;
+ if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
+ if( (rc = sessionStat1Sql(db, &sApply) ) ){
+ break;
+ }
+ sApply.bStat1 = 1;
+ }else{
+ if((rc = sessionSelectRow(db, zTab, &sApply))
+ || (rc = sessionUpdateRow(db, zTab, &sApply))
+ || (rc = sessionDeleteRow(db, zTab, &sApply))
+ || (rc = sessionInsertRow(db, zTab, &sApply))
+ ){
+ break;
+ }
+ sApply.bStat1 = 0;
}
}
nTab = sqlite3Strlen30(zTab);
@@ -181193,24 +196418,63 @@ static int sessionChangesetApply(
}
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);
+ if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==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);
+ }
}
+ if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
+ *ppRebase = (void*)sApply.rebase.aBuf;
+ *pnRebase = sApply.rebase.nBuf;
+ sApply.rebase.aBuf = 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_free((char*)sApply.rebase.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".
+*/
+SQLITE_API int sqlite3changeset_apply_v2(
+ 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 */
+ void **ppRebase, int *pnRebase,
+ int flags
+){
+ 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, ppRebase, pnRebase, flags
+ );
+ }
+ 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.
@@ -181230,12 +196494,9 @@ SQLITE_API int sqlite3changeset_apply(
),
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;
+ return sqlite3changeset_apply_v2(
+ db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
+ );
}
/*
@@ -181243,7 +196504,7 @@ SQLITE_API int sqlite3changeset_apply(
** attached to handle "db". Invoke the supplied conflict handler callback
** to resolve any conflicts encountered while applying the change.
*/
-SQLITE_API int sqlite3changeset_apply_strm(
+SQLITE_API int sqlite3changeset_apply_v2_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 */
@@ -181256,15 +196517,38 @@ SQLITE_API int sqlite3changeset_apply_strm(
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
- void *pCtx /* First argument passed to xConflict */
+ void *pCtx, /* First argument passed to xConflict */
+ void **ppRebase, int *pnRebase,
+ int flags
){
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);
+ rc = sessionChangesetApply(
+ db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
+ );
}
return rc;
}
+SQLITE_API 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 */
+){
+ return sqlite3changeset_apply_v2_strm(
+ db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
+ );
+}
/*
** sqlite3_changegroup handle.
@@ -181282,6 +196566,7 @@ struct sqlite3_changegroup {
*/
static int sessionChangeMerge(
SessionTable *pTab, /* Table structure */
+ int bRebase, /* True for a rebase hash-table */
int bPatchset, /* True for patchsets */
SessionChange *pExist, /* Existing change */
int op2, /* Second change operation */
@@ -181291,6 +196576,7 @@ static int sessionChangeMerge(
SessionChange **ppNew /* OUT: Merged change */
){
SessionChange *pNew = 0;
+ int rc = SQLITE_OK;
if( !pExist ){
pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
@@ -181300,9 +196586,66 @@ static int sessionChangeMerge(
memset(pNew, 0, sizeof(SessionChange));
pNew->op = op2;
pNew->bIndirect = bIndirect;
- pNew->nRecord = nRec;
pNew->aRecord = (u8*)&pNew[1];
- memcpy(pNew->aRecord, aRec, nRec);
+ if( bIndirect==0 || bRebase==0 ){
+ pNew->nRecord = nRec;
+ memcpy(pNew->aRecord, aRec, nRec);
+ }else{
+ int i;
+ u8 *pIn = aRec;
+ u8 *pOut = pNew->aRecord;
+ for(i=0; i<pTab->nCol; i++){
+ int nIn = sessionSerialLen(pIn);
+ if( *pIn==0 ){
+ *pOut++ = 0;
+ }else if( pTab->abPK[i]==0 ){
+ *pOut++ = 0xFF;
+ }else{
+ memcpy(pOut, pIn, nIn);
+ pOut += nIn;
+ }
+ pIn += nIn;
+ }
+ pNew->nRecord = pOut - pNew->aRecord;
+ }
+ }else if( bRebase ){
+ if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
+ *ppNew = pExist;
+ }else{
+ int nByte = nRec + pExist->nRecord + sizeof(SessionChange);
+ pNew = (SessionChange*)sqlite3_malloc(nByte);
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int i;
+ u8 *a1 = pExist->aRecord;
+ u8 *a2 = aRec;
+ u8 *pOut;
+
+ memset(pNew, 0, nByte);
+ pNew->bIndirect = bIndirect || pExist->bIndirect;
+ pNew->op = op2;
+ pOut = pNew->aRecord = (u8*)&pNew[1];
+
+ for(i=0; i<pTab->nCol; i++){
+ int n1 = sessionSerialLen(a1);
+ int n2 = sessionSerialLen(a2);
+ if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){
+ *pOut++ = 0xFF;
+ }else if( *a2==0 ){
+ memcpy(pOut, a1, n1);
+ pOut += n1;
+ }else{
+ memcpy(pOut, a2, n2);
+ pOut += n2;
+ }
+ a1 += n1;
+ a2 += n2;
+ }
+ pNew->nRecord = pOut - pNew->aRecord;
+ }
+ sqlite3_free(pExist);
+ }
}else{
int op1 = pExist->op;
@@ -181396,7 +196739,7 @@ static int sessionChangeMerge(
}
*ppNew = pNew;
- return SQLITE_OK;
+ return rc;
}
/*
@@ -181405,15 +196748,15 @@ static int sessionChangeMerge(
*/
static int sessionChangesetToHash(
sqlite3_changeset_iter *pIter, /* Iterator to read from */
- sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */
+ sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
+ int bRebase /* True if hash table is for rebasing */
){
u8 *aRec;
int nRec;
int rc = SQLITE_OK;
SessionTable *pTab = 0;
-
- while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){
+ while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
const char *zNew;
int nCol;
int op;
@@ -181493,7 +196836,7 @@ static int sessionChangesetToHash(
}
}
- rc = sessionChangeMerge(pTab,
+ rc = sessionChangeMerge(pTab, bRebase,
pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
);
if( rc ) break;
@@ -181601,7 +196944,7 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void
rc = sqlite3changeset_start(&pIter, nData, pData);
if( rc==SQLITE_OK ){
- rc = sessionChangesetToHash(pIter, pGrp);
+ rc = sessionChangesetToHash(pIter, pGrp, 0);
}
sqlite3changeset_finalize(pIter);
return rc;
@@ -181632,7 +196975,7 @@ SQLITE_API int sqlite3changegroup_add_strm(
rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
if( rc==SQLITE_OK ){
- rc = sessionChangesetToHash(pIter, pGrp);
+ rc = sessionChangesetToHash(pIter, pGrp, 0);
}
sqlite3changeset_finalize(pIter);
return rc;
@@ -181717,2438 +197060,352 @@ SQLITE_API int sqlite3changeset_concat_strm(
return rc;
}
-#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
-
-/************** End of sqlite3session.c **************************************/
-/************** Begin file json1.c *******************************************/
-/*
-** 2015-08-12
-**
-** 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 SQLite extension implements JSON functions. The interface is
-** modeled after MySQL JSON functions:
-**
-** https://dev.mysql.com/doc/refman/5.7/en/json.html
-**
-** For the time being, all JSON is stored as pure text. (We might add
-** a JSONB type in the future which stores a binary encoding of JSON in
-** a BLOB, but there is no support for JSONB in the current implementation.
-** This implementation parses JSON text at 250 MB/s, so it is hard to see
-** how JSONB might improve on that.)
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
-#if !defined(SQLITEINT_H)
-/* #include "sqlite3ext.h" */
-#endif
-SQLITE_EXTENSION_INIT1
-/* #include <assert.h> */
-/* #include <string.h> */
-/* #include <stdlib.h> */
-/* #include <stdarg.h> */
-
-/* Mark a function parameter as unused, to suppress nuisance compiler
-** warnings. */
-#ifndef UNUSED_PARAM
-# define UNUSED_PARAM(X) (void)(X)
-#endif
-
-#ifndef LARGEST_INT64
-# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
-# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
-#endif
-
-/*
-** Versions of isspace(), isalnum() and isdigit() to which it is safe
-** to pass signed char values.
-*/
-#ifdef sqlite3Isdigit
- /* Use the SQLite core versions if this routine is part of the
- ** SQLite amalgamation */
-# define safe_isdigit(x) sqlite3Isdigit(x)
-# define safe_isalnum(x) sqlite3Isalnum(x)
-# define safe_isxdigit(x) sqlite3Isxdigit(x)
-#else
- /* Use the standard library for separate compilation */
-#include <ctype.h> /* amalgamator: keep */
-# define safe_isdigit(x) isdigit((unsigned char)(x))
-# define safe_isalnum(x) isalnum((unsigned char)(x))
-# define safe_isxdigit(x) isxdigit((unsigned char)(x))
-#endif
-
-/*
-** Growing our own isspace() routine this way is twice as fast as
-** the library isspace() function, resulting in a 7% overall performance
-** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
-*/
-static const char jsonIsSpace[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
-
-#ifndef SQLITE_AMALGAMATION
- /* Unsigned integer types. These are already defined in the sqliteInt.h,
- ** but the definitions need to be repeated for separate compilation. */
- typedef unsigned int u32;
- typedef unsigned short int u16;
- typedef unsigned char u8;
-#endif
-
-/* Objects */
-typedef struct JsonString JsonString;
-typedef struct JsonNode JsonNode;
-typedef struct JsonParse JsonParse;
-
-/* An instance of this object represents a JSON string
-** under construction. Really, this is a generic string accumulator
-** that can be and is used to create strings other than JSON.
-*/
-struct JsonString {
- sqlite3_context *pCtx; /* Function context - put error messages here */
- char *zBuf; /* Append JSON content here */
- size_t nAlloc; /* Bytes of storage available in zBuf[] */
- size_t nUsed; /* Bytes of zBuf[] currently used */
- u8 bStatic; /* True if zBuf is static space */
- u8 bErr; /* True if an error has been encountered */
- char zSpace[100]; /* Initial static space */
-};
-
-/* JSON type values
-*/
-#define JSON_NULL 0
-#define JSON_TRUE 1
-#define JSON_FALSE 2
-#define JSON_INT 3
-#define JSON_REAL 4
-#define JSON_STRING 5
-#define JSON_ARRAY 6
-#define JSON_OBJECT 7
-
-/* The "subtype" set for JSON values */
-#define JSON_SUBTYPE 74 /* Ascii for "J" */
-
/*
-** Names of the various JSON types:
-*/
-static const char jsonType[][8] = {
- "null", "true", "false", "integer", "real", "text", "array", "object"
-};
-
-/* Bit values for the JsonNode.jnFlag field
-*/
-#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
-#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
-#define JNODE_REMOVE 0x04 /* Do not output */
-#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
-#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
-#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
-#define JNODE_LABEL 0x40 /* Is a label of an object */
-
-
-/* A single node of parsed JSON
-*/
-struct JsonNode {
- u8 eType; /* One of the JSON_ type values */
- u8 jnFlags; /* JNODE flags */
- u32 n; /* Bytes of content, or number of sub-nodes */
- union {
- const char *zJContent; /* Content for INT, REAL, and STRING */
- u32 iAppend; /* More terms for ARRAY and OBJECT */
- u32 iKey; /* Key for ARRAY objects in json_tree() */
- u32 iReplace; /* Replacement content for JNODE_REPLACE */
- JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
- } u;
-};
-
-/* A completely parsed JSON string
+** Changeset rebaser handle.
*/
-struct JsonParse {
- u32 nNode; /* Number of slots of aNode[] used */
- u32 nAlloc; /* Number of slots of aNode[] allocated */
- JsonNode *aNode; /* Array of nodes containing the parse */
- const char *zJson; /* Original JSON string */
- u32 *aUp; /* Index of parent of each node */
- u8 oom; /* Set to true if out of memory */
- u8 nErr; /* Number of errors seen */
- u16 iDepth; /* Nesting depth */
- int nJson; /* Length of the zJson string in bytes */
+struct sqlite3_rebaser {
+ sqlite3_changegroup grp; /* Hash table */
};
/*
-** Maximum nesting depth of JSON for this implementation.
-**
-** This limit is needed to avoid a stack overflow in the recursive
-** descent parser. A depth of 2000 is far deeper than any sane JSON
-** should go.
-*/
-#define JSON_MAX_DEPTH 2000
-
-/**************************************************************************
-** Utility routines for dealing with JsonString objects
-**************************************************************************/
-
-/* Set the JsonString object to an empty string
-*/
-static void jsonZero(JsonString *p){
- p->zBuf = p->zSpace;
- p->nAlloc = sizeof(p->zSpace);
- p->nUsed = 0;
- p->bStatic = 1;
-}
-
-/* Initialize the JsonString object
-*/
-static void jsonInit(JsonString *p, sqlite3_context *pCtx){
- p->pCtx = pCtx;
- p->bErr = 0;
- jsonZero(p);
-}
-
-
-/* Free all allocated memory and reset the JsonString object back to its
-** initial state.
-*/
-static void jsonReset(JsonString *p){
- if( !p->bStatic ) sqlite3_free(p->zBuf);
- jsonZero(p);
-}
-
-
-/* Report an out-of-memory (OOM) condition
-*/
-static void jsonOom(JsonString *p){
- p->bErr = 1;
- sqlite3_result_error_nomem(p->pCtx);
- jsonReset(p);
-}
-
-/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
-** Return zero on success. Return non-zero on an OOM error
-*/
-static int jsonGrow(JsonString *p, u32 N){
- size_t nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
- char *zNew;
- if( p->bStatic ){
- if( p->bErr ) return 1;
- zNew = sqlite3_malloc(nTotal);
- if( zNew==0 ){
- jsonOom(p);
- return SQLITE_NOMEM;
- }
- memcpy(zNew, p->zBuf, (size_t)p->nUsed);
- p->zBuf = zNew;
- p->bStatic = 0;
- }else{
- zNew = sqlite3_realloc(p->zBuf, nTotal);
- if( zNew==0 ){
- jsonOom(p);
- return SQLITE_NOMEM;
- }
- p->zBuf = zNew;
- }
- p->nAlloc = nTotal;
- return SQLITE_OK;
-}
-
-/* Append N bytes from zIn onto the end of the JsonString string.
-*/
-static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
- if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
- memcpy(p->zBuf+p->nUsed, zIn, N);
- p->nUsed += N;
-}
-
-/* Append formatted text (not to exceed N bytes) to the JsonString.
-*/
-static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
- va_list ap;
- if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
- va_start(ap, zFormat);
- sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
- va_end(ap);
- p->nUsed += (int)strlen(p->zBuf+p->nUsed);
-}
-
-/* Append a single character
-*/
-static void jsonAppendChar(JsonString *p, char c){
- if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
- p->zBuf[p->nUsed++] = c;
-}
-
-/* Append a comma separator to the output buffer, if the previous
-** character is not '[' or '{'.
-*/
-static void jsonAppendSeparator(JsonString *p){
- char c;
- if( p->nUsed==0 ) return;
- c = p->zBuf[p->nUsed-1];
- if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
-}
-
-/* Append the N-byte string in zIn to the end of the JsonString string
-** under construction. Enclose the string in "..." and escape
-** any double-quotes or backslash characters contained within the
-** string.
-*/
-static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
- u32 i;
- if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
- p->zBuf[p->nUsed++] = '"';
- for(i=0; i<N; i++){
- unsigned char c = ((unsigned const char*)zIn)[i];
- if( c=='"' || c=='\\' ){
- json_simple_escape:
- if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
- p->zBuf[p->nUsed++] = '\\';
- }else if( c<=0x1f ){
- static const char aSpecial[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- assert( sizeof(aSpecial)==32 );
- assert( aSpecial['\b']=='b' );
- assert( aSpecial['\f']=='f' );
- assert( aSpecial['\n']=='n' );
- assert( aSpecial['\r']=='r' );
- assert( aSpecial['\t']=='t' );
- if( aSpecial[c] ){
- c = aSpecial[c];
- goto json_simple_escape;
- }
- if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
- p->zBuf[p->nUsed++] = '\\';
- p->zBuf[p->nUsed++] = 'u';
- p->zBuf[p->nUsed++] = '0';
- p->zBuf[p->nUsed++] = '0';
- p->zBuf[p->nUsed++] = '0' + (c>>4);
- c = "0123456789abcdef"[c&0xf];
- }
- p->zBuf[p->nUsed++] = c;
- }
- p->zBuf[p->nUsed++] = '"';
- assert( p->nUsed<p->nAlloc );
-}
-
-/*
-** Append a function parameter value to the JSON string under
-** construction.
+** Buffers a1 and a2 must both contain a sessions module record nCol
+** fields in size. This function appends an nCol sessions module
+** record to buffer pBuf that is a copy of a1, except that for
+** each field that is undefined in a1[], swap in the field from a2[].
*/
-static void jsonAppendValue(
- JsonString *p, /* Append to this JSON string */
- sqlite3_value *pValue /* Value to append */
+static void sessionAppendRecordMerge(
+ SessionBuffer *pBuf, /* Buffer to append to */
+ int nCol, /* Number of columns in each record */
+ u8 *a1, int n1, /* Record 1 */
+ u8 *a2, int n2, /* Record 2 */
+ int *pRc /* IN/OUT: error code */
){
- switch( sqlite3_value_type(pValue) ){
- case SQLITE_NULL: {
- jsonAppendRaw(p, "null", 4);
- break;
- }
- case SQLITE_INTEGER:
- case SQLITE_FLOAT: {
- const char *z = (const char*)sqlite3_value_text(pValue);
- u32 n = (u32)sqlite3_value_bytes(pValue);
- jsonAppendRaw(p, z, n);
- break;
- }
- case SQLITE_TEXT: {
- const char *z = (const char*)sqlite3_value_text(pValue);
- u32 n = (u32)sqlite3_value_bytes(pValue);
- if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
- jsonAppendRaw(p, z, n);
+ sessionBufferGrow(pBuf, n1+n2, pRc);
+ if( *pRc==SQLITE_OK ){
+ int i;
+ u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
+ for(i=0; i<nCol; i++){
+ int nn1 = sessionSerialLen(a1);
+ int nn2 = sessionSerialLen(a2);
+ if( *a1==0 || *a1==0xFF ){
+ memcpy(pOut, a2, nn2);
+ pOut += nn2;
}else{
- jsonAppendString(p, z, n);
- }
- break;
- }
- default: {
- if( p->bErr==0 ){
- sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
- p->bErr = 2;
- jsonReset(p);
+ memcpy(pOut, a1, nn1);
+ pOut += nn1;
}
- break;
+ a1 += nn1;
+ a2 += nn2;
}
- }
-}
-
-/* Make the JSON in p the result of the SQL function.
-*/
-static void jsonResult(JsonString *p){
- if( p->bErr==0 ){
- sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
- p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
- SQLITE_UTF8);
- jsonZero(p);
+ pBuf->nBuf = pOut-pBuf->aBuf;
+ assert( pBuf->nBuf<=pBuf->nAlloc );
}
- assert( p->bStatic );
}
-/**************************************************************************
-** Utility routines for dealing with JsonNode and JsonParse objects
-**************************************************************************/
-
/*
-** Return the number of consecutive JsonNode slots need to represent
-** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and
-** OBJECT types, the number might be larger.
+** This function is called when rebasing a local UPDATE change against one
+** or more remote UPDATE changes. The aRec/nRec buffer contains the current
+** old.* and new.* records for the change. The rebase buffer (a single
+** record) is in aChange/nChange. The rebased change is appended to buffer
+** pBuf.
**
-** Appended elements are not counted. The value returned is the number
-** by which the JsonNode counter should increment in order to go to the
-** next peer value.
-*/
-static u32 jsonNodeSize(JsonNode *pNode){
- return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
-}
-
-/*
-** Reclaim all memory allocated by a JsonParse object. But do not
-** delete the JsonParse object itself.
-*/
-static void jsonParseReset(JsonParse *pParse){
- sqlite3_free(pParse->aNode);
- pParse->aNode = 0;
- pParse->nNode = 0;
- pParse->nAlloc = 0;
- sqlite3_free(pParse->aUp);
- pParse->aUp = 0;
-}
-
-/*
-** Free a JsonParse object that was obtained from sqlite3_malloc().
-*/
-static void jsonParseFree(JsonParse *pParse){
- jsonParseReset(pParse);
- sqlite3_free(pParse);
-}
-
-/*
-** Convert the JsonNode pNode into a pure JSON string and
-** append to pOut. Subsubstructure is also included. Return
-** the number of JsonNode objects that are encoded.
-*/
-static void jsonRenderNode(
- JsonNode *pNode, /* The node to render */
- JsonString *pOut, /* Write JSON here */
- sqlite3_value **aReplace /* Replacement values */
-){
- if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
- if( pNode->jnFlags & JNODE_REPLACE ){
- jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
- return;
- }
- pNode = pNode->u.pPatch;
- }
- switch( pNode->eType ){
- default: {
- assert( pNode->eType==JSON_NULL );
- jsonAppendRaw(pOut, "null", 4);
- break;
- }
- case JSON_TRUE: {
- jsonAppendRaw(pOut, "true", 4);
- break;
- }
- case JSON_FALSE: {
- jsonAppendRaw(pOut, "false", 5);
- break;
- }
- case JSON_STRING: {
- if( pNode->jnFlags & JNODE_RAW ){
- jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
- break;
- }
- /* Fall through into the next case */
- }
- case JSON_REAL:
- case JSON_INT: {
- jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
- break;
- }
- case JSON_ARRAY: {
- u32 j = 1;
- jsonAppendChar(pOut, '[');
- for(;;){
- while( j<=pNode->n ){
- if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
- jsonAppendSeparator(pOut);
- jsonRenderNode(&pNode[j], pOut, aReplace);
- }
- j += jsonNodeSize(&pNode[j]);
- }
- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
- pNode = &pNode[pNode->u.iAppend];
- j = 1;
- }
- jsonAppendChar(pOut, ']');
- break;
- }
- case JSON_OBJECT: {
- u32 j = 1;
- jsonAppendChar(pOut, '{');
- for(;;){
- while( j<=pNode->n ){
- if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
- jsonAppendSeparator(pOut);
- jsonRenderNode(&pNode[j], pOut, aReplace);
- jsonAppendChar(pOut, ':');
- jsonRenderNode(&pNode[j+1], pOut, aReplace);
- }
- j += 1 + jsonNodeSize(&pNode[j+1]);
- }
- if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
- pNode = &pNode[pNode->u.iAppend];
- j = 1;
- }
- jsonAppendChar(pOut, '}');
- break;
- }
- }
-}
-
-/*
-** Return a JsonNode and all its descendents as a JSON string.
-*/
-static void jsonReturnJson(
- JsonNode *pNode, /* Node to return */
- sqlite3_context *pCtx, /* Return value for this function */
- sqlite3_value **aReplace /* Array of replacement values */
-){
- JsonString s;
- jsonInit(&s, pCtx);
- jsonRenderNode(pNode, &s, aReplace);
- jsonResult(&s);
- sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
-}
-
-/*
-** Make the JsonNode the return value of the function.
-*/
-static void jsonReturn(
- JsonNode *pNode, /* Node to return */
- sqlite3_context *pCtx, /* Return value for this function */
- sqlite3_value **aReplace /* Array of replacement values */
-){
- switch( pNode->eType ){
- default: {
- assert( pNode->eType==JSON_NULL );
- sqlite3_result_null(pCtx);
- break;
- }
- case JSON_TRUE: {
- sqlite3_result_int(pCtx, 1);
- break;
- }
- case JSON_FALSE: {
- sqlite3_result_int(pCtx, 0);
- break;
- }
- case JSON_INT: {
- sqlite3_int64 i = 0;
- const char *z = pNode->u.zJContent;
- if( z[0]=='-' ){ z++; }
- while( z[0]>='0' && z[0]<='9' ){
- unsigned v = *(z++) - '0';
- if( i>=LARGEST_INT64/10 ){
- if( i>LARGEST_INT64/10 ) goto int_as_real;
- if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
- if( v==9 ) goto int_as_real;
- if( v==8 ){
- if( pNode->u.zJContent[0]=='-' ){
- sqlite3_result_int64(pCtx, SMALLEST_INT64);
- goto int_done;
- }else{
- goto int_as_real;
- }
- }
- }
- i = i*10 + v;
- }
- if( pNode->u.zJContent[0]=='-' ){ i = -i; }
- sqlite3_result_int64(pCtx, i);
- int_done:
- break;
- int_as_real: /* fall through to real */;
- }
- case JSON_REAL: {
- double r;
-#ifdef SQLITE_AMALGAMATION
- const char *z = pNode->u.zJContent;
- sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
-#else
- r = strtod(pNode->u.zJContent, 0);
-#endif
- sqlite3_result_double(pCtx, r);
- break;
- }
- case JSON_STRING: {
-#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
- ** json_insert() and json_replace() and those routines do not
- ** call jsonReturn() */
- if( pNode->jnFlags & JNODE_RAW ){
- sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
- SQLITE_TRANSIENT);
- }else
-#endif
- assert( (pNode->jnFlags & JNODE_RAW)==0 );
- if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
- /* JSON formatted without any backslash-escapes */
- sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
- SQLITE_TRANSIENT);
- }else{
- /* Translate JSON formatted string into raw text */
- u32 i;
- u32 n = pNode->n;
- const char *z = pNode->u.zJContent;
- char *zOut;
- u32 j;
- zOut = sqlite3_malloc( n+1 );
- if( zOut==0 ){
- sqlite3_result_error_nomem(pCtx);
- break;
- }
- for(i=1, j=0; i<n-1; i++){
- char c = z[i];
- if( c!='\\' ){
- zOut[j++] = c;
- }else{
- c = z[++i];
- if( c=='u' ){
- u32 v = 0, k;
- for(k=0; k<4; i++, k++){
- assert( i<n-2 );
- c = z[i+1];
- assert( safe_isxdigit(c) );
- if( c<='9' ) v = v*16 + c - '0';
- else if( c<='F' ) v = v*16 + c - 'A' + 10;
- else v = v*16 + c - 'a' + 10;
- }
- if( v==0 ) break;
- if( v<=0x7f ){
- zOut[j++] = (char)v;
- }else if( v<=0x7ff ){
- zOut[j++] = (char)(0xc0 | (v>>6));
- zOut[j++] = 0x80 | (v&0x3f);
- }else{
- zOut[j++] = (char)(0xe0 | (v>>12));
- zOut[j++] = 0x80 | ((v>>6)&0x3f);
- zOut[j++] = 0x80 | (v&0x3f);
- }
- }else{
- if( c=='b' ){
- c = '\b';
- }else if( c=='f' ){
- c = '\f';
- }else if( c=='n' ){
- c = '\n';
- }else if( c=='r' ){
- c = '\r';
- }else if( c=='t' ){
- c = '\t';
- }
- zOut[j++] = c;
- }
- }
- }
- zOut[j] = 0;
- sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
- }
- break;
- }
- case JSON_ARRAY:
- case JSON_OBJECT: {
- jsonReturnJson(pNode, pCtx, aReplace);
- break;
- }
- }
-}
-
-/* Forward reference */
-static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
-
-/*
-** A macro to hint to the compiler that a function should not be
-** inlined.
-*/
-#if defined(__GNUC__)
-# define JSON_NOINLINE __attribute__((noinline))
-#elif defined(_MSC_VER) && _MSC_VER>=1310
-# define JSON_NOINLINE __declspec(noinline)
-#else
-# define JSON_NOINLINE
-#endif
-
-
-static JSON_NOINLINE int jsonParseAddNodeExpand(
- JsonParse *pParse, /* Append the node to this object */
- u32 eType, /* Node type */
- u32 n, /* Content size or sub-node count */
- const char *zContent /* Content */
-){
- u32 nNew;
- JsonNode *pNew;
- assert( pParse->nNode>=pParse->nAlloc );
- if( pParse->oom ) return -1;
- nNew = pParse->nAlloc*2 + 10;
- pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
- if( pNew==0 ){
- pParse->oom = 1;
- return -1;
- }
- pParse->nAlloc = nNew;
- pParse->aNode = pNew;
- assert( pParse->nNode<pParse->nAlloc );
- return jsonParseAddNode(pParse, eType, n, zContent);
-}
-
-/*
-** Create a new JsonNode instance based on the arguments and append that
-** instance to the JsonParse. Return the index in pParse->aNode[] of the
-** new node, or -1 if a memory allocation fails.
-*/
-static int jsonParseAddNode(
- JsonParse *pParse, /* Append the node to this object */
- u32 eType, /* Node type */
- u32 n, /* Content size or sub-node count */
- const char *zContent /* Content */
-){
- JsonNode *p;
- if( pParse->nNode>=pParse->nAlloc ){
- return jsonParseAddNodeExpand(pParse, eType, n, zContent);
- }
- p = &pParse->aNode[pParse->nNode];
- p->eType = (u8)eType;
- p->jnFlags = 0;
- p->n = n;
- p->u.zJContent = zContent;
- return pParse->nNode++;
-}
-
-/*
-** Return true if z[] begins with 4 (or more) hexadecimal digits
-*/
-static int jsonIs4Hex(const char *z){
- int i;
- for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
- return 1;
-}
-
-/*
-** Parse a single JSON value which begins at pParse->zJson[i]. Return the
-** index of the first character past the end of the value parsed.
+** Rebasing the UPDATE involves:
**
-** Return negative for a syntax error. Special cases: return -2 if the
-** first non-whitespace character is '}' and return -3 if the first
-** non-whitespace character is ']'.
-*/
-static int jsonParseValue(JsonParse *pParse, u32 i){
- char c;
- u32 j;
- int iThis;
- int x;
- JsonNode *pNode;
- const char *z = pParse->zJson;
- while( safe_isspace(z[i]) ){ i++; }
- if( (c = z[i])=='{' ){
- /* Parse object */
- iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
- if( iThis<0 ) return -1;
- for(j=i+1;;j++){
- while( safe_isspace(z[j]) ){ j++; }
- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
- x = jsonParseValue(pParse, j);
- if( x<0 ){
- pParse->iDepth--;
- if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
- return -1;
- }
- if( pParse->oom ) return -1;
- pNode = &pParse->aNode[pParse->nNode-1];
- if( pNode->eType!=JSON_STRING ) return -1;
- pNode->jnFlags |= JNODE_LABEL;
- j = x;
- while( safe_isspace(z[j]) ){ j++; }
- if( z[j]!=':' ) return -1;
- j++;
- x = jsonParseValue(pParse, j);
- pParse->iDepth--;
- if( x<0 ) return -1;
- j = x;
- while( safe_isspace(z[j]) ){ j++; }
- c = z[j];
- if( c==',' ) continue;
- if( c!='}' ) return -1;
- break;
- }
- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
- return j+1;
- }else if( c=='[' ){
- /* Parse array */
- iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
- if( iThis<0 ) return -1;
- for(j=i+1;;j++){
- while( safe_isspace(z[j]) ){ j++; }
- if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
- x = jsonParseValue(pParse, j);
- pParse->iDepth--;
- if( x<0 ){
- if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
- return -1;
- }
- j = x;
- while( safe_isspace(z[j]) ){ j++; }
- c = z[j];
- if( c==',' ) continue;
- if( c!=']' ) return -1;
- break;
- }
- pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
- return j+1;
- }else if( c=='"' ){
- /* Parse string */
- u8 jnFlags = 0;
- j = i+1;
- for(;;){
- c = z[j];
- if( (c & ~0x1f)==0 ){
- /* Control characters are not allowed in strings */
- return -1;
- }
- if( c=='\\' ){
- c = z[++j];
- if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
- || c=='n' || c=='r' || c=='t'
- || (c=='u' && jsonIs4Hex(z+j+1)) ){
- jnFlags = JNODE_ESCAPE;
- }else{
- return -1;
- }
- }else if( c=='"' ){
- break;
- }
- j++;
- }
- jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
- if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
- return j+1;
- }else if( c=='n'
- && strncmp(z+i,"null",4)==0
- && !safe_isalnum(z[i+4]) ){
- jsonParseAddNode(pParse, JSON_NULL, 0, 0);
- return i+4;
- }else if( c=='t'
- && strncmp(z+i,"true",4)==0
- && !safe_isalnum(z[i+4]) ){
- jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
- return i+4;
- }else if( c=='f'
- && strncmp(z+i,"false",5)==0
- && !safe_isalnum(z[i+5]) ){
- jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
- return i+5;
- }else if( c=='-' || (c>='0' && c<='9') ){
- /* Parse number */
- u8 seenDP = 0;
- u8 seenE = 0;
- assert( '-' < '0' );
- if( c<='0' ){
- j = c=='-' ? i+1 : i;
- if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
- }
- j = i+1;
- for(;; j++){
- c = z[j];
- if( c>='0' && c<='9' ) continue;
- if( c=='.' ){
- if( z[j-1]=='-' ) return -1;
- if( seenDP ) return -1;
- seenDP = 1;
- continue;
- }
- if( c=='e' || c=='E' ){
- if( z[j-1]<'0' ) return -1;
- if( seenE ) return -1;
- seenDP = seenE = 1;
- c = z[j+1];
- if( c=='+' || c=='-' ){
- j++;
- c = z[j+1];
- }
- if( c<'0' || c>'9' ) return -1;
- continue;
- }
- break;
- }
- if( z[j-1]<'0' ) return -1;
- jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
- j - i, &z[i]);
- return j;
- }else if( c=='}' ){
- return -2; /* End of {...} */
- }else if( c==']' ){
- return -3; /* End of [...] */
- }else if( c==0 ){
- return 0; /* End of file */
- }else{
- return -1; /* Syntax error */
- }
-}
-
-/*
-** Parse a complete JSON string. Return 0 on success or non-zero if there
-** are any errors. If an error occurs, free all memory associated with
-** pParse.
+** * Removing any changes to fields for which the corresponding field
+** in the rebase buffer is set to "replaced" (type 0xFF). If this
+** means the UPDATE change updates no fields, nothing is appended
+** to the output buffer.
**
-** pParse is uninitialized when this routine is called.
-*/
-static int jsonParse(
- JsonParse *pParse, /* Initialize and fill this JsonParse object */
- sqlite3_context *pCtx, /* Report errors here */
- const char *zJson /* Input JSON text to be parsed */
-){
- int i;
- memset(pParse, 0, sizeof(*pParse));
- if( zJson==0 ) return 1;
- pParse->zJson = zJson;
- i = jsonParseValue(pParse, 0);
- if( pParse->oom ) i = -1;
- if( i>0 ){
- assert( pParse->iDepth==0 );
- while( safe_isspace(zJson[i]) ) i++;
- if( zJson[i] ) i = -1;
- }
- if( i<=0 ){
- if( pCtx!=0 ){
- if( pParse->oom ){
- sqlite3_result_error_nomem(pCtx);
- }else{
- sqlite3_result_error(pCtx, "malformed JSON", -1);
- }
- }
- jsonParseReset(pParse);
- return 1;
- }
- return 0;
-}
-
-/* Mark node i of pParse as being a child of iParent. Call recursively
-** to fill in all the descendants of node i.
-*/
-static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
- JsonNode *pNode = &pParse->aNode[i];
- u32 j;
- pParse->aUp[i] = iParent;
- switch( pNode->eType ){
- case JSON_ARRAY: {
- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
- jsonParseFillInParentage(pParse, i+j, i);
- }
- break;
- }
- case JSON_OBJECT: {
- for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
- pParse->aUp[i+j] = i;
- jsonParseFillInParentage(pParse, i+j+1, i);
- }
- break;
- }
- default: {
- break;
- }
- }
-}
-
-/*
-** Compute the parentage of all nodes in a completed parse.
-*/
-static int jsonParseFindParents(JsonParse *pParse){
- u32 *aUp;
- assert( pParse->aUp==0 );
- aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
- if( aUp==0 ){
- pParse->oom = 1;
- return SQLITE_NOMEM;
- }
- jsonParseFillInParentage(pParse, 0, 0);
- return SQLITE_OK;
-}
-
-/*
-** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
+** * For each field modified by the local change for which the
+** corresponding field in the rebase buffer is not "undefined" (0x00)
+** or "replaced" (0xFF), the old.* value is replaced by the value
+** in the rebase buffer.
*/
-#define JSON_CACHE_ID (-429938)
-
-/*
-** Obtain a complete parse of the JSON found in the first argument
-** of the argv array. Use the sqlite3_get_auxdata() cache for this
-** parse if it is available. If the cache is not available or if it
-** is no longer valid, parse the JSON again and return the new parse,
-** and also register the new parse so that it will be available for
-** future sqlite3_get_auxdata() calls.
-*/
-static JsonParse *jsonParseCached(
- sqlite3_context *pCtx,
- sqlite3_value **argv
+static void sessionAppendPartialUpdate(
+ SessionBuffer *pBuf, /* Append record here */
+ sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */
+ u8 *aRec, int nRec, /* Local change */
+ u8 *aChange, int nChange, /* Record to rebase against */
+ int *pRc /* IN/OUT: Return Code */
){
- const char *zJson = (const char*)sqlite3_value_text(argv[0]);
- int nJson = sqlite3_value_bytes(argv[0]);
- JsonParse *p;
- if( zJson==0 ) return 0;
- p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
- if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
- p->nErr = 0;
- return p; /* The cached entry matches, so return it */
- }
- p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
- if( p==0 ){
- sqlite3_result_error_nomem(pCtx);
- return 0;
- }
- memset(p, 0, sizeof(*p));
- p->zJson = (char*)&p[1];
- memcpy((char*)p->zJson, zJson, nJson+1);
- if( jsonParse(p, pCtx, p->zJson) ){
- sqlite3_free(p);
- return 0;
- }
- p->nJson = nJson;
- sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
- return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
-}
-
-/*
-** Compare the OBJECT label at pNode against zKey,nKey. Return true on
-** a match.
-*/
-static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
- if( pNode->jnFlags & JNODE_RAW ){
- if( pNode->n!=nKey ) return 0;
- return strncmp(pNode->u.zJContent, zKey, nKey)==0;
- }else{
- if( pNode->n!=nKey+2 ) return 0;
- return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
- }
-}
-
-/* forward declaration */
-static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
+ sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
+ if( *pRc==SQLITE_OK ){
+ int bData = 0;
+ u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
+ int i;
+ u8 *a1 = aRec;
+ u8 *a2 = aChange;
-/*
-** Search along zPath to find the node specified. Return a pointer
-** to that node, or NULL if zPath is malformed or if there is no such
-** node.
-**
-** If pApnd!=0, then try to append new nodes to complete zPath if it is
-** possible to do so and if no existing node corresponds to zPath. If
-** new nodes are appended *pApnd is set to 1.
-*/
-static JsonNode *jsonLookupStep(
- JsonParse *pParse, /* The JSON to search */
- u32 iRoot, /* Begin the search at this node */
- const char *zPath, /* The path to search */
- int *pApnd, /* Append nodes to complete path if not NULL */
- const char **pzErr /* Make *pzErr point to any syntax error in zPath */
-){
- u32 i, j, nKey;
- const char *zKey;
- JsonNode *pRoot = &pParse->aNode[iRoot];
- if( zPath[0]==0 ) return pRoot;
- if( zPath[0]=='.' ){
- if( pRoot->eType!=JSON_OBJECT ) return 0;
- zPath++;
- if( zPath[0]=='"' ){
- zKey = zPath + 1;
- for(i=1; zPath[i] && zPath[i]!='"'; i++){}
- nKey = i-1;
- if( zPath[i] ){
- i++;
+ *pOut++ = SQLITE_UPDATE;
+ *pOut++ = pIter->bIndirect;
+ for(i=0; i<pIter->nCol; i++){
+ int n1 = sessionSerialLen(a1);
+ int n2 = sessionSerialLen(a2);
+ if( pIter->abPK[i] || a2[0]==0 ){
+ if( !pIter->abPK[i] ) bData = 1;
+ memcpy(pOut, a1, n1);
+ pOut += n1;
+ }else if( a2[0]!=0xFF ){
+ bData = 1;
+ memcpy(pOut, a2, n2);
+ pOut += n2;
}else{
- *pzErr = zPath;
- return 0;
+ *pOut++ = '\0';
}
- }else{
- zKey = zPath;
- for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
- nKey = i;
- }
- if( nKey==0 ){
- *pzErr = zPath;
- return 0;
+ a1 += n1;
+ a2 += n2;
}
- j = 1;
- for(;;){
- while( j<=pRoot->n ){
- if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
- return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
+ if( bData ){
+ a2 = aChange;
+ for(i=0; i<pIter->nCol; i++){
+ int n1 = sessionSerialLen(a1);
+ int n2 = sessionSerialLen(a2);
+ if( pIter->abPK[i] || a2[0]!=0xFF ){
+ memcpy(pOut, a1, n1);
+ pOut += n1;
+ }else{
+ *pOut++ = '\0';
}
- j++;
- j += jsonNodeSize(&pRoot[j]);
+ a1 += n1;
+ a2 += n2;
}
- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
- iRoot += pRoot->u.iAppend;
- pRoot = &pParse->aNode[iRoot];
- j = 1;
- }
- if( pApnd ){
- u32 iStart, iLabel;
- JsonNode *pNode;
- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
- iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
- zPath += i;
- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
- if( pParse->oom ) return 0;
- if( pNode ){
- pRoot = &pParse->aNode[iRoot];
- pRoot->u.iAppend = iStart - iRoot;
- pRoot->jnFlags |= JNODE_APPEND;
- pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
- }
- return pNode;
+ pBuf->nBuf = (pOut - pBuf->aBuf);
}
- }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
- if( pRoot->eType!=JSON_ARRAY ) return 0;
- i = 0;
- j = 1;
- while( safe_isdigit(zPath[j]) ){
- i = i*10 + zPath[j] - '0';
- j++;
- }
- if( zPath[j]!=']' ){
- *pzErr = zPath;
- return 0;
- }
- zPath += j + 1;
- j = 1;
- for(;;){
- while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
- if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
- j += jsonNodeSize(&pRoot[j]);
- }
- if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
- iRoot += pRoot->u.iAppend;
- pRoot = &pParse->aNode[iRoot];
- j = 1;
- }
- if( j<=pRoot->n ){
- return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
- }
- if( i==0 && pApnd ){
- u32 iStart;
- JsonNode *pNode;
- iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
- pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
- if( pParse->oom ) return 0;
- if( pNode ){
- pRoot = &pParse->aNode[iRoot];
- pRoot->u.iAppend = iStart - iRoot;
- pRoot->jnFlags |= JNODE_APPEND;
- }
- return pNode;
- }
- }else{
- *pzErr = zPath;
- }
- return 0;
-}
-
-/*
-** Append content to pParse that will complete zPath. Return a pointer
-** to the inserted node, or return NULL if the append fails.
-*/
-static JsonNode *jsonLookupAppend(
- JsonParse *pParse, /* Append content to the JSON parse */
- const char *zPath, /* Description of content to append */
- int *pApnd, /* Set this flag to 1 */
- const char **pzErr /* Make this point to any syntax error */
-){
- *pApnd = 1;
- if( zPath[0]==0 ){
- jsonParseAddNode(pParse, JSON_NULL, 0, 0);
- return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
- }
- if( zPath[0]=='.' ){
- jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
- }else if( strncmp(zPath,"[0]",3)==0 ){
- jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
- }else{
- return 0;
}
- if( pParse->oom ) return 0;
- return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
-}
-
-/*
-** Return the text of a syntax error message on a JSON path. Space is
-** obtained from sqlite3_malloc().
-*/
-static char *jsonPathSyntaxError(const char *zErr){
- return sqlite3_mprintf("JSON path error near '%q'", zErr);
}
/*
-** Do a node lookup using zPath. Return a pointer to the node on success.
-** Return NULL if not found or if there is an error.
-**
-** On an error, write an error message into pCtx and increment the
-** pParse->nErr counter.
+** pIter is configured to iterate through a changeset. This function rebases
+** that changeset according to the current configuration of the rebaser
+** object passed as the first argument. If no error occurs and argument xOutput
+** is not NULL, then the changeset is returned to the caller by invoking
+** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
+** then (*ppOut) is set to point to a buffer containing the rebased changeset
+** before this function returns. In this case (*pnOut) is set to the size of
+** the buffer in bytes. It is the responsibility of the caller to eventually
+** free the (*ppOut) buffer using sqlite3_free().
**
-** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
-** nodes are appended.
-*/
-static JsonNode *jsonLookup(
- JsonParse *pParse, /* The JSON to search */
- const char *zPath, /* The path to search */
- int *pApnd, /* Append nodes to complete path if not NULL */
- sqlite3_context *pCtx /* Report errors here, if not NULL */
-){
- const char *zErr = 0;
- JsonNode *pNode = 0;
- char *zMsg;
-
- if( zPath==0 ) return 0;
- if( zPath[0]!='$' ){
- zErr = zPath;
- goto lookup_err;
- }
- zPath++;
- pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
- if( zErr==0 ) return pNode;
-
-lookup_err:
- pParse->nErr++;
- assert( zErr!=0 && pCtx!=0 );
- zMsg = jsonPathSyntaxError(zErr);
- if( zMsg ){
- sqlite3_result_error(pCtx, zMsg, -1);
- sqlite3_free(zMsg);
- }else{
- sqlite3_result_error_nomem(pCtx);
- }
- return 0;
-}
-
-
-/*
-** Report the wrong number of arguments for json_insert(), json_replace()
-** or json_set().
+** If an error occurs, an SQLite error code is returned. If ppOut and
+** pnOut are not NULL, then the two output parameters are set to 0 before
+** returning.
*/
-static void jsonWrongNumArgs(
- sqlite3_context *pCtx,
- const char *zFuncName
+static int sessionRebase(
+ sqlite3_rebaser *p, /* Rebaser hash table */
+ sqlite3_changeset_iter *pIter, /* Input data */
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut, /* Context for xOutput callback */
+ int *pnOut, /* OUT: Number of bytes in output changeset */
+ void **ppOut /* OUT: Inverse of pChangeset */
){
- char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
- zFuncName);
- sqlite3_result_error(pCtx, zMsg, -1);
- sqlite3_free(zMsg);
-}
-
-/*
-** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
-*/
-static void jsonRemoveAllNulls(JsonNode *pNode){
- int i, n;
- assert( pNode->eType==JSON_OBJECT );
- n = pNode->n;
- for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
- switch( pNode[i].eType ){
- case JSON_NULL:
- pNode[i].jnFlags |= JNODE_REMOVE;
- break;
- case JSON_OBJECT:
- jsonRemoveAllNulls(&pNode[i]);
- break;
- }
- }
-}
+ int rc = SQLITE_OK;
+ u8 *aRec = 0;
+ int nRec = 0;
+ int bNew = 0;
+ SessionTable *pTab = 0;
+ SessionBuffer sOut = {0,0,0};
+ while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
+ SessionChange *pChange = 0;
+ int bDone = 0;
-/****************************************************************************
-** SQL functions used for testing and debugging
-****************************************************************************/
+ if( bNew ){
+ const char *zTab = pIter->zTab;
+ for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
+ if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
+ }
+ bNew = 0;
-#ifdef SQLITE_DEBUG
-/*
-** The json_parse(JSON) function returns a string which describes
-** a parse of the JSON provided. Or it returns NULL if JSON is not
-** well-formed.
-*/
-static void jsonParseFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonString s; /* Output string - not real JSON */
- JsonParse x; /* The parse */
- u32 i;
+ /* A patchset may not be rebased */
+ if( pIter->bPatchset ){
+ rc = SQLITE_ERROR;
+ }
- assert( argc==1 );
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- jsonParseFindParents(&x);
- jsonInit(&s, ctx);
- for(i=0; i<x.nNode; i++){
- const char *zType;
- if( x.aNode[i].jnFlags & JNODE_LABEL ){
- assert( x.aNode[i].eType==JSON_STRING );
- zType = "label";
- }else{
- zType = jsonType[x.aNode[i].eType];
- }
- jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
- i, zType, x.aNode[i].n, x.aUp[i]);
- if( x.aNode[i].u.zJContent!=0 ){
- jsonAppendRaw(&s, " ", 1);
- jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
+ /* Append a table header to the output for this new table */
+ sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
+ sessionAppendVarint(&sOut, pIter->nCol, &rc);
+ sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
+ sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
}
- jsonAppendRaw(&s, "\n", 1);
- }
- jsonParseReset(&x);
- jsonResult(&s);
-}
-/*
-** The json_test1(JSON) function return true (1) if the input is JSON
-** text generated by another json function. It returns (0) if the input
-** is not known to be JSON.
-*/
-static void jsonTest1Func(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- UNUSED_PARAM(argc);
- sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
-}
-#endif /* SQLITE_DEBUG */
+ if( pTab && rc==SQLITE_OK ){
+ int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
-/****************************************************************************
-** Scalar SQL function implementations
-****************************************************************************/
-
-/*
-** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
-** corresponding to the SQL value input. Mostly this means putting
-** double-quotes around strings and returning the unquoted string "null"
-** when given a NULL input.
-*/
-static void jsonQuoteFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonString jx;
- UNUSED_PARAM(argc);
-
- jsonInit(&jx, ctx);
- jsonAppendValue(&jx, argv[0]);
- jsonResult(&jx);
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
-}
-
-/*
-** Implementation of the json_array(VALUE,...) function. Return a JSON
-** array that contains all values given in arguments. Or if any argument
-** is a BLOB, throw an error.
-*/
-static void jsonArrayFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- int i;
- JsonString jx;
-
- jsonInit(&jx, ctx);
- jsonAppendChar(&jx, '[');
- for(i=0; i<argc; i++){
- jsonAppendSeparator(&jx);
- jsonAppendValue(&jx, argv[i]);
- }
- jsonAppendChar(&jx, ']');
- jsonResult(&jx);
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
-}
-
-
-/*
-** json_array_length(JSON)
-** json_array_length(JSON, PATH)
-**
-** Return the number of elements in the top-level JSON array.
-** Return 0 if the input is not a well-formed JSON array.
-*/
-static void jsonArrayLengthFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse *p; /* The parse */
- sqlite3_int64 n = 0;
- u32 i;
- JsonNode *pNode;
-
- p = jsonParseCached(ctx, argv);
- if( p==0 ) return;
- assert( p->nNode );
- if( argc==2 ){
- const char *zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(p, zPath, 0, ctx);
- }else{
- pNode = p->aNode;
- }
- if( pNode==0 ){
- return;
- }
- if( pNode->eType==JSON_ARRAY ){
- assert( (pNode->jnFlags & JNODE_APPEND)==0 );
- for(i=1; i<=pNode->n; n++){
- i += jsonNodeSize(&pNode[i]);
+ for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
+ if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
+ break;
+ }
+ }
}
- }
- sqlite3_result_int64(ctx, n);
-}
-/*
-** json_extract(JSON, PATH, ...)
-**
-** Return the element described by PATH. Return NULL if there is no
-** PATH element. If there are multiple PATHs, then return a JSON array
-** with the result from each path. Throw an error if the JSON or any PATH
-** is malformed.
-*/
-static void jsonExtractFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse *p; /* The parse */
- JsonNode *pNode;
- const char *zPath;
- JsonString jx;
- int i;
+ if( pChange ){
+ assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
+ switch( pIter->op ){
+ case SQLITE_INSERT:
+ if( pChange->op==SQLITE_INSERT ){
+ bDone = 1;
+ if( pChange->bIndirect==0 ){
+ sessionAppendByte(&sOut, SQLITE_UPDATE, &rc);
+ sessionAppendByte(&sOut, pIter->bIndirect, &rc);
+ sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc);
+ sessionAppendBlob(&sOut, aRec, nRec, &rc);
+ }
+ }
+ break;
- if( argc<2 ) return;
- p = jsonParseCached(ctx, argv);
- if( p==0 ) return;
- jsonInit(&jx, ctx);
- jsonAppendChar(&jx, '[');
- for(i=1; i<argc; i++){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- pNode = jsonLookup(p, zPath, 0, ctx);
- if( p->nErr ) break;
- if( argc>2 ){
- jsonAppendSeparator(&jx);
- if( pNode ){
- jsonRenderNode(pNode, &jx, 0);
- }else{
- jsonAppendRaw(&jx, "null", 4);
- }
- }else if( pNode ){
- jsonReturn(pNode, ctx, 0);
- }
- }
- if( argc>2 && i==argc ){
- jsonAppendChar(&jx, ']');
- jsonResult(&jx);
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
- }
- jsonReset(&jx);
-}
+ case SQLITE_UPDATE:
+ bDone = 1;
+ if( pChange->op==SQLITE_DELETE ){
+ if( pChange->bIndirect==0 ){
+ u8 *pCsr = aRec;
+ sessionSkipRecord(&pCsr, pIter->nCol);
+ sessionAppendByte(&sOut, SQLITE_INSERT, &rc);
+ sessionAppendByte(&sOut, pIter->bIndirect, &rc);
+ sessionAppendRecordMerge(&sOut, pIter->nCol,
+ pCsr, nRec-(pCsr-aRec),
+ pChange->aRecord, pChange->nRecord, &rc
+ );
+ }
+ }else{
+ sessionAppendPartialUpdate(&sOut, pIter,
+ aRec, nRec, pChange->aRecord, pChange->nRecord, &rc
+ );
+ }
+ break;
-/* This is the RFC 7396 MergePatch algorithm.
-*/
-static JsonNode *jsonMergePatch(
- JsonParse *pParse, /* The JSON parser that contains the TARGET */
- u32 iTarget, /* Node of the TARGET in pParse */
- JsonNode *pPatch /* The PATCH */
-){
- u32 i, j;
- u32 iRoot;
- JsonNode *pTarget;
- if( pPatch->eType!=JSON_OBJECT ){
- return pPatch;
- }
- assert( iTarget>=0 && iTarget<pParse->nNode );
- pTarget = &pParse->aNode[iTarget];
- assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
- if( pTarget->eType!=JSON_OBJECT ){
- jsonRemoveAllNulls(pPatch);
- return pPatch;
- }
- iRoot = iTarget;
- for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
- u32 nKey;
- const char *zKey;
- assert( pPatch[i].eType==JSON_STRING );
- assert( pPatch[i].jnFlags & JNODE_LABEL );
- nKey = pPatch[i].n;
- zKey = pPatch[i].u.zJContent;
- assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
- for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
- assert( pTarget[j].eType==JSON_STRING );
- assert( pTarget[j].jnFlags & JNODE_LABEL );
- assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
- if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
- if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
- if( pPatch[i+1].eType==JSON_NULL ){
- pTarget[j+1].jnFlags |= JNODE_REMOVE;
- }else{
- JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
- if( pNew==0 ) return 0;
- pTarget = &pParse->aNode[iTarget];
- if( pNew!=&pTarget[j+1] ){
- pTarget[j+1].u.pPatch = pNew;
- pTarget[j+1].jnFlags |= JNODE_PATCH;
+ default:
+ assert( pIter->op==SQLITE_DELETE );
+ bDone = 1;
+ if( pChange->op==SQLITE_INSERT ){
+ sessionAppendByte(&sOut, SQLITE_DELETE, &rc);
+ sessionAppendByte(&sOut, pIter->bIndirect, &rc);
+ sessionAppendRecordMerge(&sOut, pIter->nCol,
+ pChange->aRecord, pChange->nRecord, aRec, nRec, &rc
+ );
}
- }
- break;
+ break;
}
}
- if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
- int iStart, iPatch;
- iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
- jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
- iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
- if( pParse->oom ) return 0;
- jsonRemoveAllNulls(pPatch);
- pTarget = &pParse->aNode[iTarget];
- pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
- pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
- iRoot = iStart;
- pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
- pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
- }
- }
- return pTarget;
-}
-
-/*
-** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
-** object that is the result of running the RFC 7396 MergePatch() algorithm
-** on the two arguments.
-*/
-static void jsonPatchFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The JSON that is being patched */
- JsonParse y; /* The patch */
- JsonNode *pResult; /* The result of the merge */
-
- UNUSED_PARAM(argc);
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
- jsonParseReset(&x);
- return;
- }
- pResult = jsonMergePatch(&x, 0, y.aNode);
- assert( pResult!=0 || x.oom );
- if( pResult ){
- jsonReturnJson(pResult, ctx, 0);
- }else{
- sqlite3_result_error_nomem(ctx);
- }
- jsonParseReset(&x);
- jsonParseReset(&y);
-}
-
-/*
-** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
-** object that contains all name/value given in arguments. Or if any name
-** is not a string or if any value is a BLOB, throw an error.
-*/
-static void jsonObjectFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- int i;
- JsonString jx;
- const char *z;
- u32 n;
-
- if( argc&1 ){
- sqlite3_result_error(ctx, "json_object() requires an even number "
- "of arguments", -1);
- return;
- }
- jsonInit(&jx, ctx);
- jsonAppendChar(&jx, '{');
- for(i=0; i<argc; i+=2){
- if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
- sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
- jsonReset(&jx);
- return;
+ if( bDone==0 ){
+ sessionAppendByte(&sOut, pIter->op, &rc);
+ sessionAppendByte(&sOut, pIter->bIndirect, &rc);
+ sessionAppendBlob(&sOut, aRec, nRec, &rc);
}
- jsonAppendSeparator(&jx);
- z = (const char*)sqlite3_value_text(argv[i]);
- n = (u32)sqlite3_value_bytes(argv[i]);
- jsonAppendString(&jx, z, n);
- jsonAppendChar(&jx, ':');
- jsonAppendValue(&jx, argv[i+1]);
- }
- jsonAppendChar(&jx, '}');
- jsonResult(&jx);
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
-}
-
-
-/*
-** json_remove(JSON, PATH, ...)
-**
-** Remove the named elements from JSON and return the result. malformed
-** JSON or PATH arguments result in an error.
-*/
-static void jsonRemoveFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The parse */
- JsonNode *pNode;
- const char *zPath;
- u32 i;
-
- if( argc<1 ) return;
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- assert( x.nNode );
- for(i=1; i<(u32)argc; i++){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- if( zPath==0 ) goto remove_done;
- pNode = jsonLookup(&x, zPath, 0, ctx);
- if( x.nErr ) goto remove_done;
- if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
- }
- if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
- jsonReturnJson(x.aNode, ctx, 0);
- }
-remove_done:
- jsonParseReset(&x);
-}
-
-/*
-** json_replace(JSON, PATH, VALUE, ...)
-**
-** Replace the value at PATH with VALUE. If PATH does not already exist,
-** this routine is a no-op. If JSON or PATH is malformed, throw an error.
-*/
-static void jsonReplaceFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The parse */
- JsonNode *pNode;
- const char *zPath;
- u32 i;
-
- if( argc<1 ) return;
- if( (argc&1)==0 ) {
- jsonWrongNumArgs(ctx, "replace");
- return;
- }
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- assert( x.nNode );
- for(i=1; i<(u32)argc; i+=2){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
- if( x.nErr ) goto replace_err;
- if( pNode ){
- pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->u.iReplace = i + 1;
+ if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+ sOut.nBuf = 0;
}
+ if( rc ) break;
}
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
- }else{
- jsonReturnJson(x.aNode, ctx, argv);
- }
-replace_err:
- jsonParseReset(&x);
-}
-/*
-** json_set(JSON, PATH, VALUE, ...)
-**
-** Set the value at PATH to VALUE. Create the PATH if it does not already
-** exist. Overwrite existing values that do exist.
-** If JSON or PATH is malformed, throw an error.
-**
-** json_insert(JSON, PATH, VALUE, ...)
-**
-** Create PATH and initialize it to VALUE. If PATH already exists, this
-** routine is a no-op. If JSON or PATH is malformed, throw an error.
-*/
-static void jsonSetFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The parse */
- JsonNode *pNode;
- const char *zPath;
- u32 i;
- int bApnd;
- int bIsSet = *(int*)sqlite3_user_data(ctx);
-
- if( argc<1 ) return;
- if( (argc&1)==0 ) {
- jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
- return;
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(sOut.aBuf);
+ memset(&sOut, 0, sizeof(sOut));
}
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- assert( x.nNode );
- for(i=1; i<(u32)argc; i+=2){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- bApnd = 0;
- pNode = jsonLookup(&x, zPath, &bApnd, ctx);
- if( x.oom ){
- sqlite3_result_error_nomem(ctx);
- goto jsonSetDone;
- }else if( x.nErr ){
- goto jsonSetDone;
- }else if( pNode && (bApnd || bIsSet) ){
- pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->u.iReplace = i + 1;
+
+ if( rc==SQLITE_OK ){
+ if( xOutput ){
+ if( sOut.nBuf>0 ){
+ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+ }
+ }else{
+ *ppOut = (void*)sOut.aBuf;
+ *pnOut = sOut.nBuf;
+ sOut.aBuf = 0;
}
}
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
- }else{
- jsonReturnJson(x.aNode, ctx, argv);
- }
-jsonSetDone:
- jsonParseReset(&x);
+ sqlite3_free(sOut.aBuf);
+ return rc;
}
-/*
-** json_type(JSON)
-** json_type(JSON, PATH)
-**
-** Return the top-level "type" of a JSON string. Throw an error if
-** either the JSON or PATH inputs are not well-formed.
+/*
+** Create a new rebaser object.
*/
-static void jsonTypeFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The parse */
- const char *zPath;
- JsonNode *pNode;
+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
+ int rc = SQLITE_OK;
+ sqlite3_rebaser *pNew;
- if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- assert( x.nNode );
- if( argc==2 ){
- zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
+ pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
+ if( pNew==0 ){
+ rc = SQLITE_NOMEM;
}else{
- pNode = x.aNode;
+ memset(pNew, 0, sizeof(sqlite3_rebaser));
}
- if( pNode ){
- sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
- }
- jsonParseReset(&x);
-}
-
-/*
-** json_valid(JSON)
-**
-** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
-** Return 0 otherwise.
-*/
-static void jsonValidFunc(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
-){
- JsonParse x; /* The parse */
- int rc = 0;
-
- UNUSED_PARAM(argc);
- if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
- rc = 1;
- }
- jsonParseReset(&x);
- sqlite3_result_int(ctx, rc);
+ *ppNew = pNew;
+ return rc;
}
-
-/****************************************************************************
-** Aggregate SQL function implementations
-****************************************************************************/
-/*
-** json_group_array(VALUE)
-**
-** Return a JSON array composed of all values in the aggregate.
+/*
+** Call this one or more times to configure a rebaser.
*/
-static void jsonArrayStep(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
+SQLITE_API int sqlite3rebaser_configure(
+ sqlite3_rebaser *p,
+ int nRebase, const void *pRebase
){
- JsonString *pStr;
- UNUSED_PARAM(argc);
- pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
- if( pStr ){
- if( pStr->zBuf==0 ){
- jsonInit(pStr, ctx);
- jsonAppendChar(pStr, '[');
- }else{
- jsonAppendChar(pStr, ',');
- pStr->pCtx = ctx;
- }
- jsonAppendValue(pStr, argv[0]);
- }
-}
-static void jsonArrayFinal(sqlite3_context *ctx){
- JsonString *pStr;
- pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
- if( pStr ){
- pStr->pCtx = ctx;
- jsonAppendChar(pStr, ']');
- if( pStr->bErr ){
- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
- assert( pStr->bStatic );
- }else{
- sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
- pStr->bStatic = 1;
- }
- }else{
- sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+ sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
+ int rc; /* Return code */
+ rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
+ if( rc==SQLITE_OK ){
+ rc = sessionChangesetToHash(pIter, &p->grp, 1);
}
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+ sqlite3changeset_finalize(pIter);
+ return rc;
}
-/*
-** json_group_obj(NAME,VALUE)
-**
-** Return a JSON object composed of all names and values in the aggregate.
+/*
+** Rebase a changeset according to current rebaser configuration
*/
-static void jsonObjectStep(
- sqlite3_context *ctx,
- int argc,
- sqlite3_value **argv
+SQLITE_API int sqlite3rebaser_rebase(
+ sqlite3_rebaser *p,
+ int nIn, const void *pIn,
+ int *pnOut, void **ppOut
){
- JsonString *pStr;
- const char *z;
- u32 n;
- UNUSED_PARAM(argc);
- pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
- if( pStr ){
- if( pStr->zBuf==0 ){
- jsonInit(pStr, ctx);
- jsonAppendChar(pStr, '{');
- }else{
- jsonAppendChar(pStr, ',');
- pStr->pCtx = ctx;
- }
- z = (const char*)sqlite3_value_text(argv[0]);
- n = (u32)sqlite3_value_bytes(argv[0]);
- jsonAppendString(pStr, z, n);
- jsonAppendChar(pStr, ':');
- jsonAppendValue(pStr, argv[1]);
- }
-}
-static void jsonObjectFinal(sqlite3_context *ctx){
- JsonString *pStr;
- pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
- if( pStr ){
- jsonAppendChar(pStr, '}');
- if( pStr->bErr ){
- if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
- assert( pStr->bStatic );
- }else{
- sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
- pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
- pStr->bStatic = 1;
- }
- }else{
- sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
- }
- sqlite3_result_subtype(ctx, JSON_SUBTYPE);
-}
+ sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
+ int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/****************************************************************************
-** The json_each virtual table
-****************************************************************************/
-typedef struct JsonEachCursor JsonEachCursor;
-struct JsonEachCursor {
- sqlite3_vtab_cursor base; /* Base class - must be first */
- u32 iRowid; /* The rowid */
- u32 iBegin; /* The first node of the scan */
- u32 i; /* Index in sParse.aNode[] of current row */
- u32 iEnd; /* EOF when i equals or exceeds this value */
- u8 eType; /* Type of top-level element */
- u8 bRecursive; /* True for json_tree(). False for json_each() */
- char *zJson; /* Input JSON */
- char *zRoot; /* Path by which to filter zJson */
- JsonParse sParse; /* Parse of the input JSON */
-};
-
-/* Constructor for the json_each virtual table */
-static int jsonEachConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- sqlite3_vtab *pNew;
- int rc;
-
-/* Column numbers */
-#define JEACH_KEY 0
-#define JEACH_VALUE 1
-#define JEACH_TYPE 2
-#define JEACH_ATOM 3
-#define JEACH_ID 4
-#define JEACH_PARENT 5
-#define JEACH_FULLKEY 6
-#define JEACH_PATH 7
-#define JEACH_JSON 8
-#define JEACH_ROOT 9
-
- UNUSED_PARAM(pzErr);
- UNUSED_PARAM(argv);
- UNUSED_PARAM(argc);
- UNUSED_PARAM(pAux);
- rc = sqlite3_declare_vtab(db,
- "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
- "json HIDDEN,root HIDDEN)");
if( rc==SQLITE_OK ){
- pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
- if( pNew==0 ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(*pNew));
+ rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
+ sqlite3changeset_finalize(pIter);
}
- return rc;
-}
-
-/* destructor for json_each virtual table */
-static int jsonEachDisconnect(sqlite3_vtab *pVtab){
- sqlite3_free(pVtab);
- return SQLITE_OK;
-}
-
-/* constructor for a JsonEachCursor object for json_each(). */
-static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
- JsonEachCursor *pCur;
- UNUSED_PARAM(p);
- pCur = sqlite3_malloc( sizeof(*pCur) );
- if( pCur==0 ) return SQLITE_NOMEM;
- memset(pCur, 0, sizeof(*pCur));
- *ppCursor = &pCur->base;
- return SQLITE_OK;
-}
-
-/* constructor for a JsonEachCursor object for json_tree(). */
-static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
- int rc = jsonEachOpenEach(p, ppCursor);
- if( rc==SQLITE_OK ){
- JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
- pCur->bRecursive = 1;
- }
return rc;
}
-/* Reset a JsonEachCursor back to its original state. Free any memory
-** held. */
-static void jsonEachCursorReset(JsonEachCursor *p){
- sqlite3_free(p->zJson);
- sqlite3_free(p->zRoot);
- jsonParseReset(&p->sParse);
- p->iRowid = 0;
- p->i = 0;
- p->iEnd = 0;
- p->eType = 0;
- p->zJson = 0;
- p->zRoot = 0;
-}
-
-/* Destructor for a jsonEachCursor object */
-static int jsonEachClose(sqlite3_vtab_cursor *cur){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- jsonEachCursorReset(p);
- sqlite3_free(cur);
- return SQLITE_OK;
-}
-
-/* Return TRUE if the jsonEachCursor object has been advanced off the end
-** of the JSON object */
-static int jsonEachEof(sqlite3_vtab_cursor *cur){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- return p->i >= p->iEnd;
-}
-
-/* Advance the cursor to the next element for json_tree() */
-static int jsonEachNext(sqlite3_vtab_cursor *cur){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- if( p->bRecursive ){
- if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
- p->i++;
- p->iRowid++;
- if( p->i<p->iEnd ){
- u32 iUp = p->sParse.aUp[p->i];
- JsonNode *pUp = &p->sParse.aNode[iUp];
- p->eType = pUp->eType;
- if( pUp->eType==JSON_ARRAY ){
- if( iUp==p->i-1 ){
- pUp->u.iKey = 0;
- }else{
- pUp->u.iKey++;
- }
- }
- }
- }else{
- switch( p->eType ){
- case JSON_ARRAY: {
- p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
- p->iRowid++;
- break;
- }
- case JSON_OBJECT: {
- p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
- p->iRowid++;
- break;
- }
- default: {
- p->i = p->iEnd;
- break;
- }
- }
- }
- return SQLITE_OK;
-}
-
-/* Append the name of the path for element i to pStr
+/*
+** Rebase a changeset according to current rebaser configuration
*/
-static void jsonEachComputePath(
- JsonEachCursor *p, /* The cursor */
- JsonString *pStr, /* Write the path here */
- u32 i /* Path to this element */
+SQLITE_API int sqlite3rebaser_rebase_strm(
+ sqlite3_rebaser *p,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
){
- JsonNode *pNode, *pUp;
- u32 iUp;
- if( i==0 ){
- jsonAppendChar(pStr, '$');
- return;
- }
- iUp = p->sParse.aUp[i];
- jsonEachComputePath(p, pStr, iUp);
- pNode = &p->sParse.aNode[i];
- pUp = &p->sParse.aNode[iUp];
- if( pUp->eType==JSON_ARRAY ){
- jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
- }else{
- assert( pUp->eType==JSON_OBJECT );
- if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
- assert( pNode->eType==JSON_STRING );
- assert( pNode->jnFlags & JNODE_LABEL );
- jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
- }
-}
+ sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
+ int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
-/* Return the value of a column */
-static int jsonEachColumn(
- sqlite3_vtab_cursor *cur, /* The cursor */
- sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
- int i /* Which column to return */
-){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- JsonNode *pThis = &p->sParse.aNode[p->i];
- switch( i ){
- case JEACH_KEY: {
- if( p->i==0 ) break;
- if( p->eType==JSON_OBJECT ){
- jsonReturn(pThis, ctx, 0);
- }else if( p->eType==JSON_ARRAY ){
- u32 iKey;
- if( p->bRecursive ){
- if( p->iRowid==0 ) break;
- iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
- }else{
- iKey = p->iRowid;
- }
- sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
- }
- break;
- }
- case JEACH_VALUE: {
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
- jsonReturn(pThis, ctx, 0);
- break;
- }
- case JEACH_TYPE: {
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
- sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
- break;
- }
- case JEACH_ATOM: {
- if( pThis->jnFlags & JNODE_LABEL ) pThis++;
- if( pThis->eType>=JSON_ARRAY ) break;
- jsonReturn(pThis, ctx, 0);
- break;
- }
- case JEACH_ID: {
- sqlite3_result_int64(ctx,
- (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
- break;
- }
- case JEACH_PARENT: {
- if( p->i>p->iBegin && p->bRecursive ){
- sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
- }
- break;
- }
- case JEACH_FULLKEY: {
- JsonString x;
- jsonInit(&x, ctx);
- if( p->bRecursive ){
- jsonEachComputePath(p, &x, p->i);
- }else{
- if( p->zRoot ){
- jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
- }else{
- jsonAppendChar(&x, '$');
- }
- if( p->eType==JSON_ARRAY ){
- jsonPrintf(30, &x, "[%d]", p->iRowid);
- }else{
- jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
- }
- }
- jsonResult(&x);
- break;
- }
- case JEACH_PATH: {
- if( p->bRecursive ){
- JsonString x;
- jsonInit(&x, ctx);
- jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
- jsonResult(&x);
- break;
- }
- /* For json_each() path and root are the same so fall through
- ** into the root case */
- }
- default: {
- const char *zRoot = p->zRoot;
- if( zRoot==0 ) zRoot = "$";
- sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
- break;
- }
- case JEACH_JSON: {
- assert( i==JEACH_JSON );
- sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
- break;
- }
+ if( rc==SQLITE_OK ){
+ rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
+ sqlite3changeset_finalize(pIter);
}
- return SQLITE_OK;
-}
-/* Return the current rowid value */
-static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- *pRowid = p->iRowid;
- return SQLITE_OK;
+ return rc;
}
-/* The query strategy is to look for an equality constraint on the json
-** column. Without such a constraint, the table cannot operate. idxNum is
-** 1 if the constraint is found, 3 if the constraint and zRoot are found,
-** and 0 otherwise.
+/*
+** Destroy a rebaser object
*/
-static int jsonEachBestIndex(
- sqlite3_vtab *tab,
- sqlite3_index_info *pIdxInfo
-){
- int i;
- int jsonIdx = -1;
- int rootIdx = -1;
- const struct sqlite3_index_constraint *pConstraint;
-
- UNUSED_PARAM(tab);
- pConstraint = pIdxInfo->aConstraint;
- for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- switch( pConstraint->iColumn ){
- case JEACH_JSON: jsonIdx = i; break;
- case JEACH_ROOT: rootIdx = i; break;
- default: /* no-op */ break;
- }
- }
- if( jsonIdx<0 ){
- pIdxInfo->idxNum = 0;
- pIdxInfo->estimatedCost = 1e99;
- }else{
- pIdxInfo->estimatedCost = 1.0;
- pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
- pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
- if( rootIdx<0 ){
- pIdxInfo->idxNum = 1;
- }else{
- pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
- pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
- pIdxInfo->idxNum = 3;
- }
- }
- return SQLITE_OK;
-}
-
-/* Start a search on a new JSON string */
-static int jsonEachFilter(
- sqlite3_vtab_cursor *cur,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- JsonEachCursor *p = (JsonEachCursor*)cur;
- const char *z;
- const char *zRoot = 0;
- size_t n;
-
- UNUSED_PARAM(idxStr);
- UNUSED_PARAM(argc);
- jsonEachCursorReset(p);
- if( idxNum==0 ) return SQLITE_OK;
- z = (const char*)sqlite3_value_text(argv[0]);
- if( z==0 ) return SQLITE_OK;
- n = (size_t)sqlite3_value_bytes(argv[0]);
- p->zJson = sqlite3_malloc( n+1 );
- if( p->zJson==0 ) return SQLITE_NOMEM;
- memcpy(p->zJson, z, n+1);
- if( jsonParse(&p->sParse, 0, p->zJson) ){
- int rc = SQLITE_NOMEM;
- if( p->sParse.oom==0 ){
- sqlite3_free(cur->pVtab->zErrMsg);
- cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
- if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
- }
- jsonEachCursorReset(p);
- return rc;
- }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
- jsonEachCursorReset(p);
- return SQLITE_NOMEM;
- }else{
- JsonNode *pNode = 0;
- if( idxNum==3 ){
- const char *zErr = 0;
- zRoot = (const char*)sqlite3_value_text(argv[1]);
- if( zRoot==0 ) return SQLITE_OK;
- n = (size_t)sqlite3_value_bytes(argv[1]);
- p->zRoot = sqlite3_malloc( n+1 );
- if( p->zRoot==0 ) return SQLITE_NOMEM;
- memcpy(p->zRoot, zRoot, n+1);
- if( zRoot[0]!='$' ){
- zErr = zRoot;
- }else{
- pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
- }
- if( zErr ){
- sqlite3_free(cur->pVtab->zErrMsg);
- cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
- jsonEachCursorReset(p);
- return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
- }else if( pNode==0 ){
- return SQLITE_OK;
- }
- }else{
- pNode = p->sParse.aNode;
- }
- p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
- p->eType = pNode->eType;
- if( p->eType>=JSON_ARRAY ){
- pNode->u.iKey = 0;
- p->iEnd = p->i + pNode->n + 1;
- if( p->bRecursive ){
- p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
- if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
- p->i--;
- }
- }else{
- p->i++;
- }
- }else{
- p->iEnd = p->i+1;
- }
- }
- return SQLITE_OK;
-}
-
-/* The methods of the json_each virtual table */
-static const sqlite3_module jsonEachModule = {
- 0, /* iVersion */
- 0, /* xCreate */
- jsonEachConnect, /* xConnect */
- jsonEachBestIndex, /* xBestIndex */
- jsonEachDisconnect, /* xDisconnect */
- 0, /* xDestroy */
- jsonEachOpenEach, /* xOpen - open a cursor */
- jsonEachClose, /* xClose - close a cursor */
- jsonEachFilter, /* xFilter - configure scan constraints */
- jsonEachNext, /* xNext - advance a cursor */
- jsonEachEof, /* xEof - check for end of scan */
- jsonEachColumn, /* xColumn - read data */
- jsonEachRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0 /* xRollbackTo */
-};
-
-/* The methods of the json_tree virtual table. */
-static const sqlite3_module jsonTreeModule = {
- 0, /* iVersion */
- 0, /* xCreate */
- jsonEachConnect, /* xConnect */
- jsonEachBestIndex, /* xBestIndex */
- jsonEachDisconnect, /* xDisconnect */
- 0, /* xDestroy */
- jsonEachOpenTree, /* xOpen - open a cursor */
- jsonEachClose, /* xClose - close a cursor */
- jsonEachFilter, /* xFilter - configure scan constraints */
- jsonEachNext, /* xNext - advance a cursor */
- jsonEachEof, /* xEof - check for end of scan */
- jsonEachColumn, /* xColumn - read data */
- jsonEachRowid, /* xRowid - read data */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindMethod */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0 /* xRollbackTo */
-};
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/****************************************************************************
-** The following routines are the only publically visible identifiers in this
-** file. Call the following routines in order to register the various SQL
-** functions and the virtual table implemented by this file.
-****************************************************************************/
-
-SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
- int rc = SQLITE_OK;
- unsigned int i;
- static const struct {
- const char *zName;
- int nArg;
- int flag;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- } aFunc[] = {
- { "json", 1, 0, jsonRemoveFunc },
- { "json_array", -1, 0, jsonArrayFunc },
- { "json_array_length", 1, 0, jsonArrayLengthFunc },
- { "json_array_length", 2, 0, jsonArrayLengthFunc },
- { "json_extract", -1, 0, jsonExtractFunc },
- { "json_insert", -1, 0, jsonSetFunc },
- { "json_object", -1, 0, jsonObjectFunc },
- { "json_patch", 2, 0, jsonPatchFunc },
- { "json_quote", 1, 0, jsonQuoteFunc },
- { "json_remove", -1, 0, jsonRemoveFunc },
- { "json_replace", -1, 0, jsonReplaceFunc },
- { "json_set", -1, 1, jsonSetFunc },
- { "json_type", 1, 0, jsonTypeFunc },
- { "json_type", 2, 0, jsonTypeFunc },
- { "json_valid", 1, 0, jsonValidFunc },
-
-#if SQLITE_DEBUG
- /* DEBUG and TESTING functions */
- { "json_parse", 1, 0, jsonParseFunc },
- { "json_test1", 1, 0, jsonTest1Func },
-#endif
- };
- static const struct {
- const char *zName;
- int nArg;
- void (*xStep)(sqlite3_context*,int,sqlite3_value**);
- void (*xFinal)(sqlite3_context*);
- } aAgg[] = {
- { "json_group_array", 1, jsonArrayStep, jsonArrayFinal },
- { "json_group_object", 2, jsonObjectStep, jsonObjectFinal },
- };
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- static const struct {
- const char *zName;
- const sqlite3_module *pModule;
- } aMod[] = {
- { "json_each", &jsonEachModule },
- { "json_tree", &jsonTreeModule },
- };
-#endif
- for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
- rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC,
- (void*)&aFunc[i].flag,
- aFunc[i].xFunc, 0, 0);
- }
- for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
- rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
- SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
- 0, aAgg[i].xStep, aAgg[i].xFinal);
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
- rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){
+ if( p ){
+ sessionDeleteTable(p->grp.pList);
+ sqlite3_free(p);
}
-#endif
- return rc;
}
+#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
-#ifndef SQLITE_CORE
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-SQLITE_API int sqlite3_json_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi);
- (void)pzErrMsg; /* Unused parameter */
- return sqlite3Json1Init(db);
-}
-#endif
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
-
-/************** End of json1.c ***********************************************/
+/************** End of sqlite3session.c **************************************/
/************** Begin file fts5.c ********************************************/
@@ -184607,7 +197864,7 @@ struct Fts5ExtensionApi {
** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do would be
** inefficient), it doesn't matter if the user queries for
-** 'first + place' or '1st + place', as there are entires in the
+** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
** </ol>
**
@@ -184635,7 +197892,7 @@ struct Fts5ExtensionApi {
** extra data to the FTS index or require FTS5 to query for multiple terms,
** so it is efficient in terms of disk space and query speed. However, it
** does not support prefix queries very well. If, as suggested above, the
-** token "first" is subsituted for "1st" by the tokenizer, then the query:
+** token "first" is substituted for "1st" by the tokenizer, then the query:
**
** <codeblock>
** ... MATCH '1s*'</codeblock>
@@ -185469,6 +198726,8 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
int bPrefix
);
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
+
static Fts5ExprNearset *sqlite3Fts5ParseNearset(
Fts5Parse*,
Fts5ExprNearset*,
@@ -185529,9 +198788,12 @@ static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*);
/**************************************************************************
** Interface to automatically generated code in fts5_unicode2.c.
*/
-static int sqlite3Fts5UnicodeIsalnum(int c);
-static int sqlite3Fts5UnicodeIsdiacritic(int c);
-static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
+SQLITE_PRIVATE int sqlite3Fts5UnicodeIsdiacritic(int c);
+SQLITE_PRIVATE int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
+
+static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
+static int sqlite3Fts5UnicodeCategory(int iCode);
+static void sqlite3Fts5UnicodeAscii(u8*, u8*);
/*
** End of interface to code in fts5_unicode2.c.
**************************************************************************/
@@ -185549,9 +198811,10 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
#define FTS5_STRING 9
#define FTS5_LP 10
#define FTS5_RP 11
-#define FTS5_COMMA 12
-#define FTS5_PLUS 13
-#define FTS5_STAR 14
+#define FTS5_CARET 12
+#define FTS5_COMMA 13
+#define FTS5_PLUS 14
+#define FTS5_STAR 15
/*
** 2000-05-29
@@ -185646,27 +198909,30 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
** zero the stack is dynamically sized using realloc()
** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument
** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument
+** sqlite3Fts5ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter
** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
+** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context
** fts5YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
** fts5YYNSTATE the combined number of states.
** fts5YYNRULE the number of rules in the grammar
+** fts5YYNFTS5TOKEN Number of terminal symbols
** fts5YY_MAX_SHIFT Maximum value for shift actions
** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** fts5YY_MIN_REDUCE Minimum value for reduce actions
-** fts5YY_MAX_REDUCE Maximum value for reduce actions
** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
+** fts5YY_MIN_REDUCE Minimum value for reduce actions
+** fts5YY_MAX_REDUCE Maximum value for reduce actions
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define fts5YYCODETYPE unsigned char
-#define fts5YYNOCODE 28
+#define fts5YYNOCODE 27
#define fts5YYACTIONTYPE unsigned char
#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
typedef union {
@@ -185683,19 +198949,27 @@ typedef union {
#endif
#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
-#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
-#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
-#define fts5YYNSTATE 33
-#define fts5YYNRULE 27
-#define fts5YY_MAX_SHIFT 32
-#define fts5YY_MIN_SHIFTREDUCE 50
-#define fts5YY_MAX_SHIFTREDUCE 76
-#define fts5YY_MIN_REDUCE 77
-#define fts5YY_MAX_REDUCE 103
-#define fts5YY_ERROR_ACTION 104
-#define fts5YY_ACCEPT_ACTION 105
-#define fts5YY_NO_ACTION 106
+#define sqlite3Fts5ParserARG_PARAM ,pParse
+#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
+#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
+#define sqlite3Fts5ParserCTX_SDECL
+#define sqlite3Fts5ParserCTX_PDECL
+#define sqlite3Fts5ParserCTX_PARAM
+#define sqlite3Fts5ParserCTX_FETCH
+#define sqlite3Fts5ParserCTX_STORE
+#define fts5YYNSTATE 35
+#define fts5YYNRULE 28
+#define fts5YYNFTS5TOKEN 16
+#define fts5YY_MAX_SHIFT 34
+#define fts5YY_MIN_SHIFTREDUCE 52
+#define fts5YY_MAX_SHIFTREDUCE 79
+#define fts5YY_ERROR_ACTION 80
+#define fts5YY_ACCEPT_ACTION 81
+#define fts5YY_NO_ACTION 82
+#define fts5YY_MIN_REDUCE 83
+#define fts5YY_MAX_REDUCE 110
/************* End control #defines *******************************************/
+#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
** otherwise.
@@ -185724,9 +198998,6 @@ typedef union {
** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
**
-** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
-** and fts5YY_MAX_REDUCE
-**
** N == fts5YY_ERROR_ACTION A syntax error has occurred.
**
** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
@@ -185734,25 +199005,22 @@ typedef union {
** N == fts5YY_NO_ACTION No such action. Denotes unused
** slots in the fts5yy_action[] table.
**
+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
+** and fts5YY_MAX_REDUCE
+**
** The action table is constructed as a single large table named fts5yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
** (B) N = fts5yy_default[S]
**
-** The (A) formula is preferred. The B formula is used instead if:
-** (1) The fts5yy_shift_ofst[S]+X value is out of range, or
-** (2) fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or
-** (3) fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT.
-** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that
-** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
-** Hence only tests (1) and (2) need to be evaluated.)
+** The (A) formula is preferred. The B formula is used instead if
+** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
**
** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
-** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
-** fts5YY_SHIFT_USE_DFLT.
+** the fts5yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
@@ -185766,54 +199034,56 @@ typedef union {
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (98)
+#define fts5YY_ACTTAB_COUNT (105)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 105, 19, 90, 6, 26, 93, 92, 24, 24, 17,
- /* 10 */ 90, 6, 26, 16, 92, 54, 24, 18, 90, 6,
- /* 20 */ 26, 10, 92, 12, 24, 75, 86, 90, 6, 26,
- /* 30 */ 13, 92, 75, 24, 20, 90, 6, 26, 101, 92,
- /* 40 */ 56, 24, 27, 90, 6, 26, 100, 92, 21, 24,
- /* 50 */ 23, 15, 30, 11, 1, 91, 22, 25, 9, 92,
- /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77,
- /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12,
- /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32,
- /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14,
+ /* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18,
+ /* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6,
+ /* 20 */ 28, 14, 98, 14, 26, 31, 92, 96, 6, 28,
+ /* 30 */ 108, 98, 25, 26, 21, 96, 6, 28, 78, 98,
+ /* 40 */ 58, 26, 29, 96, 6, 28, 107, 98, 22, 26,
+ /* 50 */ 24, 16, 12, 11, 1, 13, 13, 24, 16, 23,
+ /* 60 */ 11, 33, 34, 13, 97, 8, 27, 32, 98, 7,
+ /* 70 */ 26, 3, 4, 5, 3, 4, 5, 3, 83, 4,
+ /* 80 */ 5, 3, 63, 5, 3, 62, 12, 2, 86, 13,
+ /* 90 */ 9, 30, 10, 10, 54, 57, 75, 78, 78, 53,
+ /* 100 */ 57, 15, 82, 82, 71,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
/* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
/* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
- /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20,
- /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22,
+ /* 20 */ 20, 9, 22, 9, 24, 13, 17, 18, 19, 20,
+ /* 30 */ 26, 22, 24, 24, 17, 18, 19, 20, 15, 22,
/* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
- /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22,
- /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0,
- /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9,
- /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25,
- /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9,
+ /* 50 */ 6, 7, 9, 9, 10, 12, 12, 6, 7, 21,
+ /* 60 */ 9, 24, 25, 12, 18, 5, 20, 14, 22, 5,
+ /* 70 */ 24, 3, 1, 2, 3, 1, 2, 3, 0, 1,
+ /* 80 */ 2, 3, 11, 2, 3, 11, 9, 10, 5, 12,
+ /* 90 */ 23, 24, 10, 10, 8, 9, 9, 15, 15, 8,
+ /* 100 */ 9, 9, 27, 27, 11, 27, 27, 27, 27, 27,
+ /* 110 */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ /* 120 */ 27,
};
-#define fts5YY_SHIFT_USE_DFLT (98)
-#define fts5YY_SHIFT_COUNT (32)
+#define fts5YY_SHIFT_COUNT (34)
#define fts5YY_SHIFT_MIN (0)
-#define fts5YY_SHIFT_MAX (90)
+#define fts5YY_SHIFT_MAX (93)
static const unsigned char fts5yy_shift_ofst[] = {
- /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14,
- /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69,
- /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87,
- /* 30 */ 88, 39, 71,
+ /* 0 */ 44, 44, 44, 44, 44, 44, 51, 77, 43, 12,
+ /* 10 */ 14, 83, 82, 14, 23, 23, 31, 31, 71, 74,
+ /* 20 */ 78, 81, 86, 91, 6, 53, 53, 60, 64, 68,
+ /* 30 */ 53, 87, 92, 53, 93,
};
-#define fts5YY_REDUCE_USE_DFLT (-18)
-#define fts5YY_REDUCE_COUNT (16)
+#define fts5YY_REDUCE_COUNT (17)
#define fts5YY_REDUCE_MIN (-17)
#define fts5YY_REDUCE_MAX (67)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17,
- /* 10 */ 67, 12, 12, 12, 20, 27, 35,
+ /* 0 */ -16, -8, 0, 9, 17, 25, 46, -17, -17, 37,
+ /* 10 */ 67, 4, 4, 8, 4, 20, 27, 38,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104,
- /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104,
- /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104,
- /* 30 */ 104, 97, 104,
+ /* 0 */ 80, 80, 80, 80, 80, 80, 95, 80, 80, 105,
+ /* 10 */ 80, 110, 110, 80, 110, 110, 80, 80, 80, 80,
+ /* 20 */ 80, 91, 80, 80, 80, 101, 100, 80, 80, 90,
+ /* 30 */ 103, 80, 80, 104, 80,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -185872,6 +199142,7 @@ struct fts5yyParser {
int fts5yyerrcnt; /* Shifts left before out of the error */
#endif
sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */
+ sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */
#if fts5YYSTACKDEPTH<=0
int fts5yystksz; /* Current side of the stack */
fts5yyStackEntry *fts5yystack; /* The parser's stack */
@@ -185915,19 +199186,39 @@ static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
}
#endif /* NDEBUG */
-#ifndef NDEBUG
+#if defined(fts5YYCOVERAGE) || !defined(NDEBUG)
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
- "$", "OR", "AND", "NOT",
- "TERM", "COLON", "MINUS", "LCP",
- "RCP", "STRING", "LP", "RP",
- "COMMA", "PLUS", "STAR", "error",
- "input", "expr", "cnearset", "exprlist",
- "colset", "colsetlist", "nearset", "nearphrases",
- "phrase", "neardist_opt", "star_opt",
+ /* 0 */ "$",
+ /* 1 */ "OR",
+ /* 2 */ "AND",
+ /* 3 */ "NOT",
+ /* 4 */ "TERM",
+ /* 5 */ "COLON",
+ /* 6 */ "MINUS",
+ /* 7 */ "LCP",
+ /* 8 */ "RCP",
+ /* 9 */ "STRING",
+ /* 10 */ "LP",
+ /* 11 */ "RP",
+ /* 12 */ "CARET",
+ /* 13 */ "COMMA",
+ /* 14 */ "PLUS",
+ /* 15 */ "STAR",
+ /* 16 */ "input",
+ /* 17 */ "expr",
+ /* 18 */ "cnearset",
+ /* 19 */ "exprlist",
+ /* 20 */ "colset",
+ /* 21 */ "colsetlist",
+ /* 22 */ "nearset",
+ /* 23 */ "nearphrases",
+ /* 24 */ "phrase",
+ /* 25 */ "neardist_opt",
+ /* 26 */ "star_opt",
};
-#endif /* NDEBUG */
+#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
@@ -185951,15 +199242,16 @@ static const char *const fts5yyRuleName[] = {
/* 15 */ "cnearset ::= nearset",
/* 16 */ "cnearset ::= colset COLON nearset",
/* 17 */ "nearset ::= phrase",
- /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 19 */ "nearphrases ::= phrase",
- /* 20 */ "nearphrases ::= nearphrases phrase",
- /* 21 */ "neardist_opt ::=",
- /* 22 */ "neardist_opt ::= COMMA STRING",
- /* 23 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 24 */ "phrase ::= STRING star_opt",
- /* 25 */ "star_opt ::= STAR",
- /* 26 */ "star_opt ::=",
+ /* 18 */ "nearset ::= CARET phrase",
+ /* 19 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 20 */ "nearphrases ::= phrase",
+ /* 21 */ "nearphrases ::= nearphrases phrase",
+ /* 22 */ "neardist_opt ::=",
+ /* 23 */ "neardist_opt ::= COMMA STRING",
+ /* 24 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 25 */ "phrase ::= STRING star_opt",
+ /* 26 */ "star_opt ::= STAR",
+ /* 27 */ "star_opt ::=",
};
#endif /* NDEBUG */
@@ -186008,28 +199300,29 @@ static int fts5yyGrowStack(fts5yyParser *p){
/* Initialize a new parser that has already been allocated.
*/
-static void sqlite3Fts5ParserInit(void *fts5yypParser){
- fts5yyParser *pParser = (fts5yyParser*)fts5yypParser;
+static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){
+ fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser;
+ sqlite3Fts5ParserCTX_STORE
#ifdef fts5YYTRACKMAXSTACKDEPTH
- pParser->fts5yyhwm = 0;
+ fts5yypParser->fts5yyhwm = 0;
#endif
#if fts5YYSTACKDEPTH<=0
- pParser->fts5yytos = NULL;
- pParser->fts5yystack = NULL;
- pParser->fts5yystksz = 0;
- if( fts5yyGrowStack(pParser) ){
- pParser->fts5yystack = &pParser->fts5yystk0;
- pParser->fts5yystksz = 1;
+ fts5yypParser->fts5yytos = NULL;
+ fts5yypParser->fts5yystack = NULL;
+ fts5yypParser->fts5yystksz = 0;
+ if( fts5yyGrowStack(fts5yypParser) ){
+ fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0;
+ fts5yypParser->fts5yystksz = 1;
}
#endif
#ifndef fts5YYNOERRORRECOVERY
- pParser->fts5yyerrcnt = -1;
+ fts5yypParser->fts5yyerrcnt = -1;
#endif
- pParser->fts5yytos = pParser->fts5yystack;
- pParser->fts5yystack[0].stateno = 0;
- pParser->fts5yystack[0].major = 0;
+ fts5yypParser->fts5yytos = fts5yypParser->fts5yystack;
+ fts5yypParser->fts5yystack[0].stateno = 0;
+ fts5yypParser->fts5yystack[0].major = 0;
#if fts5YYSTACKDEPTH>0
- pParser->fts5yystackEnd = &pParser->fts5yystack[fts5YYSTACKDEPTH-1];
+ fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
#endif
}
@@ -186046,11 +199339,14 @@ static void sqlite3Fts5ParserInit(void *fts5yypParser){
** A pointer to a parser. This pointer is used in subsequent calls
** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
*/
-static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
- fts5yyParser *pParser;
- pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
- if( pParser ) sqlite3Fts5ParserInit(pParser);
- return pParser;
+static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){
+ fts5yyParser *fts5yypParser;
+ fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
+ if( fts5yypParser ){
+ sqlite3Fts5ParserCTX_STORE
+ sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM);
+ }
+ return (void*)fts5yypParser;
}
#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
@@ -186067,7 +199363,8 @@ static void fts5yy_destructor(
fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */
fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */
){
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ sqlite3Fts5ParserCTX_FETCH
switch( fts5yymajor ){
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
@@ -186177,24 +199474,66 @@ static int sqlite3Fts5ParserStackPeak(void *p){
}
#endif
+/* This array of booleans keeps track of the parser statement
+** coverage. The element fts5yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(fts5YYCOVERAGE)
+static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(fts5YYCOVERAGE)
+static int sqlite3Fts5ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<fts5YYNSTATE; stateno++){
+ i = fts5yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){
+ if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ fts5yyTokenName[iLookAhead],
+ fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
*/
-static unsigned int fts5yy_find_shift_action(
- fts5yyParser *pParser, /* The parser */
- fts5YYCODETYPE iLookAhead /* The look-ahead token */
+static fts5YYACTIONTYPE fts5yy_find_shift_action(
+ fts5YYCODETYPE iLookAhead, /* The look-ahead token */
+ fts5YYACTIONTYPE stateno /* Current state number */
){
int i;
- int stateno = pParser->fts5yytos->stateno;
-
- if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
+
+ if( stateno>fts5YY_MAX_SHIFT ) return stateno;
assert( stateno <= fts5YY_SHIFT_COUNT );
+#if defined(fts5YYCOVERAGE)
+ fts5yycoverage[stateno][iLookAhead] = 1;
+#endif
do{
i = fts5yy_shift_ofst[stateno];
+ assert( i>=0 );
+ /* assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD ); */
assert( iLookAhead!=fts5YYNOCODE );
+ assert( iLookAhead < fts5YYNFTS5TOKEN );
i += iLookAhead;
- if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
+ if( i>=fts5YY_NLOOKAHEAD || fts5yy_lookahead[i]!=iLookAhead ){
#ifdef fts5YYFALLBACK
fts5YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
@@ -186220,6 +199559,7 @@ static unsigned int fts5yy_find_shift_action(
#if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
j<fts5YY_ACTTAB_COUNT &&
#endif
+ j<(int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])) &&
fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
){
#ifndef NDEBUG
@@ -186244,8 +199584,8 @@ static unsigned int fts5yy_find_shift_action(
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
*/
-static int fts5yy_find_reduce_action(
- int stateno, /* Current state number */
+static fts5YYACTIONTYPE fts5yy_find_reduce_action(
+ fts5YYACTIONTYPE stateno, /* Current state number */
fts5YYCODETYPE iLookAhead /* The look-ahead token */
){
int i;
@@ -186257,7 +199597,6 @@ static int fts5yy_find_reduce_action(
assert( stateno<=fts5YY_REDUCE_COUNT );
#endif
i = fts5yy_reduce_ofst[stateno];
- assert( i!=fts5YY_REDUCE_USE_DFLT );
assert( iLookAhead!=fts5YYNOCODE );
i += iLookAhead;
#ifdef fts5YYERRORSYMBOL
@@ -186275,7 +199614,8 @@ static int fts5yy_find_reduce_action(
** The following routine is called if the stack overflows.
*/
static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ sqlite3Fts5ParserCTX_FETCH
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
@@ -186288,27 +199628,29 @@ static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
/******** End %stack_overflow code ********************************************/
- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
+ sqlite3Fts5ParserCTX_STORE
}
/*
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
-static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){
if( fts5yyTraceFILE ){
if( fts5yyNewState<fts5YYNSTATE ){
- fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n",
- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
fts5yyNewState);
}else{
- fprintf(fts5yyTraceFILE,"%sShift '%s'\n",
- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major]);
+ fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fts5yyNewState - fts5YY_MIN_REDUCE);
}
}
}
#else
-# define fts5yyTraceShift(X,Y)
+# define fts5yyTraceShift(X,Y,Z)
#endif
/*
@@ -186316,8 +199658,8 @@ static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
*/
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 */
+ fts5YYACTIONTYPE fts5yyNewState, /* The new state to shift in */
+ fts5YYCODETYPE fts5yyMajor, /* The major token to shift in */
sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor /* The minor token to shift in */
){
fts5yyStackEntry *fts5yytos;
@@ -186347,10 +199689,10 @@ static void fts5yy_shift(
fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
}
fts5yytos = fts5yypParser->fts5yytos;
- fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
- fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
+ fts5yytos->stateno = fts5yyNewState;
+ fts5yytos->major = fts5yyMajor;
fts5yytos->minor.fts5yy0 = fts5yyMinor;
- fts5yyTraceShift(fts5yypParser, fts5yyNewState);
+ fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
}
/* The following table contains information about every rule that
@@ -186360,33 +199702,34 @@ static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
signed char nrhs; /* Negative of the number of RHS symbols in the rule */
} fts5yyRuleInfo[] = {
- { 16, -1 },
- { 20, -4 },
- { 20, -3 },
- { 20, -1 },
- { 20, -2 },
- { 21, -2 },
- { 21, -1 },
- { 17, -3 },
- { 17, -3 },
- { 17, -3 },
- { 17, -5 },
- { 17, -3 },
- { 17, -1 },
- { 19, -1 },
- { 19, -2 },
- { 18, -1 },
- { 18, -3 },
- { 22, -1 },
- { 22, -5 },
- { 23, -1 },
- { 23, -2 },
- { 25, 0 },
- { 25, -2 },
- { 24, -4 },
- { 24, -2 },
- { 26, -1 },
- { 26, 0 },
+ { 16, -1 }, /* (0) input ::= expr */
+ { 20, -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
+ { 20, -3 }, /* (2) colset ::= LCP colsetlist RCP */
+ { 20, -1 }, /* (3) colset ::= STRING */
+ { 20, -2 }, /* (4) colset ::= MINUS STRING */
+ { 21, -2 }, /* (5) colsetlist ::= colsetlist STRING */
+ { 21, -1 }, /* (6) colsetlist ::= STRING */
+ { 17, -3 }, /* (7) expr ::= expr AND expr */
+ { 17, -3 }, /* (8) expr ::= expr OR expr */
+ { 17, -3 }, /* (9) expr ::= expr NOT expr */
+ { 17, -5 }, /* (10) expr ::= colset COLON LP expr RP */
+ { 17, -3 }, /* (11) expr ::= LP expr RP */
+ { 17, -1 }, /* (12) expr ::= exprlist */
+ { 19, -1 }, /* (13) exprlist ::= cnearset */
+ { 19, -2 }, /* (14) exprlist ::= exprlist cnearset */
+ { 18, -1 }, /* (15) cnearset ::= nearset */
+ { 18, -3 }, /* (16) cnearset ::= colset COLON nearset */
+ { 22, -1 }, /* (17) nearset ::= phrase */
+ { 22, -2 }, /* (18) nearset ::= CARET phrase */
+ { 22, -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+ { 23, -1 }, /* (20) nearphrases ::= phrase */
+ { 23, -2 }, /* (21) nearphrases ::= nearphrases phrase */
+ { 25, 0 }, /* (22) neardist_opt ::= */
+ { 25, -2 }, /* (23) neardist_opt ::= COMMA STRING */
+ { 24, -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
+ { 24, -2 }, /* (25) phrase ::= STRING star_opt */
+ { 26, -1 }, /* (26) star_opt ::= STAR */
+ { 26, 0 }, /* (27) star_opt ::= */
};
static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
@@ -186394,22 +199737,39 @@ static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
+**
+** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The fts5yyLookahead will be fts5YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
*/
-static void fts5yy_reduce(
+static fts5YYACTIONTYPE fts5yy_reduce(
fts5yyParser *fts5yypParser, /* The parser */
- unsigned int fts5yyruleno /* Number of the rule by which to reduce */
+ unsigned int fts5yyruleno, /* Number of the rule by which to reduce */
+ int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */
+ sqlite3Fts5ParserCTX_PDECL /* %extra_context */
){
int fts5yygoto; /* The next state */
- int fts5yyact; /* The next action */
+ fts5YYACTIONTYPE fts5yyact; /* The next action */
fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */
int fts5yysize; /* Amount to pop the stack */
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ (void)fts5yyLookahead;
+ (void)fts5yyLookaheadToken;
fts5yymsp = fts5yypParser->fts5yytos;
#ifndef NDEBUG
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);
+ if( fts5yysize ){
+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+ fts5yyTracePrompt,
+ fts5yyruleno, fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
+ }else{
+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s].\n",
+ fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno]);
+ }
}
#endif /* NDEBUG */
@@ -186426,13 +199786,19 @@ static void fts5yy_reduce(
#if fts5YYSTACKDEPTH>0
if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){
fts5yyStackOverflow(fts5yypParser);
- return;
+ /* The call to fts5yyStackOverflow() above pops the stack until it is
+ ** empty, causing the main parser loop to exit. So the return value
+ ** is never used and does not matter. */
+ return 0;
}
#else
if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){
if( fts5yyGrowStack(fts5yypParser) ){
fts5yyStackOverflow(fts5yypParser);
- return;
+ /* The call to fts5yyStackOverflow() above pops the stack until it is
+ ** empty, causing the main parser loop to exit. So the return value
+ ** is never used and does not matter. */
+ return 0;
}
fts5yymsp = fts5yypParser->fts5yytos;
}
@@ -186540,7 +199906,13 @@ static void fts5yy_reduce(
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ case 18: /* nearset ::= CARET phrase */
+{
+ sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
+ fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
+}
+ break;
+ case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
@@ -186548,40 +199920,40 @@ static void fts5yy_reduce(
}
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 19: /* nearphrases ::= phrase */
+ case 20: /* nearphrases ::= phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 20: /* nearphrases ::= nearphrases phrase */
+ case 21: /* nearphrases ::= nearphrases phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 21: /* neardist_opt ::= */
+ case 22: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
- case 22: /* neardist_opt ::= COMMA STRING */
+ case 23: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
- case 23: /* phrase ::= phrase PLUS STRING star_opt */
+ case 24: /* phrase ::= phrase PLUS STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 24: /* phrase ::= STRING star_opt */
+ case 25: /* phrase ::= STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 25: /* star_opt ::= STAR */
+ case 26: /* star_opt ::= STAR */
{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
- case 26: /* star_opt ::= */
+ case 27: /* star_opt ::= */
{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
@@ -186600,16 +199972,12 @@ static void fts5yy_reduce(
/* It is not possible for a REDUCE to be followed by an error */
assert( fts5yyact!=fts5YY_ERROR_ACTION );
- if( fts5yyact==fts5YY_ACCEPT_ACTION ){
- fts5yypParser->fts5yytos += fts5yysize;
- fts5yy_accept(fts5yypParser);
- }else{
- fts5yymsp += fts5yysize+1;
- fts5yypParser->fts5yytos = fts5yymsp;
- fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
- fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
- fts5yyTraceShift(fts5yypParser, fts5yyact);
- }
+ fts5yymsp += fts5yysize+1;
+ fts5yypParser->fts5yytos = fts5yymsp;
+ fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+ fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+ fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
+ return fts5yyact;
}
/*
@@ -186619,7 +199987,8 @@ static void fts5yy_reduce(
static void fts5yy_parse_failed(
fts5yyParser *fts5yypParser /* The parser */
){
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ sqlite3Fts5ParserCTX_FETCH
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
@@ -186630,7 +199999,8 @@ static void fts5yy_parse_failed(
** parser fails */
/************ Begin %parse_failure code ***************************************/
/************ End %parse_failure code *****************************************/
- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserCTX_STORE
}
#endif /* fts5YYNOERRORRECOVERY */
@@ -186642,7 +200012,8 @@ static void fts5yy_syntax_error(
int fts5yymajor, /* The major type of the error token */
sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */
){
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ sqlite3Fts5ParserCTX_FETCH
#define FTS5TOKEN fts5yyminor
/************ Begin %syntax_error code ****************************************/
@@ -186651,7 +200022,8 @@ static void fts5yy_syntax_error(
pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
);
/************ End %syntax_error code ******************************************/
- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserCTX_STORE
}
/*
@@ -186660,7 +200032,8 @@ static void fts5yy_syntax_error(
static void fts5yy_accept(
fts5yyParser *fts5yypParser /* The parser */
){
- sqlite3Fts5ParserARG_FETCH;
+ sqlite3Fts5ParserARG_FETCH
+ sqlite3Fts5ParserCTX_FETCH
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
@@ -186674,7 +200047,8 @@ static void fts5yy_accept(
** parser accepts */
/*********** Begin %parse_accept code *****************************************/
/*********** End %parse_accept code *******************************************/
- sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
+ sqlite3Fts5ParserCTX_STORE
}
/* The main parser program.
@@ -186703,38 +200077,51 @@ static void sqlite3Fts5Parser(
sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */
){
fts5YYMINORTYPE fts5yyminorunion;
- unsigned int fts5yyact; /* The parser action. */
+ fts5YYACTIONTYPE fts5yyact; /* The parser action. */
#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
int fts5yyendofinput; /* True if we are at the end of input */
#endif
#ifdef fts5YYERRORSYMBOL
int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */
#endif
- fts5yyParser *fts5yypParser; /* The parser */
+ fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp; /* The parser */
+ sqlite3Fts5ParserCTX_FETCH
+ sqlite3Fts5ParserARG_STORE
- fts5yypParser = (fts5yyParser*)fts5yyp;
assert( fts5yypParser->fts5yytos!=0 );
#if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
fts5yyendofinput = (fts5yymajor==0);
#endif
- sqlite3Fts5ParserARG_STORE;
+ fts5yyact = fts5yypParser->fts5yytos->stateno;
#ifndef NDEBUG
if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
+ if( fts5yyact < fts5YY_MIN_REDUCE ){
+ fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact);
+ }else{
+ fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact-fts5YY_MIN_REDUCE);
+ }
}
#endif
do{
- fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
- if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
- fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
+ assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
+ fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
+ if( fts5yyact >= fts5YY_MIN_REDUCE ){
+ fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor,
+ fts5yyminor sqlite3Fts5ParserCTX_PARAM);
+ }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor);
#ifndef fts5YYNOERRORRECOVERY
fts5yypParser->fts5yyerrcnt--;
#endif
- fts5yymajor = fts5YYNOCODE;
- }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
- fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
+ break;
+ }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
+ fts5yypParser->fts5yytos--;
+ fts5yy_accept(fts5yypParser);
+ return;
}else{
assert( fts5yyact == fts5YY_ERROR_ACTION );
fts5yyminorunion.fts5yy0 = fts5yyminor;
@@ -186801,6 +200188,8 @@ static void sqlite3Fts5Parser(
}
fts5yypParser->fts5yyerrcnt = 3;
fts5yyerrorhit = 1;
+ if( fts5yymajor==fts5YYNOCODE ) break;
+ fts5yyact = fts5yypParser->fts5yytos->stateno;
#elif defined(fts5YYNOERRORRECOVERY)
/* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
** do any kind of error recovery. Instead, simply invoke the syntax
@@ -186811,8 +200200,7 @@ static void sqlite3Fts5Parser(
*/
fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
- fts5yymajor = fts5YYNOCODE;
-
+ break;
#else /* fts5YYERRORSYMBOL is not defined */
/* This is what we do if the grammar does not define ERROR:
**
@@ -186834,10 +200222,10 @@ static void sqlite3Fts5Parser(
fts5yypParser->fts5yyerrcnt = -1;
#endif
}
- fts5yymajor = fts5YYNOCODE;
+ break;
#endif
}
- }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
+ }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fts5yyStackEntry *i;
@@ -186854,6 +200242,21 @@ static void sqlite3Fts5Parser(
}
/*
+** Return the fallback token corresponding to canonical token iToken, or
+** 0 if iToken has no fallback.
+*/
+static int sqlite3Fts5ParserFallback(int iToken){
+#ifdef fts5YYFALLBACK
+ if( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ){
+ return fts5yyFallback[iToken];
+ }
+#else
+ (void)iToken;
+#endif
+ return 0;
+}
+
+/*
** 2014 May 31
**
** The author disclaims copyright to this source code. In place of
@@ -187214,6 +200617,16 @@ static int fts5SnippetScore(
}
/*
+** Return the value in pVal interpreted as utf-8 text. Except, if pVal
+** contains a NULL value, return a pointer to a static string zero
+** bytes in length instead of a NULL pointer.
+*/
+static const char *fts5ValueToText(sqlite3_value *pVal){
+ const char *zRet = (const char*)sqlite3_value_text(pVal);
+ return zRet ? zRet : "";
+}
+
+/*
** Implementation of snippet() function.
*/
static void fts5SnippetFunction(
@@ -187248,9 +200661,9 @@ static void fts5SnippetFunction(
nCol = pApi->xColumnCount(pFts);
memset(&ctx, 0, sizeof(HighlightContext));
iCol = sqlite3_value_int(apVal[0]);
- ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
- ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
- zEllips = (const char*)sqlite3_value_text(apVal[3]);
+ ctx.zOpen = fts5ValueToText(apVal[1]);
+ ctx.zClose = fts5ValueToText(apVal[2]);
+ zEllips = fts5ValueToText(apVal[3]);
nToken = sqlite3_value_int(apVal[4]);
iBestCol = (iCol>=0 ? iCol : 0);
@@ -188953,6 +202366,7 @@ static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
/* #include <stdio.h> */
static void sqlite3Fts5ParserTrace(FILE*, char*);
#endif
+static int sqlite3Fts5ParserFallback(int);
struct Fts5Expr {
@@ -189004,7 +202418,8 @@ struct Fts5ExprNode {
** or term prefix.
*/
struct Fts5ExprTerm {
- int bPrefix; /* True for a prefix term */
+ u8 bPrefix; /* True for a prefix term */
+ u8 bFirst; /* True if token must be first in column */
char *zTerm; /* nul-terminated term */
Fts5IndexIter *pIter; /* Iterator for this term */
Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
@@ -189085,6 +202500,7 @@ static int fts5ExprGetToken(
case '+': tok = FTS5_PLUS; break;
case '*': tok = FTS5_STAR; break;
case '-': tok = FTS5_MINUS; break;
+ case '^': tok = FTS5_CARET; break;
case '\0': tok = FTS5_EOF; break;
case '"': {
@@ -189344,6 +202760,7 @@ static int fts5ExprPhraseIsMatch(
Fts5PoslistReader *aIter = aStatic;
int i;
int rc = SQLITE_OK;
+ int bFirst = pPhrase->aTerm[0].bFirst;
fts5BufferZero(&pPhrase->poslist);
@@ -189398,8 +202815,10 @@ static int fts5ExprPhraseIsMatch(
}while( bMatch==0 );
/* Append position iPos to the output */
- rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
- if( rc!=SQLITE_OK ) goto ismatch_out;
+ if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+ }
for(i=0; i<pPhrase->nTerm; i++){
if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
@@ -189653,7 +203072,9 @@ static int fts5ExprNearTest(
** phrase is not a match, break out of the loop early. */
for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
+ if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym
+ || pNear->pColset || pPhrase->aTerm[0].bFirst
+ ){
int bMatch = 0;
rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
if( bMatch==0 ) break;
@@ -189834,6 +203255,7 @@ static int fts5ExprNodeTest_STRING(
assert( pNear->nPhrase>1
|| pNear->apPhrase[0]->nTerm>1
|| pNear->apPhrase[0]->aTerm[0].pSynonym
+ || pNear->apPhrase[0]->aTerm[0].bFirst
);
/* Initialize iLast, the "lastest" rowid any iterator points to. If the
@@ -190359,6 +203781,16 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
}
/*
+** Set the "bFirst" flag on the first token of the phrase passed as the
+** only argument.
+*/
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
+ if( pPhrase && pPhrase->nTerm ){
+ pPhrase->aTerm[0].bFirst = 1;
+ }
+}
+
+/*
** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
** appended to it and the results returned.
@@ -190575,7 +204007,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
** 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;
+ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
}
pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
}
@@ -190636,6 +204068,7 @@ static int sqlite3Fts5ExprClonePhrase(
}
if( rc==SQLITE_OK ){
sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
}
}
}else{
@@ -190654,7 +204087,10 @@ static int sqlite3Fts5ExprClonePhrase(
pNew->pRoot->pNear->nPhrase = 1;
sCtx.pPhrase->pNode = pNew->pRoot;
- if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
+ if( pOrig->nTerm==1
+ && pOrig->aTerm[0].pSynonym==0
+ && pOrig->aTerm[0].bFirst==0
+ ){
pNew->pRoot->eType = FTS5_TERM;
pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
}else{
@@ -190928,6 +204364,7 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
Fts5ExprNearset *pNear = pNode->pNear;
if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1
&& pNear->apPhrase[0]->aTerm[0].pSynonym==0
+ && pNear->apPhrase[0]->aTerm[0].bFirst==0
){
pNode->eType = FTS5_TERM;
pNode->xNext = fts5ExprNodeNext_TERM;
@@ -191014,20 +204451,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
}
}
- if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL
- && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
- ){
- assert( pParse->rc==SQLITE_OK );
- pParse->rc = SQLITE_ERROR;
- assert( pParse->zErr==0 );
- pParse->zErr = sqlite3_mprintf(
- "fts5: %s queries are not supported (detail!=full)",
- pNear->nPhrase==1 ? "phrase": "NEAR"
- );
- sqlite3_free(pRet);
- pRet = 0;
+ if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
+ if( pNear->nPhrase!=1
+ || pPhrase->nTerm>1
+ || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
+ ){
+ assert( pParse->rc==SQLITE_OK );
+ pParse->rc = SQLITE_ERROR;
+ assert( pParse->zErr==0 );
+ pParse->zErr = sqlite3_mprintf(
+ "fts5: %s queries are not supported (detail!=full)",
+ pNear->nPhrase==1 ? "phrase": "NEAR"
+ );
+ sqlite3_free(pRet);
+ pRet = 0;
+ }
}
-
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
@@ -191431,14 +204871,19 @@ static void fts5ExprIsAlnum(
sqlite3_value **apVal /* Function arguments */
){
int iCode;
+ u8 aArr[32];
if( nArg!=1 ){
sqlite3_result_error(pCtx,
"wrong number of arguments to function fts5_isalnum", -1
);
return;
}
+ memset(aArr, 0, sizeof(aArr));
+ sqlite3Fts5UnicodeCatParse("L*", aArr);
+ sqlite3Fts5UnicodeCatParse("N*", aArr);
+ sqlite3Fts5UnicodeCatParse("Co", aArr);
iCode = sqlite3_value_int(apVal[0]);
- sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
+ sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
}
static void fts5ExprFold(
@@ -191482,10 +204927,12 @@ static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
rc = sqlite3_create_function_v2(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0, 0);
}
- /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
+ /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
+ ** sqlite3Fts5ParserFallback() are unused */
#ifndef NDEBUG
(void)sqlite3Fts5ParserTrace;
#endif
+ (void)sqlite3Fts5ParserFallback;
return rc;
}
@@ -193030,6 +206477,7 @@ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
sqlite3_step(p->pWriter);
p->rc = sqlite3_reset(p->pWriter);
+ sqlite3_bind_null(p->pWriter, 2);
}
/*
@@ -194658,6 +208106,7 @@ static void fts5SegIterSeekInit(
bDlidx = (val & 0x0001);
}
p->rc = sqlite3_reset(pIdxSelect);
+ sqlite3_bind_null(pIdxSelect, 2);
if( iPg<pSeg->pgnoFirst ){
iPg = pSeg->pgnoFirst;
@@ -195870,6 +209319,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
p->rc = sqlite3_reset(pIdxSelect);
+ sqlite3_bind_null(pIdxSelect, 2);
}
}
#endif
@@ -195996,6 +209446,7 @@ static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
sqlite3_step(p->pIdxWriter);
p->rc = sqlite3_reset(p->pIdxWriter);
+ sqlite3_bind_null(p->pIdxWriter, 2);
}
pWriter->iBtPage = 0;
}
@@ -197181,7 +210632,13 @@ static void fts5MergePrefixLists(
Fts5Buffer out = {0, 0, 0};
Fts5Buffer tmp = {0, 0, 0};
- if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
+ /* The maximum size of the output is equal to the sum of the two
+ ** input sizes + 1 varint (9 bytes). The extra varint is because if the
+ ** first rowid in one input is a large negative number, and the first in
+ ** the other a non-negative number, the delta for the non-negative
+ ** number will be larger on disk than the literal integer value
+ ** was. */
+ if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
fts5DoclistIterInit(p1, &i1);
fts5DoclistIterInit(p2, &i2);
@@ -197275,6 +210732,7 @@ static void fts5MergePrefixLists(
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
}
+ assert( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(&tmp);
@@ -197522,7 +210980,10 @@ static int sqlite3Fts5IndexCharlenToBytelen(
for(i=0; i<nChar; i++){
if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */
if( (unsigned char)p[n++]>=0xc0 ){
- while( (p[n] & 0xc0)==0x80 ) n++;
+ while( (p[n] & 0xc0)==0x80 ){
+ n++;
+ if( n>=nByte ) break;
+ }
}
}
return n;
@@ -199049,7 +212510,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
case FTS5_SAVEPOINT:
assert( p->ts.eState==1 );
assert( iSavepoint>=0 );
- assert( iSavepoint>p->ts.iSavepoint );
+ assert( iSavepoint>=p->ts.iSavepoint );
p->ts.iSavepoint = iSavepoint;
break;
@@ -199304,6 +212765,12 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
aColMap[1] = nCol;
aColMap[2] = nCol+1;
+ assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
+ assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
+ assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
+ assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
+ assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
+
/* Set idxFlags flags for all WHERE clause terms that will be used. */
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
@@ -199322,11 +212789,11 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
pInfo->estimatedCost = 1e50;
return SQLITE_OK;
}
- }else{
+ }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
int j;
for(j=1; j<ArraySize(aConstraint); j++){
struct Constraint *pC = &aConstraint[j];
- if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
+ if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
pC->iConsIndex = i;
idxFlags |= pC->fts5op;
}
@@ -199968,6 +213435,13 @@ static int fts5FilterMethod(
assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
assert( pCsr->iLastRowid==LARGEST_INT64 );
assert( pCsr->iFirstRowid==SMALLEST_INT64 );
+ if( pTab->pSortCsr->bDesc ){
+ pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
+ pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
+ }else{
+ pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
+ pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
+ }
pCsr->ePlan = FTS5_PLAN_SOURCE;
pCsr->pExpr = pTab->pSortCsr->pExpr;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
@@ -201398,7 +214872,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
@@ -201974,6 +215448,7 @@ static int fts5StorageInsertDocsize(
sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
+ sqlite3_bind_null(pReplace, 2);
}
}
return rc;
@@ -202634,6 +216109,7 @@ static int sqlite3Fts5StorageConfigValue(
}
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
+ sqlite3_bind_null(pReplace, 1);
}
if( rc==SQLITE_OK && pVal ){
int iNew = p->pConfig->iCookie + 1;
@@ -202884,6 +216360,8 @@ struct Unicode61Tokenizer {
int bRemoveDiacritic; /* True if remove_diacritics=1 is set */
int nException;
int *aiException;
+
+ unsigned char aCategory[32]; /* True for token char categories */
};
static int fts5UnicodeAddExceptions(
@@ -202908,7 +216386,7 @@ static int fts5UnicodeAddExceptions(
if( iCode<128 ){
p->aTokenChar[iCode] = (unsigned char)bTokenChars;
}else{
- bToken = sqlite3Fts5UnicodeIsalnum(iCode);
+ bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
assert( (bToken==0 || bToken==1) );
assert( (bTokenChars==0 || bTokenChars==1) );
if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
@@ -202969,6 +216447,21 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
return;
}
+static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
+ const char *z = zCat;
+
+ while( *z ){
+ while( *z==' ' || *z=='\t' ) z++;
+ if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){
+ return SQLITE_ERROR;
+ }
+ while( *z!=' ' && *z!='\t' && *z!='\0' ) z++;
+ }
+
+ sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar);
+ return SQLITE_OK;
+}
+
/*
** Create a "unicode61" tokenizer.
*/
@@ -202987,15 +216480,28 @@ static int fts5UnicodeCreate(
}else{
p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
if( p ){
+ const char *zCat = "L* N* Co";
int i;
memset(p, 0, sizeof(Unicode61Tokenizer));
- memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
+
p->bRemoveDiacritic = 1;
p->nFold = 64;
p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
if( p->aFold==0 ){
rc = SQLITE_NOMEM;
}
+
+ /* Search for a "categories" argument */
+ for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+ if( 0==sqlite3_stricmp(azArg[i], "categories") ){
+ zCat = azArg[i+1];
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = unicodeSetCategories(p, zCat);
+ }
+
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
@@ -203009,10 +216515,14 @@ static int fts5UnicodeCreate(
}else
if( 0==sqlite3_stricmp(azArg[i], "separators") ){
rc = fts5UnicodeAddExceptions(p, zArg, 0);
+ }else
+ if( 0==sqlite3_stricmp(azArg[i], "categories") ){
+ /* no-op */
}else{
rc = SQLITE_ERROR;
}
}
+
}else{
rc = SQLITE_NOMEM;
}
@@ -203031,8 +216541,10 @@ static int fts5UnicodeCreate(
** character (not a separator).
*/
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
- assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
- return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
+ return (
+ p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
+ ^ fts5UnicodeIsException(p, iCode)
+ );
}
static int fts5UnicodeTokenize(
@@ -203909,150 +217421,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
/* #include <assert.h> */
-/*
-** Return true if the argument corresponds to a unicode codepoint
-** classified as either a letter or a number. Otherwise false.
-**
-** The results are undefined if the value passed to this function
-** is less than zero.
-*/
-static int sqlite3Fts5UnicodeIsalnum(int c){
- /* Each unsigned integer in the following array corresponds to a contiguous
- ** range of unicode codepoints that are not either letters or numbers (i.e.
- ** codepoints for which this function should return 0).
- **
- ** The most significant 22 bits in each 32-bit value contain the first
- ** codepoint in the range. The least significant 10 bits are used to store
- ** the size of the range (always at least 1). In other words, the value
- ** ((C<<22) + N) represents a range of N codepoints starting with codepoint
- ** C. It is not possible to represent a range larger than 1023 codepoints
- ** using this format.
- */
- static const unsigned int aEntry[] = {
- 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
- 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
- 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
- 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
- 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163403,
- 0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15,
- 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07,
- 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B,
- 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09,
- 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
- 0x00235030, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
- 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02,
- 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802,
- 0x0027F401, 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02,
- 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403,
- 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802,
- 0x002BC002, 0x002BE806, 0x002C0403, 0x002CF001, 0x002CF807,
- 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
- 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
- 0x002FCC08, 0x00300004, 0x0030F807, 0x00311803, 0x00312804,
- 0x00315402, 0x00318802, 0x0031FC01, 0x00320403, 0x0032F001,
- 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
- 0x00340004, 0x0034EC02, 0x0034F807, 0x00351803, 0x00352804,
- 0x00353C01, 0x00355C01, 0x00358802, 0x0035E401, 0x00360802,
- 0x00372801, 0x00373C06, 0x00375801, 0x00376008, 0x0037C803,
- 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09, 0x00396802,
- 0x003AC401, 0x003AD006, 0x003AEC02, 0x003B2006, 0x003C041F,
- 0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424, 0x003EF80F,
- 0x003F380D, 0x0040AC14, 0x00412806, 0x00415804, 0x00417803,
- 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C, 0x00423C01,
- 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A, 0x00500001,
- 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03, 0x005C4803,
- 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023, 0x005F6004,
- 0x005F7401, 0x0060000F, 0x00621402, 0x0062A401, 0x0064800C,
- 0x0064C00C, 0x00650001, 0x00651002, 0x00677822, 0x00685C05,
- 0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007,
- 0x006AA006, 0x006AC00F, 0x006C0005, 0x006CD011, 0x006D6823,
- 0x006E0003, 0x006E840D, 0x006F980E, 0x006FF004, 0x00709014,
- 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019, 0x0073B401,
- 0x0073C803, 0x0073DC03, 0x0077003A, 0x0077EC05, 0x007EF401,
- 0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403, 0x007FF402,
- 0x00800065, 0x0081980A, 0x0081E805, 0x00822805, 0x00828020,
- 0x00834021, 0x00840002, 0x00840C04, 0x00842002, 0x00845001,
- 0x00845803, 0x00847806, 0x00849401, 0x00849C01, 0x0084A401,
- 0x0084B801, 0x0084E802, 0x00850005, 0x00852804, 0x00853C01,
- 0x00862802, 0x00864297, 0x0091000B, 0x0092704E, 0x00940276,
- 0x009E53E0, 0x00ADD820, 0x00AE6022, 0x00AEF40C, 0x00AF2809,
- 0x00AFB004, 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802,
- 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C01A, 0x00BA001A,
- 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019,
- 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001,
- 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F,
- 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F,
- 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802, 0x02983403,
- 0x0299BC10, 0x029A7802, 0x029BC008, 0x029C0017, 0x029C8002,
- 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09,
- 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D012, 0x02A33802,
- 0x02A38012, 0x02A3E003, 0x02A3F001, 0x02A4980A, 0x02A51C0D,
- 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401,
- 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03,
- 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802,
- 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402, 0x02AD6C01,
- 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, 0x037FFC01,
- 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, 0x03F7F002,
- 0x03F8001A, 0x03F88033, 0x03F95013, 0x03F9A004, 0x03FBFC01,
- 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B, 0x03FF8007,
- 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09, 0x0405E411,
- 0x04063003, 0x0406400C, 0x04068001, 0x0407402E, 0x040B8001,
- 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01, 0x04215C01,
- 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403, 0x04281402,
- 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, 0x0429FC01,
- 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407, 0x042E6404,
- 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012, 0x04440003,
- 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003, 0x0446CC0E,
- 0x04471409, 0x04476C01, 0x04477403, 0x0448B013, 0x044AA401,
- 0x044B7C0C, 0x044C0004, 0x044CF001, 0x044CF807, 0x044D1C02,
- 0x044D2C03, 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005,
- 0x0450D412, 0x04512C05, 0x04516C01, 0x04517401, 0x0452C014,
- 0x04531801, 0x0456BC07, 0x0456E020, 0x04577002, 0x0458C014,
- 0x0459800D, 0x045AAC0D, 0x045C740F, 0x045CF004, 0x0468040A,
- 0x0468CC07, 0x0468EC0D, 0x0469440B, 0x046A2813, 0x046A7805,
- 0x0470BC08, 0x0470E008, 0x04710405, 0x0471C002, 0x04724816,
- 0x0472A40E, 0x0474C406, 0x0474E801, 0x0474F002, 0x0474FC07,
- 0x04751C01, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
- 0x05AD1002, 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6,
- 0x07440027, 0x0744A4C0, 0x07480046, 0x074C0057, 0x075B0401,
- 0x075B6C01, 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01,
- 0x075DBC01, 0x075E2401, 0x075EA401, 0x075F0C01, 0x0760028C,
- 0x076A6C05, 0x076A840F, 0x07800007, 0x07802011, 0x07806C07,
- 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007, 0x07A57802,
- 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F,
- 0x07C3040F, 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C03D,
- 0x07C7981D, 0x07C8402C, 0x07C90009, 0x07C94002, 0x07C98006,
- 0x07CC03D5, 0x07DB800D, 0x07DBC009, 0x07DC0074, 0x07DE0055,
- 0x07E0000C, 0x07E04038, 0x07E1400A, 0x07E18028, 0x07E2401E,
- 0x07E4000C, 0x07E4402F, 0x07E5000D, 0x07E5401C, 0x07E60018,
- 0x07E70001, 0x07E74017, 0x38000401, 0x38008060, 0x380400F0,
- };
- static const unsigned int aAscii[4] = {
- 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
- };
-
- if( (unsigned int)c<128 ){
- return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
- }else if( (unsigned int)c<(1<<22) ){
- unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
- int iRes = 0;
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
- int iLo = 0;
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( key >= aEntry[iTest] ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- assert( aEntry[0]<key );
- assert( key>=aEntry[iRes] );
- return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
- }
- return 1;
-}
/*
@@ -204113,7 +217481,7 @@ static int fts5_remove_diacritic(int c){
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
-static int sqlite3Fts5UnicodeIsdiacritic(int c){
+SQLITE_PRIVATE int sqlite3Fts5UnicodeIsdiacritic(int c){
unsigned int mask0 = 0x08029FDF;
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
@@ -204132,7 +217500,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
-static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
+SQLITE_PRIVATE int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -204157,8 +217525,8 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
} aEntry[] = {
{65, 14, 26}, {181, 66, 1}, {192, 14, 23},
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
- {313, 1, 16}, {330, 1, 46}, {376, 150, 1},
- {377, 1, 6}, {383, 138, 1}, {385, 52, 1},
+ {313, 1, 16}, {330, 1, 46}, {376, 152, 1},
+ {377, 1, 6}, {383, 140, 1}, {385, 52, 1},
{386, 1, 4}, {390, 46, 1}, {391, 0, 1},
{393, 44, 2}, {395, 0, 1}, {398, 34, 1},
{399, 40, 1}, {400, 42, 1}, {401, 0, 1},
@@ -204171,51 +217539,52 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
- {497, 2, 1}, {498, 1, 4}, {502, 156, 1},
- {503, 168, 1}, {504, 1, 40}, {544, 144, 1},
+ {497, 2, 1}, {498, 1, 4}, {502, 158, 1},
+ {503, 170, 1}, {504, 1, 40}, {544, 146, 1},
{546, 1, 18}, {570, 74, 1}, {571, 0, 1},
- {573, 142, 1}, {574, 72, 1}, {577, 0, 1},
- {579, 140, 1}, {580, 30, 1}, {581, 32, 1},
+ {573, 144, 1}, {574, 72, 1}, {577, 0, 1},
+ {579, 142, 1}, {580, 30, 1}, {581, 32, 1},
{582, 1, 10}, {837, 38, 1}, {880, 1, 4},
{886, 0, 1}, {895, 38, 1}, {902, 20, 1},
{904, 18, 3}, {908, 28, 1}, {910, 26, 2},
{913, 14, 17}, {931, 14, 9}, {962, 0, 1},
- {975, 4, 1}, {976, 174, 1}, {977, 176, 1},
- {981, 180, 1}, {982, 178, 1}, {984, 1, 24},
- {1008, 170, 1}, {1009, 172, 1}, {1012, 164, 1},
- {1013, 162, 1}, {1015, 0, 1}, {1017, 186, 1},
- {1018, 0, 1}, {1021, 144, 3}, {1024, 36, 16},
+ {975, 4, 1}, {976, 176, 1}, {977, 178, 1},
+ {981, 182, 1}, {982, 180, 1}, {984, 1, 24},
+ {1008, 172, 1}, {1009, 174, 1}, {1012, 166, 1},
+ {1013, 164, 1}, {1015, 0, 1}, {1017, 188, 1},
+ {1018, 0, 1}, {1021, 146, 3}, {1024, 36, 16},
{1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54},
{1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
{1329, 24, 38}, {4256, 70, 38}, {4295, 70, 1},
- {4301, 70, 1}, {5112, 184, 6}, {7296, 122, 1},
+ {4301, 70, 1}, {5112, 186, 6}, {7296, 122, 1},
{7297, 124, 1}, {7298, 126, 1}, {7299, 130, 2},
{7301, 128, 1}, {7302, 132, 1}, {7303, 134, 1},
- {7304, 96, 1}, {7680, 1, 150}, {7835, 166, 1},
- {7838, 116, 1}, {7840, 1, 96}, {7944, 184, 8},
- {7960, 184, 6}, {7976, 184, 8}, {7992, 184, 8},
- {8008, 184, 6}, {8025, 185, 8}, {8040, 184, 8},
- {8072, 184, 8}, {8088, 184, 8}, {8104, 184, 8},
- {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
- {8126, 120, 1}, {8136, 158, 4}, {8140, 182, 1},
- {8152, 184, 2}, {8154, 154, 2}, {8168, 184, 2},
- {8170, 152, 2}, {8172, 186, 1}, {8184, 146, 2},
- {8186, 148, 2}, {8188, 182, 1}, {8486, 118, 1},
- {8490, 112, 1}, {8491, 114, 1}, {8498, 12, 1},
- {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26},
- {11264, 24, 47}, {11360, 0, 1}, {11362, 108, 1},
- {11363, 136, 1}, {11364, 110, 1}, {11367, 1, 6},
- {11373, 104, 1}, {11374, 106, 1}, {11375, 100, 1},
- {11376, 102, 1}, {11378, 0, 1}, {11381, 0, 1},
- {11390, 98, 2}, {11392, 1, 100}, {11499, 1, 4},
- {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28},
- {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4},
- {42877, 94, 1}, {42878, 1, 10}, {42891, 0, 1},
- {42893, 86, 1}, {42896, 1, 4}, {42902, 1, 20},
- {42922, 80, 1}, {42923, 76, 1}, {42924, 78, 1},
- {42925, 82, 1}, {42926, 80, 1}, {42928, 90, 1},
- {42929, 84, 1}, {42930, 88, 1}, {42931, 68, 1},
- {42932, 1, 4}, {43888, 92, 80}, {65313, 14, 26},
+ {7304, 96, 1}, {7312, 138, 43}, {7357, 138, 3},
+ {7680, 1, 150}, {7835, 168, 1}, {7838, 116, 1},
+ {7840, 1, 96}, {7944, 186, 8}, {7960, 186, 6},
+ {7976, 186, 8}, {7992, 186, 8}, {8008, 186, 6},
+ {8025, 187, 8}, {8040, 186, 8}, {8072, 186, 8},
+ {8088, 186, 8}, {8104, 186, 8}, {8120, 186, 2},
+ {8122, 162, 2}, {8124, 184, 1}, {8126, 120, 1},
+ {8136, 160, 4}, {8140, 184, 1}, {8152, 186, 2},
+ {8154, 156, 2}, {8168, 186, 2}, {8170, 154, 2},
+ {8172, 188, 1}, {8184, 148, 2}, {8186, 150, 2},
+ {8188, 184, 1}, {8486, 118, 1}, {8490, 112, 1},
+ {8491, 114, 1}, {8498, 12, 1}, {8544, 8, 16},
+ {8579, 0, 1}, {9398, 10, 26}, {11264, 24, 47},
+ {11360, 0, 1}, {11362, 108, 1}, {11363, 136, 1},
+ {11364, 110, 1}, {11367, 1, 6}, {11373, 104, 1},
+ {11374, 106, 1}, {11375, 100, 1}, {11376, 102, 1},
+ {11378, 0, 1}, {11381, 0, 1}, {11390, 98, 2},
+ {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
+ {42560, 1, 46}, {42624, 1, 28}, {42786, 1, 14},
+ {42802, 1, 62}, {42873, 1, 4}, {42877, 94, 1},
+ {42878, 1, 10}, {42891, 0, 1}, {42893, 86, 1},
+ {42896, 1, 4}, {42902, 1, 20}, {42922, 80, 1},
+ {42923, 76, 1}, {42924, 78, 1}, {42925, 82, 1},
+ {42926, 80, 1}, {42928, 90, 1}, {42929, 84, 1},
+ {42930, 88, 1}, {42931, 68, 1}, {42932, 1, 6},
+ {43888, 92, 80}, {65313, 14, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
@@ -204226,10 +217595,10 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
23228, 23231, 23254, 23256, 23275, 23278, 26672, 30204,
35267, 54721, 54753, 54754, 54756, 54787, 54793, 54809,
57153, 57274, 57921, 58019, 58363, 59314, 59315, 59324,
- 59325, 59326, 59332, 59356, 61722, 65268, 65341, 65373,
- 65406, 65408, 65410, 65415, 65424, 65436, 65439, 65450,
- 65462, 65472, 65476, 65478, 65480, 65482, 65488, 65506,
- 65511, 65514, 65521, 65527, 65528, 65529,
+ 59325, 59326, 59332, 59356, 61722, 62528, 65268, 65341,
+ 65373, 65406, 65408, 65410, 65415, 65424, 65436, 65439,
+ 65450, 65462, 65472, 65476, 65478, 65480, 65482, 65488,
+ 65506, 65511, 65514, 65521, 65527, 65528, 65529,
};
int ret = c;
@@ -204278,6 +217647,9 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
else if( c>=71840 && c<71872 ){
ret = c + 32;
}
+ else if( c>=93760 && c<93792 ){
+ ret = c + 32;
+ }
else if( c>=125184 && c<125218 ){
ret = c + 34;
}
@@ -204285,6 +217657,615 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
return ret;
}
+
+#if 0
+static int sqlite3Fts5UnicodeNCat(void) {
+ return 32;
+}
+#endif
+
+SQLITE_PRIVATE int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
+ aArray[0] = 1;
+ switch( zCat[0] ){
+ case 'C':
+ switch( zCat[1] ){
+ case 'c': aArray[1] = 1; break;
+ case 'f': aArray[2] = 1; break;
+ case 'n': aArray[3] = 1; break;
+ case 's': aArray[4] = 1; break;
+ case 'o': aArray[31] = 1; break;
+ case '*':
+ aArray[1] = 1;
+ aArray[2] = 1;
+ aArray[3] = 1;
+ aArray[4] = 1;
+ aArray[31] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'L':
+ switch( zCat[1] ){
+ case 'l': aArray[5] = 1; break;
+ case 'm': aArray[6] = 1; break;
+ case 'o': aArray[7] = 1; break;
+ case 't': aArray[8] = 1; break;
+ case 'u': aArray[9] = 1; break;
+ case 'C': aArray[30] = 1; break;
+ case '*':
+ aArray[5] = 1;
+ aArray[6] = 1;
+ aArray[7] = 1;
+ aArray[8] = 1;
+ aArray[9] = 1;
+ aArray[30] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'M':
+ switch( zCat[1] ){
+ case 'c': aArray[10] = 1; break;
+ case 'e': aArray[11] = 1; break;
+ case 'n': aArray[12] = 1; break;
+ case '*':
+ aArray[10] = 1;
+ aArray[11] = 1;
+ aArray[12] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'N':
+ switch( zCat[1] ){
+ case 'd': aArray[13] = 1; break;
+ case 'l': aArray[14] = 1; break;
+ case 'o': aArray[15] = 1; break;
+ case '*':
+ aArray[13] = 1;
+ aArray[14] = 1;
+ aArray[15] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'P':
+ switch( zCat[1] ){
+ case 'c': aArray[16] = 1; break;
+ case 'd': aArray[17] = 1; break;
+ case 'e': aArray[18] = 1; break;
+ case 'f': aArray[19] = 1; break;
+ case 'i': aArray[20] = 1; break;
+ case 'o': aArray[21] = 1; break;
+ case 's': aArray[22] = 1; break;
+ case '*':
+ aArray[16] = 1;
+ aArray[17] = 1;
+ aArray[18] = 1;
+ aArray[19] = 1;
+ aArray[20] = 1;
+ aArray[21] = 1;
+ aArray[22] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'S':
+ switch( zCat[1] ){
+ case 'c': aArray[23] = 1; break;
+ case 'k': aArray[24] = 1; break;
+ case 'm': aArray[25] = 1; break;
+ case 'o': aArray[26] = 1; break;
+ case '*':
+ aArray[23] = 1;
+ aArray[24] = 1;
+ aArray[25] = 1;
+ aArray[26] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ case 'Z':
+ switch( zCat[1] ){
+ case 'l': aArray[27] = 1; break;
+ case 'p': aArray[28] = 1; break;
+ case 's': aArray[29] = 1; break;
+ case '*':
+ aArray[27] = 1;
+ aArray[28] = 1;
+ aArray[29] = 1;
+ break;
+ default: return 1; }
+ break;
+
+ }
+ return 0;
+}
+
+static const u16 aFts5UnicodeBlock[] = {
+ 0, 1538, 2131, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ 2142, 2142, 2142, 2142, 2142, 2145, 2147,
+ };
+static const u16 aFts5UnicodeMap[] = {
+ 0, 32, 33, 36, 37, 40, 41, 42, 43, 44,
+ 45, 46, 48, 58, 60, 63, 65, 91, 92, 93,
+ 94, 95, 96, 97, 123, 124, 125, 126, 127, 160,
+ 161, 162, 166, 167, 168, 169, 170, 171, 172, 173,
+ 174, 175, 176, 177, 178, 180, 181, 182, 184, 185,
+ 186, 187, 188, 191, 192, 215, 216, 223, 247, 248,
+ 256, 312, 313, 329, 330, 377, 383, 385, 387, 388,
+ 391, 394, 396, 398, 402, 403, 405, 406, 409, 412,
+ 414, 415, 417, 418, 423, 427, 428, 431, 434, 436,
+ 437, 440, 442, 443, 444, 446, 448, 452, 453, 454,
+ 455, 456, 457, 458, 459, 460, 461, 477, 478, 496,
+ 497, 498, 499, 500, 503, 505, 506, 564, 570, 572,
+ 573, 575, 577, 580, 583, 584, 592, 660, 661, 688,
+ 706, 710, 722, 736, 741, 748, 749, 750, 751, 768,
+ 880, 884, 885, 886, 890, 891, 894, 895, 900, 902,
+ 903, 904, 908, 910, 912, 913, 931, 940, 975, 977,
+ 978, 981, 984, 1008, 1012, 1014, 1015, 1018, 1020, 1021,
+ 1072, 1120, 1154, 1155, 1160, 1162, 1217, 1231, 1232, 1329,
+ 1369, 1370, 1376, 1417, 1418, 1421, 1423, 1425, 1470, 1471,
+ 1472, 1473, 1475, 1476, 1478, 1479, 1488, 1519, 1523, 1536,
+ 1542, 1545, 1547, 1548, 1550, 1552, 1563, 1564, 1566, 1568,
+ 1600, 1601, 1611, 1632, 1642, 1646, 1648, 1649, 1748, 1749,
+ 1750, 1757, 1758, 1759, 1765, 1767, 1769, 1770, 1774, 1776,
+ 1786, 1789, 1791, 1792, 1807, 1808, 1809, 1810, 1840, 1869,
+ 1958, 1969, 1984, 1994, 2027, 2036, 2038, 2039, 2042, 2045,
+ 2046, 2048, 2070, 2074, 2075, 2084, 2085, 2088, 2089, 2096,
+ 2112, 2137, 2142, 2144, 2208, 2230, 2259, 2274, 2275, 2307,
+ 2308, 2362, 2363, 2364, 2365, 2366, 2369, 2377, 2381, 2382,
+ 2384, 2385, 2392, 2402, 2404, 2406, 2416, 2417, 2418, 2433,
+ 2434, 2437, 2447, 2451, 2474, 2482, 2486, 2492, 2493, 2494,
+ 2497, 2503, 2507, 2509, 2510, 2519, 2524, 2527, 2530, 2534,
+ 2544, 2546, 2548, 2554, 2555, 2556, 2557, 2558, 2561, 2563,
+ 2565, 2575, 2579, 2602, 2610, 2613, 2616, 2620, 2622, 2625,
+ 2631, 2635, 2641, 2649, 2654, 2662, 2672, 2674, 2677, 2678,
+ 2689, 2691, 2693, 2703, 2707, 2730, 2738, 2741, 2748, 2749,
+ 2750, 2753, 2759, 2761, 2763, 2765, 2768, 2784, 2786, 2790,
+ 2800, 2801, 2809, 2810, 2817, 2818, 2821, 2831, 2835, 2858,
+ 2866, 2869, 2876, 2877, 2878, 2879, 2880, 2881, 2887, 2891,
+ 2893, 2902, 2903, 2908, 2911, 2914, 2918, 2928, 2929, 2930,
+ 2946, 2947, 2949, 2958, 2962, 2969, 2972, 2974, 2979, 2984,
+ 2990, 3006, 3008, 3009, 3014, 3018, 3021, 3024, 3031, 3046,
+ 3056, 3059, 3065, 3066, 3072, 3073, 3076, 3077, 3086, 3090,
+ 3114, 3133, 3134, 3137, 3142, 3146, 3157, 3160, 3168, 3170,
+ 3174, 3192, 3199, 3200, 3201, 3202, 3204, 3205, 3214, 3218,
+ 3242, 3253, 3260, 3261, 3262, 3263, 3264, 3270, 3271, 3274,
+ 3276, 3285, 3294, 3296, 3298, 3302, 3313, 3328, 3330, 3333,
+ 3342, 3346, 3387, 3389, 3390, 3393, 3398, 3402, 3405, 3406,
+ 3407, 3412, 3415, 3416, 3423, 3426, 3430, 3440, 3449, 3450,
+ 3458, 3461, 3482, 3507, 3517, 3520, 3530, 3535, 3538, 3542,
+ 3544, 3558, 3570, 3572, 3585, 3633, 3634, 3636, 3647, 3648,
+ 3654, 3655, 3663, 3664, 3674, 3713, 3716, 3719, 3722, 3725,
+ 3732, 3737, 3745, 3749, 3751, 3754, 3757, 3761, 3762, 3764,
+ 3771, 3773, 3776, 3782, 3784, 3792, 3804, 3840, 3841, 3844,
+ 3859, 3860, 3861, 3864, 3866, 3872, 3882, 3892, 3893, 3894,
+ 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3904, 3913,
+ 3953, 3967, 3968, 3973, 3974, 3976, 3981, 3993, 4030, 4038,
+ 4039, 4046, 4048, 4053, 4057, 4096, 4139, 4141, 4145, 4146,
+ 4152, 4153, 4155, 4157, 4159, 4160, 4170, 4176, 4182, 4184,
+ 4186, 4190, 4193, 4194, 4197, 4199, 4206, 4209, 4213, 4226,
+ 4227, 4229, 4231, 4237, 4238, 4239, 4240, 4250, 4253, 4254,
+ 4256, 4295, 4301, 4304, 4347, 4348, 4349, 4352, 4682, 4688,
+ 4696, 4698, 4704, 4746, 4752, 4786, 4792, 4800, 4802, 4808,
+ 4824, 4882, 4888, 4957, 4960, 4969, 4992, 5008, 5024, 5112,
+ 5120, 5121, 5741, 5743, 5760, 5761, 5787, 5788, 5792, 5867,
+ 5870, 5873, 5888, 5902, 5906, 5920, 5938, 5941, 5952, 5970,
+ 5984, 5998, 6002, 6016, 6068, 6070, 6071, 6078, 6086, 6087,
+ 6089, 6100, 6103, 6104, 6107, 6108, 6109, 6112, 6128, 6144,
+ 6150, 6151, 6155, 6158, 6160, 6176, 6211, 6212, 6272, 6277,
+ 6279, 6313, 6314, 6320, 6400, 6432, 6435, 6439, 6441, 6448,
+ 6450, 6451, 6457, 6464, 6468, 6470, 6480, 6512, 6528, 6576,
+ 6608, 6618, 6622, 6656, 6679, 6681, 6683, 6686, 6688, 6741,
+ 6742, 6743, 6744, 6752, 6753, 6754, 6755, 6757, 6765, 6771,
+ 6783, 6784, 6800, 6816, 6823, 6824, 6832, 6846, 6912, 6916,
+ 6917, 6964, 6965, 6966, 6971, 6972, 6973, 6978, 6979, 6981,
+ 6992, 7002, 7009, 7019, 7028, 7040, 7042, 7043, 7073, 7074,
+ 7078, 7080, 7082, 7083, 7086, 7088, 7098, 7142, 7143, 7144,
+ 7146, 7149, 7150, 7151, 7154, 7164, 7168, 7204, 7212, 7220,
+ 7222, 7227, 7232, 7245, 7248, 7258, 7288, 7294, 7296, 7312,
+ 7357, 7360, 7376, 7379, 7380, 7393, 7394, 7401, 7405, 7406,
+ 7410, 7412, 7413, 7415, 7416, 7424, 7468, 7531, 7544, 7545,
+ 7579, 7616, 7675, 7680, 7830, 7838, 7936, 7944, 7952, 7960,
+ 7968, 7976, 7984, 7992, 8000, 8008, 8016, 8025, 8027, 8029,
+ 8031, 8033, 8040, 8048, 8064, 8072, 8080, 8088, 8096, 8104,
+ 8112, 8118, 8120, 8124, 8125, 8126, 8127, 8130, 8134, 8136,
+ 8140, 8141, 8144, 8150, 8152, 8157, 8160, 8168, 8173, 8178,
+ 8182, 8184, 8188, 8189, 8192, 8203, 8208, 8214, 8216, 8217,
+ 8218, 8219, 8221, 8222, 8223, 8224, 8232, 8233, 8234, 8239,
+ 8240, 8249, 8250, 8251, 8255, 8257, 8260, 8261, 8262, 8263,
+ 8274, 8275, 8276, 8277, 8287, 8288, 8294, 8304, 8305, 8308,
+ 8314, 8317, 8318, 8319, 8320, 8330, 8333, 8334, 8336, 8352,
+ 8400, 8413, 8417, 8418, 8421, 8448, 8450, 8451, 8455, 8456,
+ 8458, 8459, 8462, 8464, 8467, 8468, 8469, 8470, 8472, 8473,
+ 8478, 8484, 8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495,
+ 8496, 8500, 8501, 8505, 8506, 8508, 8510, 8512, 8517, 8519,
+ 8522, 8523, 8524, 8526, 8527, 8528, 8544, 8579, 8581, 8585,
+ 8586, 8592, 8597, 8602, 8604, 8608, 8609, 8611, 8612, 8614,
+ 8615, 8622, 8623, 8654, 8656, 8658, 8659, 8660, 8661, 8692,
+ 8960, 8968, 8969, 8970, 8971, 8972, 8992, 8994, 9001, 9002,
+ 9003, 9084, 9085, 9115, 9140, 9180, 9186, 9280, 9312, 9372,
+ 9450, 9472, 9655, 9656, 9665, 9666, 9720, 9728, 9839, 9840,
+ 10088, 10089, 10090, 10091, 10092, 10093, 10094, 10095, 10096, 10097,
+ 10098, 10099, 10100, 10101, 10102, 10132, 10176, 10181, 10182, 10183,
+ 10214, 10215, 10216, 10217, 10218, 10219, 10220, 10221, 10222, 10223,
+ 10224, 10240, 10496, 10627, 10628, 10629, 10630, 10631, 10632, 10633,
+ 10634, 10635, 10636, 10637, 10638, 10639, 10640, 10641, 10642, 10643,
+ 10644, 10645, 10646, 10647, 10648, 10649, 10712, 10713, 10714, 10715,
+ 10716, 10748, 10749, 10750, 11008, 11056, 11077, 11079, 11085, 11126,
+ 11160, 11210, 11264, 11312, 11360, 11363, 11365, 11367, 11374, 11377,
+ 11378, 11380, 11381, 11383, 11388, 11390, 11393, 11394, 11492, 11493,
+ 11499, 11503, 11506, 11513, 11517, 11518, 11520, 11559, 11565, 11568,
+ 11631, 11632, 11647, 11648, 11680, 11688, 11696, 11704, 11712, 11720,
+ 11728, 11736, 11744, 11776, 11778, 11779, 11780, 11781, 11782, 11785,
+ 11786, 11787, 11788, 11789, 11790, 11799, 11800, 11802, 11803, 11804,
+ 11805, 11806, 11808, 11809, 11810, 11811, 11812, 11813, 11814, 11815,
+ 11816, 11817, 11818, 11823, 11824, 11834, 11836, 11840, 11841, 11842,
+ 11843, 11904, 11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294,
+ 12295, 12296, 12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304,
+ 12305, 12306, 12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315,
+ 12316, 12317, 12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342,
+ 12344, 12347, 12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447,
+ 12448, 12449, 12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694,
+ 12704, 12736, 12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896,
+ 12928, 12938, 12977, 12992, 13056, 13312, 19893, 19904, 19968, 40943,
+ 40960, 40981, 40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509,
+ 42512, 42528, 42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622,
+ 42623, 42624, 42652, 42654, 42656, 42726, 42736, 42738, 42752, 42775,
+ 42784, 42786, 42800, 42802, 42864, 42865, 42873, 42878, 42888, 42889,
+ 42891, 42895, 42896, 42900, 42902, 42923, 42927, 42928, 42933, 42934,
+ 42999, 43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020,
+ 43043, 43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124,
+ 43136, 43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259,
+ 43260, 43261, 43263, 43264, 43274, 43302, 43310, 43312, 43335, 43346,
+ 43359, 43360, 43392, 43395, 43396, 43443, 43444, 43446, 43450, 43452,
+ 43453, 43457, 43471, 43472, 43486, 43488, 43493, 43494, 43495, 43504,
+ 43514, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588,
+ 43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643,
+ 43644, 43645, 43646, 43696, 43697, 43698, 43701, 43703, 43705, 43710,
+ 43712, 43713, 43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758,
+ 43760, 43762, 43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816,
+ 43824, 43867, 43868, 43872, 43888, 43968, 44003, 44005, 44006, 44008,
+ 44009, 44011, 44012, 44013, 44016, 44032, 55203, 55216, 55243, 55296,
+ 56191, 56319, 57343, 57344, 63743, 63744, 64112, 64256, 64275, 64285,
+ 64286, 64287, 64297, 64298, 64312, 64318, 64320, 64323, 64326, 64434,
+ 64467, 64830, 64831, 64848, 64914, 65008, 65020, 65021, 65024, 65040,
+ 65047, 65048, 65049, 65056, 65072, 65073, 65075, 65077, 65078, 65079,
+ 65080, 65081, 65082, 65083, 65084, 65085, 65086, 65087, 65088, 65089,
+ 65090, 65091, 65092, 65093, 65095, 65096, 65097, 65101, 65104, 65108,
+ 65112, 65113, 65114, 65115, 65116, 65117, 65118, 65119, 65122, 65123,
+ 65124, 65128, 65129, 65130, 65136, 65142, 65279, 65281, 65284, 65285,
+ 65288, 65289, 65290, 65291, 65292, 65293, 65294, 65296, 65306, 65308,
+ 65311, 65313, 65339, 65340, 65341, 65342, 65343, 65344, 65345, 65371,
+ 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65382,
+ 65392, 65393, 65438, 65440, 65474, 65482, 65490, 65498, 65504, 65506,
+ 65507, 65508, 65509, 65512, 65513, 65517, 65529, 65532, 0, 13,
+ 40, 60, 63, 80, 128, 256, 263, 311, 320, 373,
+ 377, 394, 396, 400, 416, 464, 509, 640, 672, 736,
+ 737, 768, 800, 813, 833, 834, 842, 848, 886, 896,
+ 927, 928, 968, 976, 977, 1024, 1064, 1104, 1184, 1200,
+ 1240, 1280, 1328, 1391, 1536, 1856, 1888, 2048, 2056, 2058,
+ 2103, 2108, 2111, 2135, 2136, 2144, 2167, 2169, 2176, 2215,
+ 2272, 2292, 2299, 2304, 2326, 2335, 2336, 2367, 2432, 2492,
+ 2494, 2496, 2514, 2560, 2561, 2565, 2572, 2576, 2581, 2585,
+ 2616, 2623, 2624, 2640, 2656, 2685, 2687, 2688, 2717, 2752,
+ 2760, 2761, 2789, 2795, 2800, 2816, 2873, 2880, 2904, 2912,
+ 2936, 2944, 2969, 2985, 3072, 3200, 3264, 3322, 3328, 3364,
+ 3376, 3680, 3840, 3869, 3879, 3888, 3910, 3921, 3925, 4096,
+ 4097, 4098, 4099, 4152, 4167, 4178, 4198, 4223, 4226, 4227,
+ 4272, 4275, 4279, 4281, 4283, 4285, 4286, 4301, 4304, 4336,
+ 4352, 4355, 4391, 4396, 4397, 4406, 4416, 4420, 4421, 4432,
+ 4467, 4468, 4470, 4480, 4482, 4483, 4531, 4534, 4543, 4545,
+ 4549, 4553, 4557, 4560, 4570, 4571, 4572, 4573, 4577, 4608,
+ 4627, 4652, 4655, 4658, 4660, 4661, 4662, 4664, 4670, 4736,
+ 4744, 4746, 4751, 4767, 4777, 4784, 4831, 4832, 4835, 4848,
+ 4864, 4866, 4869, 4879, 4883, 4906, 4914, 4917, 4923, 4925,
+ 4926, 4928, 4929, 4935, 4939, 4944, 4951, 4957, 4962, 4966,
+ 4976, 5120, 5173, 5176, 5184, 5186, 5189, 5190, 5191, 5195,
+ 5200, 5211, 5213, 5214, 5248, 5296, 5299, 5305, 5306, 5307,
+ 5311, 5313, 5314, 5316, 5318, 5319, 5328, 5504, 5551, 5554,
+ 5560, 5564, 5566, 5567, 5569, 5592, 5596, 5632, 5680, 5683,
+ 5691, 5693, 5694, 5695, 5697, 5700, 5712, 5728, 5760, 5803,
+ 5804, 5805, 5806, 5808, 5814, 5815, 5824, 5888, 5917, 5920,
+ 5922, 5926, 5927, 5936, 5946, 5948, 5951, 6144, 6188, 6191,
+ 6200, 6201, 6203, 6304, 6336, 6368, 6378, 6399, 6656, 6657,
+ 6667, 6707, 6713, 6714, 6715, 6719, 6727, 6736, 6737, 6743,
+ 6745, 6748, 6790, 6794, 6807, 6808, 6810, 6813, 6814, 6848,
+ 7168, 7178, 7215, 7216, 7224, 7230, 7231, 7232, 7233, 7248,
+ 7258, 7280, 7282, 7314, 7337, 7338, 7345, 7346, 7348, 7349,
+ 7424, 7432, 7435, 7473, 7482, 7484, 7487, 7494, 7495, 7504,
+ 7520, 7527, 7530, 7562, 7568, 7571, 7573, 7574, 7575, 7576,
+ 7584, 7904, 7923, 7925, 7927, 8192, 9216, 9328, 9344, 12288,
+ 17408, 26624, 27200, 27232, 27246, 27344, 27376, 27381, 27392, 27440,
+ 27447, 27452, 27456, 27460, 27461, 27472, 27483, 27491, 27517, 28224,
+ 28256, 28288, 28311, 28416, 28496, 28497, 28559, 28563, 28640, 28672,
+ 34801, 34816, 45056, 45424, 48128, 48240, 48256, 48272, 48284, 48285,
+ 48287, 48288, 53248, 53504, 53545, 53605, 53607, 53610, 53613, 53619,
+ 53627, 53635, 53637, 53644, 53674, 53678, 53760, 53826, 53829, 53984,
+ 54016, 54112, 54272, 54298, 54324, 54350, 54358, 54376, 54402, 54428,
+ 54430, 54434, 54437, 54441, 54446, 54454, 54459, 54461, 54469, 54480,
+ 54506, 54532, 54535, 54541, 54550, 54558, 54584, 54587, 54592, 54598,
+ 54602, 54610, 54636, 54662, 54688, 54714, 54740, 54766, 54792, 54818,
+ 54844, 54870, 54896, 54922, 54952, 54977, 54978, 55003, 55004, 55010,
+ 55035, 55036, 55061, 55062, 55068, 55093, 55094, 55119, 55120, 55126,
+ 55151, 55152, 55177, 55178, 55184, 55209, 55210, 55235, 55236, 55242,
+ 55246, 55296, 55808, 55863, 55867, 55917, 55925, 55926, 55940, 55941,
+ 55943, 55963, 55969, 57344, 57352, 57371, 57379, 57382, 59392, 59591,
+ 59600, 59648, 59682, 59716, 59728, 59742, 60529, 60588, 60589, 60592,
+ 60593, 60928, 60933, 60961, 60964, 60967, 60969, 60980, 60985, 60987,
+ 60994, 60999, 61001, 61003, 61005, 61009, 61012, 61015, 61017, 61019,
+ 61021, 61023, 61025, 61028, 61031, 61036, 61044, 61049, 61054, 61056,
+ 61067, 61089, 61093, 61099, 61168, 61440, 61488, 61600, 61617, 61633,
+ 61649, 61696, 61712, 61808, 61926, 61968, 62016, 62032, 62048, 62208,
+ 62459, 62464, 63200, 63216, 63232, 63360, 63488, 63504, 63568, 63584,
+ 63632, 63744, 63760, 63808, 63859, 63866, 63868, 63920, 63936, 63952,
+ 64096, 0, 42710, 42752, 46900, 46912, 47133, 47136, 52897, 52912,
+ 60384, 63488, 1, 32, 256, 0, 65533,
+ };
+static const u16 aFts5UnicodeData[] = {
+ 1025, 61, 117, 55, 117, 54, 50, 53, 57, 53,
+ 49, 85, 333, 85, 121, 85, 841, 54, 53, 50,
+ 56, 48, 56, 837, 54, 57, 50, 57, 1057, 61,
+ 53, 151, 58, 53, 56, 58, 39, 52, 57, 34,
+ 58, 56, 58, 57, 79, 56, 37, 85, 56, 47,
+ 39, 51, 111, 53, 745, 57, 233, 773, 57, 261,
+ 1822, 37, 542, 37, 1534, 222, 69, 73, 37, 126,
+ 126, 73, 69, 137, 37, 73, 37, 105, 101, 73,
+ 37, 73, 37, 190, 158, 37, 126, 126, 73, 37,
+ 126, 94, 37, 39, 94, 69, 135, 41, 40, 37,
+ 41, 40, 37, 41, 40, 37, 542, 37, 606, 37,
+ 41, 40, 37, 126, 73, 37, 1886, 197, 73, 37,
+ 73, 69, 126, 105, 37, 286, 2181, 39, 869, 582,
+ 152, 390, 472, 166, 248, 38, 56, 38, 568, 3596,
+ 158, 38, 56, 94, 38, 101, 53, 41, 88, 41,
+ 53, 105, 41, 73, 37, 553, 297, 1125, 94, 37,
+ 105, 101, 798, 133, 94, 57, 126, 94, 37, 1641,
+ 1541, 1118, 58, 172, 75, 1790, 478, 37, 3102, 1225,
+ 38, 213, 1317, 53, 49, 90, 55, 1452, 49, 44,
+ 53, 76, 53, 76, 53, 44, 871, 135, 85, 194,
+ 121, 85, 55, 85, 90, 364, 53, 34, 85, 1031,
+ 38, 327, 684, 333, 149, 71, 44, 3175, 53, 39,
+ 236, 34, 58, 204, 70, 76, 58, 140, 71, 333,
+ 103, 90, 39, 469, 34, 39, 44, 967, 876, 2855,
+ 364, 39, 333, 1063, 300, 70, 58, 117, 38, 44,
+ 87, 711, 140, 38, 300, 38, 108, 38, 172, 501,
+ 807, 108, 53, 359, 679, 263, 492, 34, 1036, 42,
+ 1735, 44, 42, 44, 39, 106, 268, 138, 44, 74,
+ 39, 236, 327, 76, 85, 333, 53, 38, 487, 44,
+ 74, 263, 71, 711, 231, 39, 135, 44, 39, 106,
+ 140, 74, 74, 44, 39, 42, 71, 103, 76, 333,
+ 71, 87, 207, 58, 55, 39, 53, 44, 76, 42,
+ 199, 71, 711, 231, 71, 71, 71, 44, 106, 76,
+ 76, 108, 44, 135, 39, 333, 76, 103, 44, 53,
+ 76, 42, 295, 103, 711, 231, 71, 167, 44, 39,
+ 106, 172, 76, 42, 74, 44, 39, 71, 76, 333,
+ 53, 55, 39, 204, 44, 74, 263, 71, 711, 231,
+ 71, 167, 44, 39, 42, 44, 42, 140, 74, 74,
+ 44, 44, 42, 71, 103, 76, 333, 58, 39, 207,
+ 44, 39, 199, 103, 135, 71, 39, 71, 71, 103,
+ 391, 74, 44, 74, 106, 106, 44, 39, 42, 333,
+ 111, 218, 55, 58, 44, 106, 44, 263, 103, 743,
+ 519, 39, 108, 138, 108, 140, 76, 103, 71, 76,
+ 333, 239, 58, 39, 44, 74, 53, 263, 103, 743,
+ 327, 167, 44, 39, 42, 44, 170, 44, 74, 74,
+ 76, 74, 39, 71, 76, 333, 71, 76, 74, 263,
+ 103, 1319, 76, 39, 106, 140, 106, 106, 44, 39,
+ 58, 103, 42, 239, 103, 76, 333, 303, 58, 199,
+ 74, 583, 775, 295, 39, 231, 44, 106, 108, 44,
+ 266, 333, 74, 53, 1543, 44, 71, 236, 55, 199,
+ 38, 268, 53, 333, 85, 71, 39, 71, 39, 39,
+ 135, 231, 103, 39, 39, 71, 135, 44, 71, 204,
+ 76, 39, 167, 38, 204, 333, 135, 39, 122, 501,
+ 58, 53, 122, 76, 218, 333, 335, 58, 44, 58,
+ 44, 58, 44, 54, 50, 54, 50, 74, 263, 1159,
+ 460, 42, 172, 53, 76, 167, 364, 1164, 282, 44,
+ 218, 90, 181, 154, 85, 1383, 74, 140, 42, 204,
+ 42, 76, 74, 76, 39, 333, 213, 199, 74, 76,
+ 135, 108, 39, 106, 71, 234, 103, 140, 423, 44,
+ 74, 76, 202, 44, 39, 42, 333, 106, 44, 90,
+ 1225, 41, 41, 1381, 53, 38, 101, 10535, 135, 231,
+ 39, 135, 1319, 135, 1063, 135, 231, 39, 135, 487,
+ 1831, 135, 2151, 108, 309, 655, 519, 346, 2761, 197,
+ 49, 19847, 85, 551, 61, 839, 54, 50, 2407, 117,
+ 110, 263, 423, 135, 108, 583, 108, 85, 583, 76,
+ 423, 103, 76, 1671, 76, 42, 236, 266, 44, 74,
+ 364, 117, 38, 117, 55, 39, 44, 333, 335, 213,
+ 49, 149, 108, 34, 333, 1127, 38, 1703, 167, 76,
+ 1095, 44, 39, 2247, 999, 108, 138, 76, 106, 74,
+ 44, 202, 108, 58, 85, 333, 967, 167, 1415, 839,
+ 333, 47, 1114, 743, 76, 74, 44, 85, 1703, 42,
+ 44, 42, 236, 44, 42, 44, 74, 268, 202, 332,
+ 44, 333, 333, 245, 38, 213, 460, 43, 140, 42,
+ 1511, 44, 42, 172, 42, 44, 170, 44, 74, 231,
+ 333, 245, 346, 300, 314, 76, 42, 967, 42, 140,
+ 74, 76, 42, 108, 71, 333, 1415, 44, 42, 76,
+ 106, 44, 42, 108, 74, 149, 1159, 266, 268, 74,
+ 76, 181, 333, 103, 333, 967, 198, 85, 293, 1385,
+ 105, 277, 108, 53, 428, 42, 236, 135, 44, 135,
+ 74, 44, 71, 42, 76, 1413, 2022, 421, 38, 1093,
+ 1190, 1868, 172, 4830, 261, 3166, 261, 265, 197, 201,
+ 261, 265, 261, 265, 197, 201, 261, 41, 41, 41,
+ 94, 229, 265, 453, 261, 264, 261, 264, 261, 264,
+ 165, 69, 137, 40, 56, 37, 120, 101, 69, 137,
+ 40, 120, 133, 69, 137, 120, 261, 169, 120, 101,
+ 69, 137, 40, 88, 381, 162, 209, 85, 52, 51,
+ 54, 84, 51, 54, 52, 277, 59, 60, 162, 61,
+ 309, 52, 51, 149, 80, 117, 57, 54, 50, 373,
+ 57, 53, 48, 341, 61, 162, 322, 47, 38, 207,
+ 121, 54, 50, 38, 335, 121, 54, 50, 422, 1047,
+ 428, 139, 44, 107, 396, 90, 41, 154, 41, 90,
+ 37, 105, 69, 105, 37, 58, 41, 90, 57, 169,
+ 218, 41, 58, 41, 58, 41, 58, 137, 58, 37,
+ 137, 37, 135, 37, 90, 69, 73, 185, 94, 101,
+ 58, 57, 90, 37, 58, 527, 1134, 94, 142, 47,
+ 90, 185, 186, 89, 154, 57, 90, 57, 90, 57,
+ 250, 57, 1018, 89, 90, 57, 58, 57, 1018, 8601,
+ 282, 54, 50, 54, 50, 666, 89, 250, 54, 50,
+ 2618, 57, 986, 825, 1306, 217, 2234, 378, 1935, 2522,
+ 719, 5882, 57, 314, 57, 1754, 281, 3578, 57, 7962,
+ 54, 50, 54, 50, 54, 50, 54, 50, 54, 50,
+ 54, 50, 54, 50, 975, 1434, 185, 54, 50, 1017,
+ 54, 50, 54, 50, 54, 50, 54, 50, 54, 50,
+ 537, 8218, 4217, 54, 50, 54, 50, 54, 50, 54,
+ 50, 54, 50, 54, 50, 54, 50, 54, 50, 54,
+ 50, 54, 50, 54, 50, 2041, 54, 50, 54, 50,
+ 1049, 54, 50, 8281, 1562, 697, 90, 217, 1274, 1050,
+ 1594, 1722, 1513, 1509, 126, 73, 69, 254, 105, 37,
+ 94, 37, 94, 165, 70, 105, 37, 3166, 37, 218,
+ 158, 108, 94, 149, 47, 85, 1221, 37, 37, 1799,
+ 38, 53, 44, 743, 231, 231, 231, 231, 231, 231,
+ 231, 231, 1036, 85, 52, 51, 52, 51, 117, 52,
+ 51, 53, 52, 51, 309, 49, 85, 49, 53, 52,
+ 51, 85, 52, 51, 54, 50, 54, 50, 54, 50,
+ 54, 50, 181, 38, 341, 81, 149, 49, 53, 54,
+ 405, 858, 2874, 6874, 410, 61, 117, 58, 38, 39,
+ 46, 54, 50, 54, 50, 54, 50, 54, 50, 54,
+ 50, 90, 54, 50, 54, 50, 54, 50, 54, 50,
+ 49, 54, 82, 58, 302, 140, 74, 49, 166, 90,
+ 110, 38, 39, 53, 90, 2759, 76, 88, 70, 39,
+ 49, 2887, 53, 102, 39, 1383, 3015, 90, 143, 346,
+ 871, 1178, 519, 1018, 335, 986, 271, 58, 495, 1050,
+ 335, 1274, 495, 2042, 8218, 39, 39, 2074, 39, 39,
+ 679, 38, 36583, 1786, 1287, 198, 85, 8583, 38, 117,
+ 519, 333, 71, 1502, 39, 44, 107, 53, 332, 53,
+ 38, 926, 70, 76, 2247, 334, 76, 213, 760, 294,
+ 88, 478, 69, 2014, 38, 261, 190, 350, 38, 88,
+ 158, 39, 158, 69, 702, 137, 37, 169, 37, 158,
+ 39, 70, 37, 231, 44, 103, 44, 135, 44, 743,
+ 74, 76, 42, 154, 207, 90, 55, 58, 1671, 149,
+ 74, 1607, 522, 76, 85, 333, 588, 199, 117, 39,
+ 53, 71, 44, 333, 903, 268, 85, 743, 364, 74,
+ 53, 935, 108, 42, 1511, 44, 74, 140, 74, 44,
+ 138, 437, 38, 333, 85, 167, 44, 38, 295, 333,
+ 167, 1319, 204, 74, 76, 74, 76, 103, 44, 263,
+ 44, 42, 333, 149, 519, 38, 199, 122, 39, 42,
+ 44, 42, 1607, 44, 39, 108, 71, 76, 167, 76,
+ 39, 44, 39, 71, 38, 85, 359, 42, 76, 74,
+ 85, 39, 70, 42, 44, 199, 199, 199, 231, 231,
+ 1381, 56, 134, 197, 2565, 1127, 74, 44, 74, 44,
+ 74, 53, 42, 44, 333, 39, 39, 743, 1575, 36,
+ 68, 68, 36, 63, 63, 11719, 3399, 229, 165, 39,
+ 44, 327, 57, 423, 167, 39, 71, 71, 3463, 536,
+ 11623, 50, 54, 2055, 1735, 391, 55, 58, 524, 245,
+ 54, 50, 53, 524, 53, 81, 80, 54, 50, 54,
+ 50, 54, 50, 54, 50, 54, 50, 54, 50, 54,
+ 50, 54, 50, 85, 54, 50, 149, 112, 117, 149,
+ 49, 54, 50, 54, 50, 54, 50, 117, 57, 49,
+ 121, 53, 55, 85, 167, 4327, 34, 117, 55, 117,
+ 54, 50, 53, 57, 53, 49, 85, 333, 85, 121,
+ 85, 841, 54, 53, 50, 56, 48, 56, 837, 54,
+ 57, 50, 57, 54, 50, 53, 54, 50, 85, 327,
+ 38, 1447, 70, 999, 199, 199, 199, 103, 87, 57,
+ 56, 58, 87, 58, 153, 90, 98, 90, 391, 839,
+ 615, 71, 487, 455, 3943, 117, 1455, 314, 1710, 143,
+ 570, 79, 122, 410, 58, 1466, 44, 935, 1575, 44,
+ 879, 1031, 143, 647, 46, 263, 46, 1223, 172, 967,
+ 53, 1159, 263, 53, 174, 1289, 1285, 2503, 333, 1161,
+ 1157, 1287, 1671, 53, 9959, 711, 263, 199, 39, 1415,
+ 71, 39, 743, 53, 271, 743, 90, 239, 999, 303,
+ 615, 71, 175, 711, 207, 53, 839, 53, 1799, 79,
+ 71, 527, 1487, 39, 108, 76, 140, 135, 103, 935,
+ 108, 44, 303, 309, 935, 79, 53, 935, 111, 263,
+ 58, 903, 76, 175, 245, 1735, 245, 711, 271, 615,
+ 271, 583, 149, 239, 2343, 1641, 1637, 207, 1159, 140,
+ 333, 1007, 935, 335, 39, 711, 364, 143, 181, 42,
+ 44, 42, 1703, 492, 245, 655, 333, 108, 42, 1447,
+ 106, 140, 74, 76, 85, 34, 149, 34, 807, 333,
+ 108, 1159, 172, 42, 268, 333, 149, 39, 74, 1127,
+ 44, 85, 39, 76, 42, 1543, 106, 300, 74, 135,
+ 149, 140, 53, 333, 39, 53, 39, 117, 655, 583,
+ 807, 106, 108, 74, 44, 42, 76, 213, 44, 231,
+ 39, 135, 487, 327, 53, 1511, 44, 106, 268, 333,
+ 76, 74, 263, 71, 711, 231, 71, 167, 76, 39,
+ 74, 44, 138, 74, 106, 39, 42, 167, 74, 236,
+ 172, 1703, 106, 268, 74, 108, 42, 44, 135, 181,
+ 333, 53, 53, 44, 1543, 106, 204, 42, 44, 138,
+ 76, 42, 76, 71, 53, 39, 333, 1511, 106, 140,
+ 138, 76, 42, 76, 757, 135, 76, 1543, 106, 268,
+ 74, 44, 42, 76, 117, 39, 333, 437, 1383, 44,
+ 42, 44, 74, 204, 42, 44, 333, 871, 108, 74,
+ 140, 42, 172, 333, 79, 117, 58, 1415, 106, 300,
+ 42, 76, 53, 1033, 1029, 333, 303, 39, 39, 332,
+ 1287, 204, 42, 39, 140, 277, 44, 39, 204, 74,
+ 108, 1287, 135, 428, 42, 76, 117, 39, 181, 1831,
+ 295, 1191, 42, 236, 204, 42, 44, 39, 181, 333,
+ 623, 85, 967, 716, 42, 236, 42, 76, 42, 76,
+ 231, 71, 1223, 204, 44, 76, 236, 39, 44, 333,
+ 199, 71, 1031, 170, 76, 74, 44, 42, 44, 39,
+ 333, 615, 76, 74, 85, 29511, 3566, 181, 6279, 34279,
+ 18663, 18215, 999, 333, 85, 967, 172, 53, 1543, 236,
+ 181, 154, 134, 53, 58, 333, 239, 679, 615, 1033,
+ 1029, 751, 149, 2215, 39, 1482, 140, 422, 70, 39,
+ 39, 24167, 9191, 12679, 3431, 423, 295, 327, 58, 76,
+ 53, 130, 7898, 1274, 1946, 74, 108, 122, 202, 258,
+ 268, 90, 236, 986, 140, 1914, 2138, 108, 58, 655,
+ 2810, 815, 841, 837, 841, 229, 581, 841, 837, 41,
+ 73, 41, 73, 137, 265, 133, 37, 229, 357, 841,
+ 837, 73, 137, 265, 233, 837, 73, 137, 169, 41,
+ 233, 837, 841, 837, 841, 837, 841, 837, 841, 837,
+ 841, 837, 841, 901, 809, 57, 805, 57, 197, 809,
+ 57, 805, 57, 197, 809, 57, 805, 57, 197, 809,
+ 57, 805, 57, 197, 809, 57, 805, 57, 197, 94,
+ 1613, 16410, 1772, 154, 1612, 282, 44, 474, 44, 90,
+ 181, 172, 492, 236, 556, 236, 76, 172, 6311, 303,
+ 236, 1097, 1093, 236, 333, 85, 1903, 58, 111, 55,
+ 143, 135, 871, 71, 39, 39, 327, 135, 39, 39,
+ 39, 39, 39, 39, 103, 71, 39, 39, 39, 39,
+ 39, 39, 71, 39, 135, 231, 135, 135, 39, 327,
+ 551, 103, 167, 551, 89, 1434, 3226, 506, 506, 506,
+ 1210, 431, 2970, 1978, 954, 1434, 314, 90, 218, 8058,
+ 184, 23226, 442, 346, 3738, 2874, 410, 1818, 346, 1306,
+ 986, 410, 1530, 1594, 154, 58, 1274, 346, 122, 1562,
+ 474, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 17351, 34, 3074, 7692, 63, 63,
+ };
+
+static int sqlite3Fts5UnicodeCategory(int iCode) {
+ int iRes = -1;
+ int iHi;
+ int iLo;
+ int ret;
+ u16 iKey;
+
+ if( iCode>=(1<<20) ){
+ return 0;
+ }
+ iLo = aFts5UnicodeBlock[(iCode>>16)];
+ iHi = aFts5UnicodeBlock[1+(iCode>>16)];
+ iKey = (iCode & 0xFFFF);
+ while( iHi>iLo ){
+ int iTest = (iHi + iLo) / 2;
+ assert( iTest>=iLo && iTest<iHi );
+ if( iKey>=aFts5UnicodeMap[iTest] ){
+ iRes = iTest;
+ iLo = iTest+1;
+ }else{
+ iHi = iTest;
+ }
+ }
+
+ if( iRes<0 ) return 0;
+ if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
+ ret = aFts5UnicodeData[iRes] & 0x1F;
+ if( ret!=30 ) return ret;
+ return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9;
+}
+
+static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
+ int i = 0;
+ int iTbl = 0;
+ while( i<128 ){
+ int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
+ int n = (aFts5UnicodeData[iTbl] >> 5) + i;
+ for(; i<128 && i<n; i++){
+ aAscii[i] = bToken;
+ }
+ iTbl++;
+ }
+}
+
+
/*
** 2015 May 30
**
@@ -205716,9 +219697,9 @@ SQLITE_API int sqlite3_extension_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=205719
+#if __LINE__!=219700
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de4alt2"
+#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b750alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.h b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.h
index 48d05ab..d761d6e 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3.h
+++ b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3.h
@@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.21.0"
-#define SQLITE_VERSION_NUMBER 3021000
-#define SQLITE_SOURCE_ID "2017-10-24 18:55:49 1a584e499906b5c87ec7d43d4abce641fdf017c42125b083109bc77c4de48827"
+#define SQLITE_VERSION "3.25.3"
+#define SQLITE_VERSION_NUMBER 3025003
+#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -470,6 +470,9 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
+#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@@ -502,17 +505,22 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
+#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
+#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
+#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -880,7 +888,8 @@ struct sqlite3_io_methods {
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
-** write ahead log and shared memory files used for transaction control
+** write ahead log ([WAL file]) and shared memory
+** files used for transaction control
** are automatically deleted when the latest connection to the database
** closes. Setting persistent WAL mode causes those files to persist after
** close. Persisting the files is useful when other processes that do not
@@ -1060,6 +1069,32 @@ struct sqlite3_io_methods {
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
+** a file lock using the xLock or xShmLock methods of the VFS to wait
+** for up to M milliseconds before failing, where M is the single
+** unsigned integer parameter.
+**
+** <li>[[SQLITE_FCNTL_DATA_VERSION]]
+** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
+** a database file. The argument is a pointer to a 32-bit unsigned integer.
+** The "data version" for the pager is written into the pointer. The
+** "data version" changes whenever any change occurs to the corresponding
+** database file, either through SQL statements on the same database
+** connection or through transactions committed by separate database
+** connections possibly in other processes. The [sqlite3_total_changes()]
+** interface can be used to find if any database on the connection has changed,
+** but that interface responds to changes on TEMP as well as MAIN and does
+** not provide a mechanism to detect changes to MAIN only. Also, the
+** [sqlite3_total_changes()] interface responds to internal changes only and
+** omits changes made by other database connections. The
+** [PRAGMA data_version] command provide a mechanism to detect changes to
+** a single attached database that occur due to other database connections,
+** but omits changes implemented by the database connection on which it is
+** called. This file control is the only mechanism to detect changes that
+** happen either internally or externally and that are associated with
+** a particular attached database.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -1094,6 +1129,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
+#define SQLITE_FCNTL_LOCK_TIMEOUT 34
+#define SQLITE_FCNTL_DATA_VERSION 35
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1131,12 +1168,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
+** Note that the structure
+** of the sqlite3_vfs object changes in the transition from
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@@ -1810,6 +1853,22 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** I/O required to support statement rollback.
** The default value for this setting is controlled by the
** [SQLITE_STMTJRNL_SPILL] compile-time option.
+**
+** [[SQLITE_CONFIG_SORTERREF_SIZE]]
+** <dt>SQLITE_CONFIG_SORTERREF_SIZE
+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
+** of type (int) - the new value of the sorter-reference size threshold.
+** Usually, when SQLite uses an external sort to order records according
+** to an ORDER BY clause, all fields required by the caller are present in the
+** sorted records. However, if SQLite determines based on the declared type
+** of a table column that its values are likely to be very large - larger
+** than the configured sorter-reference size threshold - then a reference
+** is stored in each sorted record and the required column values loaded
+** from the database as records are returned in sorted order. The default
+** value for this option is to never use this optimization. Specifying a
+** negative value for this option restores the default behaviour.
+** This option is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -1837,6 +1896,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
+#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -1939,8 +1999,9 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
** override this behaviour. The first parameter passed to this operation
-** is an integer - non-zero to disable checkpoints-on-close, or zero (the
-** default) to enable them. The second parameter is a pointer to an integer
+** is an integer - positive to disable checkpoints-on-close, or zero (the
+** default) to enable them, and 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 checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
** </dd>
@@ -1954,8 +2015,45 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** slower. But the QPSG has the advantage of more predictable behavior. With
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
+** The first argument to this setting is an integer which is 0 to disable
+** the QPSG, positive to enable QPSG, 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 the QPSG is disabled or enabled
+** following this call.
+** </dd>
+**
+** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
+** positive to enable output for trigger programs, or zero to disable it,
+** 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 output-for-triggers has been disabled - 0 if
+** it is not disabled, 1 if it is.
** </dd>
**
+** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
+** [VACUUM] in order to reset a database back to an empty database
+** with no schema and no content. The following process works even for
+** a badly corrupted database file:
+** <ol>
+** <li> If the database connection is newly opened, make sure it has read the
+** database schema by preparing then discarding some query against the
+** database, or calling sqlite3_table_column_metadata(), ignoring any
+** errors. This step is only necessary if the application desires to keep
+** the database in WAL mode after the reset if it was in WAL mode before
+** the reset.
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
+** </ol>
+** Because resetting a database is destructive and irreversible, the
+** process requires the use of this obscure API and multiple steps to help
+** ensure that it does not happen by accident.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -1966,7 +2064,9 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -2094,12 +2194,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** program, the value returned reflects the number of rows modified by the
** previous INSERT, UPDATE or DELETE statement within the same trigger.
**
-** See also the [sqlite3_total_changes()] interface, the
-** [count_changes pragma], and the [changes() SQL function].
-**
** If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_total_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** </ul>
*/
SQLITE_API sqlite3_uint64 sqlite3_changes(sqlite3*);
#define sqlite3_changes(db) ((int)(sqlite3_changes)(db))
@@ -2119,13 +2224,26 @@ SQLITE_API sqlite3_uint64 sqlite3_changes(sqlite3*);
** count, but those made as part of REPLACE constraint resolution are
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
** are not counted.
-**
-** See also the [sqlite3_changes()] interface, the
-** [count_changes pragma], and the [total_changes() SQL function].
**
+** This the [sqlite3_total_changes(D)] interface only reports the number
+** of rows that changed due to SQL statement run against database
+** connection D. Any changes by other database connections are ignored.
+** To detect changes against a database file from other database
+** connections use the [PRAGMA data_version] command or the
+** [SQLITE_FCNTL_DATA_VERSION] [file control].
+**
** If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
+**
+** See also:
+** <ul>
+** <li> the [sqlite3_changes()] interface
+** <li> the [count_changes pragma]
+** <li> the [changes() SQL function]
+** <li> the [data_version pragma]
+** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
+** </ul>
*/
SQLITE_API sqlite3_uint64 sqlite3_total_changes(sqlite3*);
#define sqlite3_total_changes(db) ((int)(sqlite3_total_changes)(db))
@@ -2376,16 +2494,16 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
-** These routines understand most of the common K&R formatting options,
-** plus some additional non-standard formats, detailed below.
-** Note that some of the more obscure formatting options from recent
-** C-library standards are omitted from this implementation.
+** These routines understand most of the common formatting options from
+** the standard library printf()
+** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
+** See the [built-in printf()] documentation for details.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
+** results into memory obtained from [sqlite3_malloc64()].
** The strings returned by these two routines should be
** released by [sqlite3_free()]. ^Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
@@ -2409,71 +2527,7 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** All of the usual printf() formatting options apply. In addition, there
-** is are "%q", "%Q", "%w" and "%z" options.
-**
-** ^(The %q option works like %s in that it substitutes a nul-terminated
-** string from the argument list. But %q also doubles every '\'' character.
-** %q is designed for use inside a string literal.)^ By doubling each '\''
-** character it escapes that character and allows it to be inserted into
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** ^(The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes).)^ So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** ^(The "%w" formatting option is like "%q" except that it expects to
-** be contained within double-quotes instead of single quotes, and it
-** escapes the double-quote character instead of the single-quote
-** character.)^ The "%w" formatting option is intended for safely inserting
-** table and column names into a constructed SQL statement.
-**
-** ^(The "%z" formatting option works like "%s" but with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string.)^
+** See also: [built-in printf()], [printf() SQL function]
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
@@ -2831,8 +2885,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The third argument
-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@@ -3247,13 +3301,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
** [database connection] D failed, then the sqlite3_errcode(D) interface
** returns the numeric [result code] or [extended result code] for that
** API call.
-** If the most recent API call was successful,
-** then the return value from sqlite3_errcode() is undefined.
** ^The sqlite3_extended_errcode()
** interface is the same except that it always returns the
** [extended result code] even when extended result codes are
** disabled.
**
+** The values returned by sqlite3_errcode() and/or
+** sqlite3_extended_errcode() might change with each API call.
+** Except, there are some interfaces that are guaranteed to never
+** change the value of the error code. The error-code preserving
+** interfaces are:
+**
+** <ul>
+** <li> sqlite3_errcode()
+** <li> sqlite3_extended_errcode()
+** <li> sqlite3_errmsg()
+** <li> sqlite3_errmsg16()
+** </ul>
+**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
** text that describes the error, as either UTF-8 or UTF-16 respectively.
** ^(Memory to hold the error message string is managed internally.
@@ -3539,13 +3604,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** </li>
+** </ol>
**
** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
** the extra prepFlags parameter, which is a bit array consisting of zero or
** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
** sqlite3_prepare_v2() interface works exactly the same as
** sqlite3_prepare_v3() with a zero prepFlags parameter.
-** </ol>
*/
SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
@@ -4407,11 +4472,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
-** ^(If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].)^
+** As long as the input parameters are correct, these routines will only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_column_blob()
+** <li> sqlite3_column_text()
+** <li> sqlite3_column_text16()
+** <li> sqlite3_column_bytes()
+** <li> sqlite3_column_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
*/
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
@@ -4488,11 +4567,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^These functions (collectively known as "function creation routines")
** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only differences between
-** these routines are the text encoding expected for
-** the second parameter (the name of the function being created)
-** and the presence or absence of a destructor callback for
-** the application data pointer.
+** of existing SQL functions or aggregates. The only differences between
+** the three "sqlite3_create_function*" routines are the text encoding
+** expected for the second parameter (the name of the function being
+** created) and the presence or absence of a destructor callback for
+** the application data pointer. Function sqlite3_create_window_function()
+** is similar, but allows the user to supply the extra callback functions
+** needed by [aggregate window functions].
**
** ^The first parameter is the [database connection] to which the SQL
** function is to be added. ^If an application uses more than one database
@@ -4538,7 +4619,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
**
-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
+** ^The sixth, seventh and eighth parameters passed to the three
+** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
** pointers to C-language functions that implement the SQL function or
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
** callback only; NULL pointers must be passed as the xStep and xFinal
@@ -4547,15 +4629,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** SQL function or aggregate, pass NULL pointers for all three function
** callbacks.
**
-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
-** then it is destructor for the application data pointer.
-** The destructor is invoked when the function is deleted, either by being
-** overloaded or when the database connection closes.)^
-** ^The destructor is also invoked if the call to
-** sqlite3_create_function_v2() fails.
-** ^When the destructor callback of the tenth parameter is invoked, it
-** is passed a single argument which is a copy of the application data
-** pointer which was the fifth parameter to sqlite3_create_function_v2().
+** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue
+** and xInverse) passed to sqlite3_create_window_function are pointers to
+** C-language callbacks that implement the new function. xStep and xFinal
+** must both be non-NULL. xValue and xInverse may either both be NULL, in
+** which case a regular aggregate function is created, or must both be
+** non-NULL, in which case the new function may be used as either an aggregate
+** or aggregate window function. More details regarding the implementation
+** of aggregate window functions are
+** [user-defined window functions|available here].
+**
+** ^(If the final parameter to sqlite3_create_function_v2() or
+** sqlite3_create_window_function() is not NULL, then it is destructor for
+** the application data pointer. The destructor is invoked when the function
+** is deleted, either by being overloaded or when the database connection
+** closes.)^ ^The destructor is also invoked if the call to
+** sqlite3_create_function_v2() fails. ^When the destructor callback is
+** invoked, it is passed a single argument which is a copy of the application
+** data pointer which was the fifth parameter to sqlite3_create_function_v2().
**
** ^It is permitted to register multiple implementations of the same
** functions with the same name but with either differing numbers of
@@ -4610,6 +4701,18 @@ SQLITE_API int sqlite3_create_function_v2(
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*)
);
+SQLITE_API int sqlite3_create_window_function(
+ sqlite3 *db,
+ const char *zFunctionName,
+ int nArg,
+ int eTextRep,
+ void *pApp,
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
+ void(*xDestroy)(void*)
+);
/*
** CAPI3REF: Text Encodings
@@ -4680,6 +4783,9 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@@ -4728,6 +4834,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -4736,6 +4855,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
**
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
+**
+** As long as the input parameter is correct, these routines can only
+** fail if an out-of-memory error occurs during a format conversion.
+** Only the following subset of interfaces are subject to out-of-memory
+** errors:
+**
+** <ul>
+** <li> sqlite3_value_blob()
+** <li> sqlite3_value_text()
+** <li> sqlite3_value_text16()
+** <li> sqlite3_value_text16le()
+** <li> sqlite3_value_text16be()
+** <li> sqlite3_value_bytes()
+** <li> sqlite3_value_bytes16()
+** </ul>
+**
+** If an out-of-memory error occurs, then the return value from these
+** routines is the same as if the column had contained an SQL NULL value.
+** Valid SQL NULL returns can be distinguished from out-of-memory errors
+** by invoking the [sqlite3_errcode()] immediately after the suspect
+** return value is obtained and before any
+** other SQLite interface is called on the same [database connection].
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API double sqlite3_value_double(sqlite3_value*);
@@ -4750,6 +4891,7 @@ SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -5419,6 +5561,41 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
+** CAPI3REF: Win32 Specific Interface
+**
+** These interfaces are available only on Windows. The
+** [sqlite3_win32_set_directory] interface is used to set the value associated
+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
+** zValue, depending on the value of the type parameter. The zValue parameter
+** should be NULL to cause the previous value to be freed via [sqlite3_free];
+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
+** prior to being used. The [sqlite3_win32_set_directory] interface returns
+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
+** or [SQLITE_NOMEM] if memory could not be allocated. The value of the
+** [sqlite3_data_directory] variable is intended to act as a replacement for
+** the current directory on the sub-platforms of Win32 where that concept is
+** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and
+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
+** sqlite3_win32_set_directory interface except the string parameter must be
+** UTF-8 or UTF-16, respectively.
+*/
+SQLITE_API int sqlite3_win32_set_directory(
+ unsigned long type, /* Identifier for directory being set or reset */
+ void *zValue /* New value for directory being set or reset */
+);
+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
+
+/*
+** CAPI3REF: Win32 Directory Types
+**
+** These macros are only available on Windows. They define the allowed values
+** for the type argument to the [sqlite3_win32_set_directory] interface.
+*/
+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1
+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2
+
+/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
** METHOD: sqlite3
@@ -6151,6 +6328,10 @@ struct sqlite3_index_info {
/*
** CAPI3REF: Virtual Table Scan Flags
+**
+** Virtual table implementations are allowed to set the
+** [sqlite3_index_info].idxFlags field to some combination of
+** these bits.
*/
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
@@ -6176,6 +6357,7 @@ struct sqlite3_index_info {
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
#define SQLITE_INDEX_CONSTRAINT_IS 72
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -6854,6 +7036,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
** METHOD: sqlite3
+** KEYWORDS: {file control}
**
** ^The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6868,11 +7051,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** the xFileControl method. ^The return value of the xFileControl
** method becomes the return value of this routine.
**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
+** A few opcodes for [sqlite3_file_control()] are handled directly
+** by the SQLite core and never invoke the
+** sqlite3_io_methods.xFileControl method.
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
-** case is a short-circuit path which does not actually invoke the
-** underlying sqlite3_io_methods.xFileControl method.
+** the space pointed to by the 4th parameter. The
+** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
+** the [sqlite3_file] object associated with the journal file instead of
+** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns
+** a pointer to the underlying [sqlite3_vfs] object for the file.
+** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
+** from the pager.
**
** ^If the second parameter (zDbName) does not match the name of any
** open database file, then SQLITE_ERROR is returned. ^This error
@@ -6882,7 +7072,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
+** See also: [file control opcodes]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
@@ -6928,7 +7118,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
-#define SQLITE_TESTCTRL_ISKEYWORD 16
+#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
@@ -6939,7 +7129,191 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_LAST 25
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
+
+/*
+** CAPI3REF: SQL Keyword Checking
+**
+** These routines provide access to the set of SQL language keywords
+** recognized by SQLite. Applications can uses these routines to determine
+** whether or not a specific identifier needs to be escaped (for example,
+** by enclosing in double-quotes) so as not to confuse the parser.
+**
+** The sqlite3_keyword_count() interface returns the number of distinct
+** keywords understood by SQLite.
+**
+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** makes *Z point to that keyword expressed as UTF8 and writes the number
+** of bytes in the keyword into *L. The string that *Z points to is not
+** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
+** or L are NULL or invalid pointers then calls to
+** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
+**
+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
+** if it is and zero if not.
+**
+** The parser used by SQLite is forgiving. It is often possible to use
+** a keyword as an identifier as long as such use does not result in a
+** parsing ambiguity. For example, the statement
+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
+** creates a new table named "BEGIN" with three columns named
+** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid
+** using keywords as identifiers. Common techniques used to avoid keyword
+** name collisions include:
+** <ul>
+** <li> Put all identifier names inside double-quotes. This is the official
+** SQL way to escape identifier names.
+** <li> Put identifier names inside &#91;...&#93;. This is not standard SQL,
+** but it is what SQL Server does and so lots of programmers use this
+** technique.
+** <li> Begin every identifier with the letter "Z" as no SQL keywords start
+** with "Z".
+** <li> Include a digit somewhere in every identifier name.
+** </ul>
+**
+** Note that the number of keywords understood by SQLite can depend on
+** compile-time options. For example, "VACUUM" is not a keyword if
+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also,
+** new keywords may be added to future releases of SQLite.
+*/
+SQLITE_API int sqlite3_keyword_count(void);
+SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
+SQLITE_API int sqlite3_keyword_check(const char*,int);
+
+/*
+** CAPI3REF: Dynamic String Object
+** KEYWORDS: {dynamic string}
+**
+** An instance of the sqlite3_str object contains a dynamically-sized
+** string under construction.
+**
+** The lifecycle of an sqlite3_str object is as follows:
+** <ol>
+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
+** <li> ^Text is appended to the sqlite3_str object using various
+** methods, such as [sqlite3_str_appendf()].
+** <li> ^The sqlite3_str object is destroyed and the string it created
+** is returned using the [sqlite3_str_finish()] interface.
+** </ol>
+*/
+typedef struct sqlite3_str sqlite3_str;
+
+/*
+** CAPI3REF: Create A New Dynamic String Object
+** CONSTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_new(D)] interface allocates and initializes
+** a new [sqlite3_str] object. To avoid memory leaks, the object returned by
+** [sqlite3_str_new()] must be freed by a subsequent call to
+** [sqlite3_str_finish(X)].
+**
+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
+** valid [sqlite3_str] object, though in the event of an out-of-memory
+** error the returned object might be a special singleton that will
+** silently reject new text, always return SQLITE_NOMEM from
+** [sqlite3_str_errcode()], always return 0 for
+** [sqlite3_str_length()], and always return NULL from
+** [sqlite3_str_finish(X)]. It is always safe to use the value
+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
+** to any of the other [sqlite3_str] methods.
+**
+** The D parameter to [sqlite3_str_new(D)] may be NULL. If the
+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
+** length of the string contained in the [sqlite3_str] object will be
+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
+** of [SQLITE_MAX_LENGTH].
+*/
+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
+
+/*
+** CAPI3REF: Finalize A Dynamic String
+** DESTRUCTOR: sqlite3_str
+**
+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
+** that contains the constructed string. The calling application should
+** pass the returned value to [sqlite3_free()] to avoid a memory leak.
+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
+** errors were encountered during construction of the string. ^The
+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
+** string in [sqlite3_str] object X is zero bytes long.
+*/
+SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
+
+/*
+** CAPI3REF: Add Content To A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces add content to an sqlite3_str object previously obtained
+** from [sqlite3_str_new()].
+**
+** ^The [sqlite3_str_appendf(X,F,...)] and
+** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
+** functionality of SQLite to append formatted text onto the end of
+** [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
+** onto the end of the [sqlite3_str] object X. N must be non-negative.
+** S must contain at least N non-zero bytes of content. To append a
+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
+** method instead.
+**
+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
+** zero-terminated string S onto the end of [sqlite3_str] object X.
+**
+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
+** single-byte character C onto the end of [sqlite3_str] object X.
+** ^This method can be used, for example, to add whitespace indentation.
+**
+** ^The [sqlite3_str_reset(X)] method resets the string under construction
+** inside [sqlite3_str] object X back to zero bytes in length.
+**
+** These methods do not return a result code. ^If an error occurs, that fact
+** is recorded in the [sqlite3_str] object and can be recovered by a
+** subsequent call to [sqlite3_str_errcode(X)].
+*/
+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
+SQLITE_API void sqlite3_str_reset(sqlite3_str*);
+
+/*
+** CAPI3REF: Status Of A Dynamic String
+** METHOD: sqlite3_str
+**
+** These interfaces return the current status of an [sqlite3_str] object.
+**
+** ^If any prior errors have occurred while constructing the dynamic string
+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
+** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns
+** [SQLITE_NOMEM] following any out-of-memory error, or
+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
+**
+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
+** of the dynamic string under construction in [sqlite3_str] object X.
+** ^The length returned by [sqlite3_str_length(X)] does not include the
+** zero-termination byte.
+**
+** ^The [sqlite3_str_value(X)] method returns a pointer to the current
+** content of the dynamic string under construction in X. The value
+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
+** and might be freed or altered by any subsequent method on the same
+** [sqlite3_str] object. Applications must not used the pointer returned
+** [sqlite3_str_value(X)] after any subsequent method call on the same
+** object. ^Applications may change the content of the string returned
+** by [sqlite3_str_value(X)] as long as they do not write into any bytes
+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
+** write any byte after any subsequent sqlite3_str method call.
+*/
+SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
+SQLITE_API int sqlite3_str_length(sqlite3_str*);
+SQLITE_API char *sqlite3_str_value(sqlite3_str*);
/*
** CAPI3REF: SQLite Runtime Status
@@ -7174,6 +7548,15 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
+** <dd>This parameter returns the number of dirty cache entries that have
+** been written to disk in the middle of a transaction due to the page
+** cache overflowing. Transactions are more efficient if they are written
+** to disk all at once. When pages spill mid-transaction, that introduces
+** additional overhead. This parameter can be used help identify
+** inefficiencies that can be resolve by increasing the cache size.
+** </dd>
+**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
@@ -7193,7 +7576,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
-#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_CACHE_SPILL 12
+#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
/*
@@ -8196,6 +8580,40 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** method of a [virtual table], then it returns true if and only if the
+** column is being fetched as part of an UPDATE operation during which the
+** column value will not change. Applications might use this to substitute
+** a return value that is less expensive to compute and that the corresponding
+** [xUpdate] method understands as a "no-change" value.
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+** the column is not changed by the UPDATE statement, then the xColumn
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
+** method of a [virtual table].
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
+** structure passed to xBestIndex. This function returns a pointer to a buffer
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -8465,7 +8883,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
/*
** CAPI3REF: Database Snapshot
** KEYWORDS: {snapshot} {sqlite3_snapshot}
-** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
** database for some specific point in history.
@@ -8482,11 +8899,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
** version of the database file so that it is possible to later open a new read
** transaction that sees that historical version of the database rather than
** the most recent version.
-**
-** The constructor for this object is [sqlite3_snapshot_get()]. The
-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
-** to an historical snapshot (if possible). The destructor for
-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
typedef struct sqlite3_snapshot {
unsigned char hidden[48];
@@ -8494,7 +8906,7 @@ typedef struct sqlite3_snapshot {
/*
** CAPI3REF: Record A Database Snapshot
-** EXPERIMENTAL
+** CONSTRUCTOR: sqlite3_snapshot
**
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
** new [sqlite3_snapshot] object that records the current state of
@@ -8510,7 +8922,7 @@ typedef struct sqlite3_snapshot {
** in this case.
**
** <ul>
-** <li> The database handle must be in [autocommit mode].
+** <li> The database handle must not be in [autocommit mode].
**
** <li> Schema S of [database connection] D must be a [WAL mode] database.
**
@@ -8533,7 +8945,7 @@ typedef struct sqlite3_snapshot {
** to avoid a memory leak.
**
** The [sqlite3_snapshot_get()] interface is only available when the
-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
sqlite3 *db,
@@ -8543,24 +8955,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
/*
** CAPI3REF: Start a read transaction on an historical snapshot
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
+**
+** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
+** transaction or upgrades an existing one 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, the database connection must not be in
+** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
+** is already a read transaction open on schema S, then the database handle
+** must have no active statements (SELECT statements that have been passed
+** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()).
+** SQLITE_ERROR is returned if either of these conditions is violated, or
+** if schema S does not exist, or if the snapshot object is invalid.
+**
+** ^A call to sqlite3_snapshot_open() will fail to open if the specified
+** snapshot has been overwritten by a [checkpoint]. In this case
+** SQLITE_ERROR_SNAPSHOT is returned.
+**
+** If there is already a read transaction open when this function is
+** invoked, then the same read transaction remains open (on the same
+** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
+** is returned. If another error code - for example SQLITE_PROTOCOL or an
+** SQLITE_IOERR error code - is returned, then the final state of the
+** read transaction is undefined. If SQLITE_OK is returned, then the
+** read transaction is now open on database 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 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
@@ -8571,7 +8994,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** 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.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
sqlite3 *db,
@@ -8581,20 +9004,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
/*
** CAPI3REF: Destroy a snapshot
-** EXPERIMENTAL
+** DESTRUCTOR: sqlite3_snapshot
**
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
** The application must eventually free every [sqlite3_snapshot] object
** using this routine to avoid a memory leak.
**
** The [sqlite3_snapshot_free()] interface is only available when the
-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
+** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** CAPI3REF: Compare the ages of two snapshot handles.
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
**
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
** of two valid snapshot handles.
@@ -8613,6 +9036,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
** 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.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
sqlite3_snapshot *p1,
@@ -8621,27 +9047,152 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
/*
** CAPI3REF: Recover snapshots from a wal file
-** EXPERIMENTAL
+** METHOD: sqlite3_snapshot
**
-** If all connections disconnect from a database file but do not perform
-** a checkpoint, the existing wal file is opened along with the database
-** file the next time the database is opened. At this point it is only
-** possible to successfully call sqlite3_snapshot_open() to open the most
-** recent snapshot of the database (the one at the head of the wal file),
-** even though the wal file may contain other valid snapshots for which
-** clients have sqlite3_snapshot handles.
+** If a [WAL file] remains on disk after all database connections close
+** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
+** or because the last process to have the database opened exited without
+** calling [sqlite3_close()]) and a new connection is subsequently opened
+** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
+** will only be able to open the last transaction added to the WAL file
+** even though the WAL file contains other valid transactions.
**
-** This function attempts to scan the wal file associated with database zDb
+** This function attempts to scan the WAL file associated with database zDb
** of database handle db and make all valid snapshots available to
** sqlite3_snapshot_open(). It is an error if there is already a read
-** transaction open on the database, or if the database is not a wal mode
+** transaction open on the database, or if the database is not a WAL mode
** database.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_SNAPSHOT] option.
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
/*
+** CAPI3REF: Serialize a database
+**
+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
+** that is a serialization of the S database on [database connection] D.
+** If P is not a NULL pointer, then the size of the database in bytes
+** is written into *P.
+**
+** For an ordinary on-disk database file, the serialization is just a
+** copy of the disk file. For an in-memory database or a "TEMP" database,
+** the serialization is the same sequence of bytes which would be written
+** to disk if that database where backed up to disk.
+**
+** The usual case is that sqlite3_serialize() copies the serialization of
+** the database into memory obtained from [sqlite3_malloc64()] and returns
+** a pointer to that memory. The caller is responsible for freeing the
+** returned value to avoid a memory leak. However, if the F argument
+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
+** are made, and the sqlite3_serialize() function will return a pointer
+** to the contiguous memory representation of the database that SQLite
+** is currently using for that database, or NULL if the no such contiguous
+** memory representation of the database exists. A contiguous memory
+** representation of the database will usually only exist if there has
+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+** values of D and S.
+** The size of the database is written into *P even if the
+** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+** of the database exists.
+**
+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
+** allocation error occurs.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API unsigned char *sqlite3_serialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
+ sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
+ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_serialize
+**
+** Zero or more of the following constants can be OR-ed together for
+** the F argument to [sqlite3_serialize(D,S,P,F)].
+**
+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
+** a pointer to contiguous in-memory database that it is currently using,
+** without making a copy of the database. If SQLite is not currently using
+** a contiguous in-memory database, then this option causes
+** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be
+** using a contiguous in-memory database if it has been initialized by a
+** prior call to [sqlite3_deserialize()].
+*/
+#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
+
+/*
+** CAPI3REF: Deserialize a database
+**
+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
+** [database connection] D to disconnect from database S and then
+** reopen S as an in-memory database based on the serialization contained
+** in P. The serialized database P is N bytes in size. M is the size of
+** the buffer P, which might be larger than N. If M is larger than N, and
+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
+** permitted to add content to the in-memory database as long as the total
+** size does not exceed M bytes.
+**
+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
+** invoke sqlite3_free() on the serialization buffer when the database
+** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
+** SQLite will try to increase the buffer size using sqlite3_realloc64()
+** if writes on the database cause it to grow larger than M bytes.
+**
+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
+** database is currently in a read transaction or is involved in a backup
+** operation.
+**
+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
+** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
+** [sqlite3_free()] is invoked on argument P prior to returning.
+**
+** This interface is only available if SQLite is compiled with the
+** [SQLITE_ENABLE_DESERIALIZE] option.
+*/
+SQLITE_API int sqlite3_deserialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to reopen with the deserialization */
+ unsigned char *pData, /* The serialized database content */
+ sqlite3_int64 szDb, /* Number bytes in the deserialization */
+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */
+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3_deserialize()
+**
+** The following are allowed values for 6th argument (the F argument) to
+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
+**
+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
+** in the P argument is held in memory obtained from [sqlite3_malloc64()]
+** and that SQLite should take ownership of this memory and automatically
+** free it when it has finished using it. Without this flag, the caller
+** is responsible for freeing any dynamically allocated memory.
+**
+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
+** grow the size of the database using calls to [sqlite3_realloc64()]. This
+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
+** Without this flag, the deserialized database cannot increase in size beyond
+** the number of bytes specified by the M parameter.
+**
+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
+** should be treated as read-only.
+*/
+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
+#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
+#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
+
+/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
@@ -8788,16 +9339,23 @@ extern "C" {
/*
** CAPI3REF: Session Object Handle
+**
+** An instance of this object is a [session] that can be used to
+** record changes to a database.
*/
typedef struct sqlite3_session sqlite3_session;
/*
** CAPI3REF: Changeset Iterator Handle
+**
+** An instance of this object acts as a cursor for iterating
+** over the elements of a [changeset] or [patchset].
*/
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
/*
** CAPI3REF: Create A New Session Object
+** CONSTRUCTOR: sqlite3_session
**
** 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
@@ -8834,6 +9392,7 @@ SQLITE_API int sqlite3session_create(
/*
** CAPI3REF: Delete A Session Object
+** DESTRUCTOR: sqlite3_session
**
** Delete a session object previously allocated using
** [sqlite3session_create()]. Once a session object has been deleted, the
@@ -8849,6 +9408,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
/*
** CAPI3REF: Enable Or Disable A Session Object
+** METHOD: sqlite3_session
**
** Enable or disable the recording of changes by a session object. When
** enabled, a session object records changes made to the database. When
@@ -8868,6 +9428,7 @@ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
+** METHOD: sqlite3_session
**
** Each change recorded by a session object is marked as either direct or
** indirect. A change is marked as indirect if either:
@@ -8897,6 +9458,7 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
/*
** CAPI3REF: Attach A Table To A Session Object
+** METHOD: sqlite3_session
**
** 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
@@ -8922,6 +9484,35 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
**
** 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.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
+** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
+** </pre>
+**
+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
+** The sqlite3changeset_apply() function automatically converts the
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
*/
SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@@ -8930,6 +9521,7 @@ SQLITE_API int sqlite3session_attach(
/*
** CAPI3REF: Set a table filter on a Session Object.
+** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
@@ -8948,6 +9540,7 @@ SQLITE_API void sqlite3session_table_filter(
/*
** CAPI3REF: Generate A Changeset From A Session Object
+** METHOD: sqlite3_session
**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
@@ -9057,7 +9650,8 @@ SQLITE_API int sqlite3session_changeset(
);
/*
-** CAPI3REF: Load The Difference Between Tables Into A Session
+** CAPI3REF: Load The Difference Between Tables Into A Session
+** METHOD: sqlite3_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
@@ -9122,6 +9716,7 @@ SQLITE_API int sqlite3session_diff(
/*
** CAPI3REF: Generate A Patchset From A Session Object
+** METHOD: sqlite3_session
**
** The differences between a patchset and a changeset are that:
**
@@ -9173,6 +9768,7 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
+** CONSTRUCTOR: sqlite3_changeset_iter
**
** 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
@@ -9213,6 +9809,7 @@ SQLITE_API int sqlite3changeset_start(
/*
** CAPI3REF: Advance A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
@@ -9237,6 +9834,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -9271,6 +9869,7 @@ SQLITE_API int sqlite3changeset_op(
/*
** CAPI3REF: Obtain The Primary Key Definition Of A Table
+** METHOD: sqlite3_changeset_iter
**
** For each modified table, a changeset includes the following:
**
@@ -9302,6 +9901,7 @@ SQLITE_API int sqlite3changeset_pk(
/*
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -9332,6 +9932,7 @@ SQLITE_API int sqlite3changeset_old(
/*
** CAPI3REF: Obtain new.* Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -9365,6 +9966,7 @@ SQLITE_API int sqlite3changeset_new(
/*
** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function should only be used with iterator objects passed to a
** conflict-handler callback by [sqlite3changeset_apply()] with either
@@ -9392,6 +9994,7 @@ SQLITE_API int sqlite3changeset_conflict(
/*
** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
+** METHOD: sqlite3_changeset_iter
**
** This function may only be called with an iterator passed to an
** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
@@ -9408,6 +10011,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
/*
** CAPI3REF: Finalize A Changeset Iterator
+** METHOD: sqlite3_changeset_iter
**
** This function is used to finalize an iterator allocated with
** [sqlite3changeset_start()].
@@ -9424,6 +10028,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** to that error is returned by this function. Otherwise, SQLITE_OK is
** returned. This is to allow the following pattern (pseudo-code):
**
+** <pre>
** sqlite3changeset_start();
** while( SQLITE_ROW==sqlite3changeset_next() ){
** // Do something with change.
@@ -9432,6 +10037,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** if( rc!=SQLITE_OK ){
** // An error has occurred
** }
+** </pre>
*/
SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
@@ -9479,6 +10085,7 @@ SQLITE_API int sqlite3changeset_invert(
** sqlite3_changegroup object. Calling it produces similar results as the
** following code fragment:
**
+** <pre>
** sqlite3_changegroup *pGrp;
** rc = sqlite3_changegroup_new(&pGrp);
** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
@@ -9489,6 +10096,7 @@ SQLITE_API int sqlite3changeset_invert(
** *ppOut = 0;
** *pnOut = 0;
** }
+** </pre>
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
@@ -9504,11 +10112,15 @@ SQLITE_API int sqlite3changeset_concat(
/*
** CAPI3REF: Changegroup Handle
+**
+** A changegroup is an object used to combine two or more
+** [changesets] or [patchsets]
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
** CAPI3REF: Create A New Changegroup Object
+** CONSTRUCTOR: sqlite3_changegroup
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@@ -9546,6 +10158,7 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
+** METHOD: sqlite3_changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
@@ -9623,6 +10236,7 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pDa
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+** METHOD: sqlite3_changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
@@ -9653,25 +10267,25 @@ SQLITE_API int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
+** DESTRUCTOR: sqlite3_changegroup
*/
SQLITE_API 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.
+** Apply a changeset or patchset to a database. These functions attempt 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
+** The fourth argument (xFilter) passed to these functions 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.
+** passed as the sixth argument 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
+** 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
@@ -9716,7 +10330,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dl>
** <dt>DELETE Changes<dd>
-** For each DELETE change, this function checks if the target database
+** For each DELETE change, the 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
@@ -9761,7 +10375,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** [SQLITE_CHANGESET_REPLACE].
**
** <dt>UPDATE Changes<dd>
-** For each UPDATE change, this function checks if the target database
+** For each UPDATE change, the 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 modified non-primary key columns also match the values
@@ -9792,11 +10406,28 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** This can be used to further customize the applications conflict
** resolution strategy.
**
-** All changes made by this function are enclosed in a savepoint transaction.
+** All changes made by these functions 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.
+**
+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
+** may set (*ppRebase) to point to a "rebase" that may be used with the
+** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
+** is set to the size of the buffer in bytes. It is the responsibility of the
+** caller to eventually free any such buffer using sqlite3_free(). The buffer
+** is only allocated and populated if one or more conflicts were encountered
+** while applying the patchset. See comments surrounding the sqlite3_rebaser
+** APIs for further details.
+**
+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
+**
+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
+** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
@@ -9813,6 +10444,41 @@ SQLITE_API int sqlite3changeset_apply(
),
void *pCtx /* First argument passed to xConflict */
);
+SQLITE_API int sqlite3changeset_apply_v2(
+ 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 */
+ void **ppRebase, int *pnRebase, /* OUT: Rebase data */
+ int flags /* Combination of SESSION_APPLY_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_apply_v2
+**
+** The following flags may passed via the 9th parameter to
+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
+**
+** <dl>
+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
+** Usually, the sessions module encloses all operations performed by
+** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
+** SAVEPOINT is committed if the changeset or patchset is successfully
+** applied, or rolled back if an error occurs. Specifying this flag
+** causes the sessions module to omit this savepoint. In this case, if the
+** caller has an open transaction or savepoint when apply_v2() is called,
+** it may revert the partially applied changeset by rolling it back.
+*/
+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -9910,6 +10576,161 @@ SQLITE_API int sqlite3changeset_apply(
#define SQLITE_CHANGESET_REPLACE 1
#define SQLITE_CHANGESET_ABORT 2
+/*
+** CAPI3REF: Rebasing changesets
+** EXPERIMENTAL
+**
+** Suppose there is a site hosting a database in state S0. And that
+** modifications are made that move that database to state S1 and a
+** changeset recorded (the "local" changeset). Then, a changeset based
+** on S0 is received from another site (the "remote" changeset) and
+** applied to the database. The database is then in state
+** (S1+"remote"), where the exact state depends on any conflict
+** resolution decisions (OMIT or REPLACE) made while applying "remote".
+** Rebasing a changeset is to update it to take those conflict
+** resolution decisions into account, so that the same conflicts
+** do not have to be resolved elsewhere in the network.
+**
+** For example, if both the local and remote changesets contain an
+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
+**
+** local: INSERT INTO t1 VALUES(1, 'v1');
+** remote: INSERT INTO t1 VALUES(1, 'v2');
+**
+** and the conflict resolution is REPLACE, then the INSERT change is
+** removed from the local changeset (it was overridden). Or, if the
+** conflict resolution was "OMIT", then the local changeset is modified
+** to instead contain:
+**
+** UPDATE t1 SET b = 'v2' WHERE a=1;
+**
+** Changes within the local changeset are rebased as follows:
+**
+** <dl>
+** <dt>Local INSERT<dd>
+** This may only conflict with a remote INSERT. If the conflict
+** resolution was OMIT, then add an UPDATE change to the rebased
+** changeset. Or, if the conflict resolution was REPLACE, add
+** nothing to the rebased changeset.
+**
+** <dt>Local DELETE<dd>
+** This may conflict with a remote UPDATE or DELETE. In both cases the
+** only possible resolution is OMIT. If the remote operation was a
+** DELETE, then add no change to the rebased changeset. If the remote
+** operation was an UPDATE, then the old.* fields of change are updated
+** to reflect the new.* values in the UPDATE.
+**
+** <dt>Local UPDATE<dd>
+** This may conflict with a remote UPDATE or DELETE. If it conflicts
+** with a DELETE, and the conflict resolution was OMIT, then the update
+** is changed into an INSERT. Any undefined values in the new.* record
+** from the update change are filled in using the old.* values from
+** the conflicting DELETE. Or, if the conflict resolution was REPLACE,
+** the UPDATE change is simply omitted from the rebased changeset.
+**
+** If conflict is with a remote UPDATE and the resolution is OMIT, then
+** the old.* values are rebased using the new.* values in the remote
+** change. Or, if the resolution is REPLACE, then the change is copied
+** into the rebased changeset with updates to columns also updated by
+** the conflicting remote UPDATE removed. If this means no columns would
+** be updated, the change is omitted.
+** </dl>
+**
+** A local change may be rebased against multiple remote changes
+** simultaneously. If a single key is modified by multiple remote
+** changesets, they are combined as follows before the local changeset
+** is rebased:
+**
+** <ul>
+** <li> If there has been one or more REPLACE resolutions on a
+** key, it is rebased according to a REPLACE.
+**
+** <li> If there have been no REPLACE resolutions on a key, then
+** the local changeset is rebased according to the most recent
+** of the OMIT resolutions.
+** </ul>
+**
+** Note that conflict resolutions from multiple remote changesets are
+** combined on a per-field basis, not per-row. This means that in the
+** case of multiple remote UPDATE operations, some fields of a single
+** local change may be rebased for REPLACE while others are rebased for
+** OMIT.
+**
+** In order to rebase a local changeset, the remote changeset must first
+** be applied to the local database using sqlite3changeset_apply_v2() and
+** the buffer of rebase information captured. Then:
+**
+** <ol>
+** <li> An sqlite3_rebaser object is created by calling
+** sqlite3rebaser_create().
+** <li> The new object is configured with the rebase buffer obtained from
+** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
+** If the local changeset is to be rebased against multiple remote
+** changesets, then sqlite3rebaser_configure() should be called
+** multiple times, in the same order that the multiple
+** sqlite3changeset_apply_v2() calls were made.
+** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
+** <li> The sqlite3_rebaser object is deleted by calling
+** sqlite3rebaser_delete().
+** </ol>
+*/
+typedef struct sqlite3_rebaser sqlite3_rebaser;
+
+/*
+** CAPI3REF: Create a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
+** point to the new object and return SQLITE_OK. Otherwise, if an error
+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew)
+** to NULL.
+*/
+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
+
+/*
+** CAPI3REF: Configure a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Configure the changeset rebaser object to rebase changesets according
+** to the conflict resolutions described by buffer pRebase (size nRebase
+** bytes), which must have been obtained from a previous call to
+** sqlite3changeset_apply_v2().
+*/
+SQLITE_API int sqlite3rebaser_configure(
+ sqlite3_rebaser*,
+ int nRebase, const void *pRebase
+);
+
+/*
+** CAPI3REF: Rebase a changeset
+** EXPERIMENTAL
+**
+** Argument pIn must point to a buffer containing a changeset nIn bytes
+** in size. This function allocates and populates a buffer with a copy
+** of the changeset rebased rebased according to the configuration of the
+** rebaser object passed as the first argument. If successful, (*ppOut)
+** is set to point to the new buffer containing the rebased changset and
+** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
+** responsibility of the caller to eventually free the new buffer using
+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
+** are set to zero and an SQLite error code returned.
+*/
+SQLITE_API int sqlite3rebaser_rebase(
+ sqlite3_rebaser*,
+ int nIn, const void *pIn,
+ int *pnOut, void **ppOut
+);
+
+/*
+** CAPI3REF: Delete a changeset rebaser object.
+** EXPERIMENTAL
+**
+** Delete the changeset rebaser object and all associated resources. There
+** should be one call to this function for each successful invocation
+** of sqlite3rebaser_create().
+*/
+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
+
/*
** CAPI3REF: Streaming Versions of API functions.
**
@@ -9919,6 +10740,7 @@ SQLITE_API int sqlite3changeset_apply(
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
+** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
@@ -10014,6 +10836,23 @@ SQLITE_API int sqlite3changeset_apply_strm(
),
void *pCtx /* First argument passed to xConflict */
);
+SQLITE_API int sqlite3changeset_apply_v2_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 */
+ void **ppRebase, int *pnRebase,
+ int flags
+);
SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
@@ -10051,6 +10890,13 @@ SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
+SQLITE_API int sqlite3rebaser_rebase_strm(
+ sqlite3_rebaser *pRebaser,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int (*xOutput)(void *pOut, const void *pData, int nData),
+ void *pOut
+);
/*
@@ -10509,7 +11355,7 @@ struct Fts5ExtensionApi {
** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do would be
** inefficient), it doesn't matter if the user queries for
-** 'first + place' or '1st + place', as there are entires in the
+** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
** </ol>
**
@@ -10537,7 +11383,7 @@ struct Fts5ExtensionApi {
** extra data to the FTS index or require FTS5 to query for multiple terms,
** so it is efficient in terms of disk space and query speed. However, it
** does not support prefix queries very well. If, as suggested above, the
-** token "first" is subsituted for "1st" by the tokenizer, then the query:
+** token "first" is substituted for "1st" by the tokenizer, then the query:
**
** <codeblock>
** ... MATCH '1s*'</codeblock>
diff --git a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3ext.h b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3ext.h
index 543f856..bda8388 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/compat/sqlite3/sqlite3ext.h
+++ b/tcl8.6/pkgs/sqlite3.25.3/compat/sqlite3/sqlite3ext.h
@@ -292,6 +292,30 @@ struct sqlite3_api_routines {
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
+ int (*vtab_nochange)(sqlite3_context*);
+ int (*value_nochange)(sqlite3_value*);
+ const char *(*vtab_collation)(sqlite3_index_info*,int);
+ /* Version 3.24.0 and later */
+ int (*keyword_count)(void);
+ int (*keyword_name)(int,const char**,int*);
+ int (*keyword_check)(const char*,int);
+ sqlite3_str *(*str_new)(sqlite3*);
+ char *(*str_finish)(sqlite3_str*);
+ void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
+ void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
+ void (*str_append)(sqlite3_str*, const char *zIn, int N);
+ void (*str_appendall)(sqlite3_str*, const char *zIn);
+ void (*str_appendchar)(sqlite3_str*, int N, char C);
+ void (*str_reset)(sqlite3_str*);
+ int (*str_errcode)(sqlite3_str*);
+ int (*str_length)(sqlite3_str*);
+ char *(*str_value)(sqlite3_str*);
+ int (*create_window_function)(sqlite3*,const char*,int,int,void*,
+ void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+ void (*xFinal)(sqlite3_context*),
+ void (*xValue)(sqlite3_context*),
+ void (*xInv)(sqlite3_context*,int,sqlite3_value**),
+ void(*xDestroy)(void*));
};
/*
@@ -582,6 +606,27 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
+#define sqlite3_value_nochange sqlite3_api->value_nochange
+#define sqlite3_vtab_collation sqlite3_api->vtab_collation
+/* Version 3.24.0 and later */
+#define sqlite3_keyword_count sqlite3_api->keyword_count
+#define sqlite3_keyword_name sqlite3_api->keyword_name
+#define sqlite3_keyword_check sqlite3_api->keyword_check
+#define sqlite3_str_new sqlite3_api->str_new
+#define sqlite3_str_finish sqlite3_api->str_finish
+#define sqlite3_str_appendf sqlite3_api->str_appendf
+#define sqlite3_str_vappendf sqlite3_api->str_vappendf
+#define sqlite3_str_append sqlite3_api->str_append
+#define sqlite3_str_appendall sqlite3_api->str_appendall
+#define sqlite3_str_appendchar sqlite3_api->str_appendchar
+#define sqlite3_str_reset sqlite3_api->str_reset
+#define sqlite3_str_errcode sqlite3_api->str_errcode
+#define sqlite3_str_length sqlite3_api->str_length
+#define sqlite3_str_value sqlite3_api->str_value
+/* Version 3.25.0 and later */
+#define sqlite3_create_window_function sqlite3_api->create_window_function
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
diff --git a/tcl8.6/pkgs/sqlite3.21.0/configure b/tcl8.6/pkgs/sqlite3.25.3/configure
index 5814167..cf198ee 100755
--- a/tcl8.6/pkgs/sqlite3.21.0/configure
+++ b/tcl8.6/pkgs/sqlite3.25.3/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.21.0.
+# Generated by GNU Autoconf 2.69 for sqlite 3.25.3.
#
#
# 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.21.0'
-PACKAGE_STRING='sqlite 3.21.0'
+PACKAGE_VERSION='3.25.3'
+PACKAGE_STRING='sqlite 3.25.3'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -648,17 +648,10 @@ 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
@@ -682,6 +675,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1296,7 +1295,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.21.0 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.25.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1357,7 +1356,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.21.0:";;
+ short | recursive ) echo "Configuration of sqlite 3.25.3:";;
esac
cat <<\_ACEOF
@@ -1461,7 +1460,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.21.0
+sqlite configure 3.25.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1623,6 +1622,93 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_header_compile
+# 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
+
# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
@@ -1736,93 +1822,6 @@ $as_echo "$ac_res" >&6; }
} # 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
-
# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
# ---------------------------------------------
# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
@@ -1872,7 +1871,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.21.0, which was
+It was created by sqlite $as_me 3.25.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2228,26 +2227,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2256,7 +2245,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2348,6 +2337,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2457,6 +2495,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2483,13 +2524,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -4210,20 +4255,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -4895,470 +4926,6 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
#-----------------------------------------------------------------------
@@ -5436,6 +5003,10 @@ done
+ PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_DBPAGE_VTAB=1"
+
+
+
PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_DBSTAT_VTAB=1"
@@ -5468,6 +5039,10 @@ done
+ PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_GEOPOLY=1"
+
+
+
PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1"
@@ -7433,7 +7008,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8067,9 +7642,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -9532,7 +9107,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.21.0, which was
+This file was extended by sqlite $as_me 3.25.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9585,7 +9160,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.21.0
+sqlite config.status 3.25.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/sqlite3.21.0/configure.ac b/tcl8.6/pkgs/sqlite3.25.3/configure.ac
index e7c0d47..1ba619a 100755
--- a/tcl8.6/pkgs/sqlite3.21.0/configure.ac
+++ b/tcl8.6/pkgs/sqlite3.25.3/configure.ac
@@ -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.21.0])
+AC_INIT([sqlite], [3.25.3])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -75,6 +75,7 @@ TEA_ADD_SOURCES([tclsqlite3.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([-I\"`\${CYGPATH} \${srcdir}/generic`\"])
TEA_ADD_LIBS([])
+TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBPAGE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3_PARENTHESIS=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
@@ -83,6 +84,7 @@ 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_GEOPOLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1])
TEA_ADD_CFLAGS([-DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1])
TEA_ADD_CFLAGS([-DSQLITE_UNTESTABLE=1])
diff --git a/tcl8.6/pkgs/sqlite3.21.0/doc/sqlite3.n b/tcl8.6/pkgs/sqlite3.25.3/doc/sqlite3.n
index 13913e5..13913e5 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/doc/sqlite3.n
+++ b/tcl8.6/pkgs/sqlite3.25.3/doc/sqlite3.n
diff --git a/tcl8.6/pkgs/sqlite3.21.0/generic/tclsqlite3.c b/tcl8.6/pkgs/sqlite3.25.3/generic/tclsqlite3.c
index a5b19d9..9f8d827 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/generic/tclsqlite3.c
+++ b/tcl8.6/pkgs/sqlite3.25.3/generic/tclsqlite3.c
@@ -65,13 +65,18 @@
/* Used to get the current process ID */
#if !defined(_WIN32)
+# include <signal.h>
# include <unistd.h>
# define GETPID getpid
#elif !defined(_WIN32_WCE)
# ifndef SQLITE_AMALGAMATION
-# define WIN32_LEAN_AND_MEAN
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
# include <windows.h>
# endif
+# include <io.h>
+# define isatty(h) _isatty(h)
# define GETPID (int)GetCurrentProcessId
#endif
@@ -676,7 +681,7 @@ static int DbTraceV2Handler(
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
- Tcl_NewWideIntObj((Tcl_WideInt)(size_t)pStmt));
+ Tcl_NewWideIntObj((size_t)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewStringObj(zSql, -1));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
@@ -686,12 +691,12 @@ static int DbTraceV2Handler(
}
case SQLITE_TRACE_PROFILE: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
- size_t ns = (size_t)xd;
+ sqlite3_int64 ns = *(sqlite3_int64*)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
- Tcl_NewWideIntObj((Tcl_WideInt)(size_t)pStmt));
+ Tcl_NewWideIntObj((size_t)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)ns));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
@@ -705,7 +710,7 @@ static int DbTraceV2Handler(
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
- Tcl_NewWideIntObj((Tcl_WideInt)(size_t)pStmt));
+ Tcl_NewWideIntObj((size_t)pStmt));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
@@ -717,7 +722,7 @@ static int DbTraceV2Handler(
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
- Tcl_NewWideIntObj((Tcl_WideInt)(size_t)db));
+ Tcl_NewWideIntObj((size_t)db));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
@@ -1041,8 +1046,9 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
** has no string representation. */
data = Tcl_GetByteArrayFromObj(pVar, &n);
sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
- }else if( c=='b' && strcmp(zType,"boolean")==0 ){
- Tcl_GetIntFromObj(0, pVar, &n);
+ }else if( c=='b' && (strcmp(zType,"boolean")==0 ||
+ strcmp(zType,"booleanString")) ){
+ Tcl_GetBooleanFromObj(0, pVar, &n);
sqlite3_result_int(context, n);
}else if( c=='d' && strcmp(zType,"double")==0 ){
double r;
@@ -1409,8 +1415,9 @@ static int dbPrepareAndBind(
sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
Tcl_IncrRefCount(pVar);
pPreStmt->apParm[iParm++] = pVar;
- }else if( c=='b' && strcmp(zType,"boolean")==0 ){
- Tcl_GetIntFromObj(interp, pVar, &n);
+ }else if( c=='b' && (strcmp(zType,"boolean")==0 ||
+ strcmp(zType,"booleanString")==0) ){
+ Tcl_GetBooleanFromObj(interp, pVar, &n);
sqlite3_bind_int(pStmt, i, n);
}else if( c=='d' && strcmp(zType,"double")==0 ){
double r;
@@ -1894,35 +1901,35 @@ static int SQLITE_TCLAPI DbObjCmd(
int choice;
int rc = TCL_OK;
static const char *const DB_strs[] = {
- "authorizer", "backup", "busy",
- "cache", "changes", "close",
- "collate", "collation_needed", "commit_hook",
- "complete", "copy", "enable_load_extension",
- "errorcode", "eval", "exists",
- "function", "incrblob", "interrupt",
- "last_insert_rowid", "nullvalue", "onecolumn",
- "preupdate", "profile", "progress",
- "rekey", "restore", "rollback_hook",
- "status", "timeout", "total_changes",
- "trace", "trace_v2", "transaction",
- "unlock_notify", "update_hook", "version",
- "wal_hook",
- 0
+ "authorizer", "backup", "busy",
+ "cache", "changes", "close",
+ "collate", "collation_needed", "commit_hook",
+ "complete", "copy", "deserialize",
+ "enable_load_extension", "errorcode", "eval",
+ "exists", "function", "incrblob",
+ "interrupt", "last_insert_rowid", "nullvalue",
+ "onecolumn", "preupdate", "profile",
+ "progress", "rekey", "restore",
+ "rollback_hook", "serialize", "status",
+ "timeout", "total_changes", "trace",
+ "trace_v2", "transaction", "unlock_notify",
+ "update_hook", "version", "wal_hook",
+ 0
};
enum DB_enum {
- DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
- DB_CACHE, DB_CHANGES, DB_CLOSE,
- DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
- DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
- DB_ERRORCODE, DB_EVAL, DB_EXISTS,
- DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
- DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
- DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
- DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
- DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
- DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
- DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
- DB_WAL_HOOK,
+ DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
+ DB_CACHE, DB_CHANGES, DB_CLOSE,
+ DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
+ DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
+ DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
+ DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
+ DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
+ DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
+ DB_PROGRESS, DB_REKEY, DB_RESTORE,
+ DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
+ DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
+ DB_TRACE_V2, 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 */
@@ -2094,7 +2101,7 @@ static int SQLITE_TCLAPI DbObjCmd(
Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
return TCL_ERROR;
}
- subCmd = Tcl_GetStringFromObj(objv[2], NULL);
+ subCmd = Tcl_GetString( objv[2] );
if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "flush");
@@ -2109,7 +2116,7 @@ static int SQLITE_TCLAPI DbObjCmd(
}else{
if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
Tcl_AppendResult( interp, "cannot convert \"",
- Tcl_GetStringFromObj(objv[3], NULL), "\" to integer", (char*)0);
+ Tcl_GetString(objv[3]), "\" to integer", (char*)0);
return TCL_ERROR;
}else{
if( n<0 ){
@@ -2123,7 +2130,7 @@ static int SQLITE_TCLAPI DbObjCmd(
}
}else{
Tcl_AppendResult( interp, "bad option \"",
- Tcl_GetStringFromObj(objv[2], NULL), "\": must be flush or size",
+ Tcl_GetString(objv[2]), "\": must be flush or size",
(char*)0);
return TCL_ERROR;
}
@@ -2152,7 +2159,7 @@ static int SQLITE_TCLAPI DbObjCmd(
** Shutdown the database
*/
case DB_CLOSE: {
- Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], NULL));
+ Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
break;
}
@@ -2171,7 +2178,7 @@ static int SQLITE_TCLAPI DbObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
return TCL_ERROR;
}
- zName = Tcl_GetStringFromObj(objv[2], NULL);
+ zName = Tcl_GetString(objv[2]);
zScript = Tcl_GetStringFromObj(objv[3], &nScript);
pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
if( pCollate==0 ) return TCL_ERROR;
@@ -2260,7 +2267,7 @@ static int SQLITE_TCLAPI DbObjCmd(
Tcl_WrongNumArgs(interp, 2, objv, "SQL");
return TCL_ERROR;
}
- isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], NULL) );
+ isComplete = sqlite3_complete( Tcl_GetString(objv[2]) );
pResult = Tcl_GetObjResult(interp);
Tcl_SetBooleanObj(pResult, isComplete);
#endif
@@ -2312,18 +2319,18 @@ static int SQLITE_TCLAPI DbObjCmd(
return TCL_ERROR;
}
if( objc>=6 ){
- zSep = Tcl_GetStringFromObj(objv[5], NULL);
+ zSep = Tcl_GetString(objv[5]);
}else{
zSep = "\t";
}
if( objc>=7 ){
- zNull = Tcl_GetStringFromObj(objv[6], NULL);
+ zNull = Tcl_GetString(objv[6]);
}else{
zNull = "";
}
- zConflict = Tcl_GetStringFromObj(objv[2], NULL);
- zTable = Tcl_GetStringFromObj(objv[3], NULL);
- zFile = Tcl_GetStringFromObj(objv[4], NULL);
+ zConflict = Tcl_GetString(objv[2]);
+ zTable = Tcl_GetString(objv[3]);
+ zFile = Tcl_GetString(objv[4]);
nSep = strlen30(zSep);
nNull = strlen30(zNull);
if( nSep==0 ){
@@ -2394,7 +2401,7 @@ static int SQLITE_TCLAPI DbObjCmd(
Tcl_DStringInit(&str);
(void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
- while( Tcl_Gets(in, &str)!=-1 ){
+ while( (size_t)Tcl_Gets(in, &str)!=(size_t)-1 ) {
char *z;
lineno++;
zLine = Tcl_DStringValue(&str);
@@ -2463,6 +2470,53 @@ static int SQLITE_TCLAPI DbObjCmd(
}
/*
+ ** $db deserialize ?DATABASE? VALUE
+ **
+ ** Reopen DATABASE (default "main") using the content in $VALUE
+ */
+ case DB_DESERIALIZE: {
+#ifndef SQLITE_ENABLE_DESERIALIZE
+ Tcl_AppendResult(interp, "MEMDB not available in this build",
+ (char*)0);
+ rc = TCL_ERROR;
+#else
+ const char *zSchema;
+ Tcl_Obj *pValue;
+ unsigned char *pBA;
+ unsigned char *pData;
+ int len, xrc;
+
+ if( objc==3 ){
+ zSchema = 0;
+ pValue = objv[2];
+ }else if( objc==4 ){
+ zSchema = Tcl_GetString(objv[2]);
+ pValue = objv[3];
+ }else{
+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
+ rc = TCL_ERROR;
+ break;
+ }
+ pBA = Tcl_GetByteArrayFromObj(pValue, &len);
+ pData = sqlite3_malloc64( len );
+ if( pData==0 && len>0 ){
+ Tcl_AppendResult(interp, "out of memory", (char*)0);
+ rc = TCL_ERROR;
+ }else{
+ if( len>0 ) memcpy(pData, pBA, len);
+ xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
+ SQLITE_DESERIALIZE_FREEONCLOSE |
+ SQLITE_DESERIALIZE_RESIZEABLE);
+ if( xrc ){
+ Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
+ rc = TCL_ERROR;
+ }
+ }
+#endif
+ break;
+ }
+
+ /*
** $db enable_load_extension BOOLEAN
**
** Turn the extension loading feature on or off. It if off by
@@ -2648,7 +2702,7 @@ static int SQLITE_TCLAPI DbObjCmd(
}
pScript = objv[objc-1];
- zName = Tcl_GetStringFromObj(objv[2], NULL);
+ zName = Tcl_GetString(objv[2]);
pFunc = findSqlFunc(pDb, zName);
if( pFunc==0 ) return TCL_ERROR;
if( pFunc->pScript ){
@@ -2937,6 +2991,39 @@ static int SQLITE_TCLAPI DbObjCmd(
}
/*
+ ** $db serialize ?DATABASE?
+ **
+ ** Return a serialization of a database.
+ */
+ case DB_SERIALIZE: {
+#ifndef SQLITE_ENABLE_DESERIALIZE
+ Tcl_AppendResult(interp, "MEMDB not available in this build",
+ (char*)0);
+ rc = TCL_ERROR;
+#else
+ const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
+ sqlite3_int64 sz = 0;
+ unsigned char *pData;
+ if( objc!=2 && objc!=3 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
+ rc = TCL_ERROR;
+ }else{
+ int needFree;
+ pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
+ if( pData ){
+ needFree = 0;
+ }else{
+ pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
+ needFree = 1;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
+ if( needFree ) sqlite3_free(pData);
+ }
+#endif
+ break;
+ }
+
+ /*
** $db status (step|sort|autoindex|vmstep)
**
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
@@ -3396,6 +3483,24 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor(
#endif /* SQLITE_TCL_NRE */
/*
+** Issue the usage message when the "sqlite3" command arguments are
+** incorrect.
+*/
+static int sqliteCmdUsage(
+ Tcl_Interp *interp,
+ Tcl_Obj *const*objv
+){
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
+ " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
+ " ?-key CODECKEY?"
+#endif
+ );
+ return TCL_ERROR;
+}
+
+/*
** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
** ?-create BOOLEAN? ?-nomutex BOOLEAN?
**
@@ -3420,7 +3525,7 @@ static int SQLITE_TCLAPI DbMain(
const char *zArg;
char *zErrMsg;
int i;
- const char *zFile;
+ const char *zFile = 0;
const char *zVfs = 0;
int flags;
Tcl_DString translatedFilename;
@@ -3431,7 +3536,7 @@ static int SQLITE_TCLAPI DbMain(
int rc;
/* In normal use, each TCL interpreter runs in a single thread. So
- ** by default, we can turn of mutexing on SQLite database connections.
+ ** by default, we can turn off mutexing on SQLite database connections.
** However, for testing purposes it is useful to have mutexes turned
** on. So, by default, mutexes default off. But if compiled with
** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
@@ -3442,8 +3547,9 @@ static int SQLITE_TCLAPI DbMain(
flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
#endif
+ if( objc==1 ) return sqliteCmdUsage(interp, objv);
if( objc==2 ){
- zArg = Tcl_GetStringFromObj(objv[1], NULL);
+ zArg = Tcl_GetString(objv[1]);
if( strcmp(zArg,"-version")==0 ){
Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
return TCL_OK;
@@ -3460,18 +3566,26 @@ static int SQLITE_TCLAPI DbMain(
#endif
return TCL_OK;
}
+ if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
}
- for(i=3; i+1<objc; i+=2){
+ for(i=2; i<objc; i++){
zArg = Tcl_GetString(objv[i]);
+ if( zArg[0]!='-' ){
+ if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
+ zFile = zArg;
+ continue;
+ }
+ if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
+ i++;
if( strcmp(zArg,"-key")==0 ){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
- pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
+ pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
#endif
}else if( strcmp(zArg, "-vfs")==0 ){
- zVfs = Tcl_GetString(objv[i+1]);
+ zVfs = Tcl_GetString(objv[i]);
}else if( strcmp(zArg, "-readonly")==0 ){
int b;
- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
flags |= SQLITE_OPEN_READONLY;
@@ -3481,7 +3595,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-create")==0 ){
int b;
- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
flags |= SQLITE_OPEN_CREATE;
}else{
@@ -3489,7 +3603,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-nomutex")==0 ){
int b;
- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_NOMUTEX;
flags &= ~SQLITE_OPEN_FULLMUTEX;
@@ -3498,7 +3612,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-fullmutex")==0 ){
int b;
- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_FULLMUTEX;
flags &= ~SQLITE_OPEN_NOMUTEX;
@@ -3507,7 +3621,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-uri")==0 ){
int b;
- if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_URI;
}else{
@@ -3518,20 +3632,10 @@ static int SQLITE_TCLAPI DbMain(
return TCL_ERROR;
}
}
- if( objc<3 || (objc&1)!=1 ){
- Tcl_WrongNumArgs(interp, 1, objv,
- "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
- " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
-#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
- " ?-key CODECKEY?"
-#endif
- );
- return TCL_ERROR;
- }
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
memset(p, 0, sizeof(*p));
- zFile = Tcl_GetStringFromObj(objv[2], NULL);
+ if( zFile==0 ) zFile = "";
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
@@ -3558,7 +3662,7 @@ static int SQLITE_TCLAPI DbMain(
p->maxStmt = NUM_PREPARED_STMTS;
p->openFlags = flags & SQLITE_OPEN_URI;
p->interp = interp;
- zArg = Tcl_GetStringFromObj(objv[1], NULL);
+ zArg = Tcl_GetString(objv[1]);
if( DbUseNre() ){
Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
(char*)p, DbDeleteCmd);
@@ -3698,11 +3802,19 @@ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
#endif
#if !defined(_WIN32_WCE)
- if( getenv("BREAK") ){
- fprintf(stderr,
- "attach debugger to process %d and press any key to continue.\n",
- GETPID());
- fgetc(stdin);
+ if( getenv("SQLITE_DEBUG_BREAK") ){
+ if( isatty(0) && isatty(2) ){
+ fprintf(stderr,
+ "attach debugger to process %d and press any key to continue.\n",
+ GETPID());
+ fgetc(stdin);
+ }else{
+#if defined(_WIN32) || defined(WIN32)
+ DebugBreak();
+#elif defined(SIGTRAP)
+ raise(SIGTRAP);
+#endif
+ }
}
#endif
diff --git a/tcl8.6/pkgs/sqlite3.21.0/license.terms b/tcl8.6/pkgs/sqlite3.25.3/license.terms
index 723c4cd..723c4cd 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/license.terms
+++ b/tcl8.6/pkgs/sqlite3.25.3/license.terms
diff --git a/tcl8.6/pkgs/sqlite3.21.0/pkgIndex.tcl.in b/tcl8.6/pkgs/sqlite3.25.3/pkgIndex.tcl.in
index bc585f7..bc585f7 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/sqlite3.25.3/pkgIndex.tcl.in
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/install-sh b/tcl8.6/pkgs/sqlite3.25.3/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/install-sh
+++ b/tcl8.6/pkgs/sqlite3.25.3/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/tcl.m4 b/tcl8.6/pkgs/sqlite3.25.3/tclconfig/tcl.m4
index e8234a2..0fa06b2 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/tcl.m4
+++ b/tcl8.6/pkgs/sqlite3.25.3/tclconfig/tcl.m4
@@ -11,10 +11,6 @@
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.10"
-
# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
@@ -109,6 +105,9 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -135,13 +134,17 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -265,6 +268,9 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tk.framework/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
@@ -280,8 +286,15 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
; do
if test -f "$i/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i; pwd)`"
@@ -2053,7 +2066,7 @@ dnl # preprocessing tests use only CPPFLAGS.
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
@@ -2305,96 +2318,6 @@ int main() {
])
#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
# TEA_PATH_X
#
# Locate the X11 header files and the X11 library archive. Try
@@ -2649,92 +2572,6 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
])
#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
# TEA_TCL_EARLY_FLAGS
#
# Check for what flags are needed to be passed so the correct OS
@@ -2895,23 +2732,14 @@ 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.10"
+ TEA_VERSION="3.13"
- AC_MSG_CHECKING([for correct TEA configuration])
+ AC_MSG_CHECKING([TEA configuration])
if test x"${PACKAGE_NAME}" = x ; then
AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.ac])
fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
# 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".
@@ -2920,7 +2748,7 @@ TEA version not specified.])
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
EXEEXT=".exe"
TEA_PLATFORM="windows"
@@ -2973,6 +2801,9 @@ TEA version not specified.])
AC_SUBST(PKG_INCLUDES)
AC_SUBST(PKG_LIBS)
AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
])
#------------------------------------------------------------------------
@@ -3264,20 +3095,6 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
AC_PROG_CC
AC_PROG_CPP
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -3336,14 +3153,6 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
#--------------------------------------------------------------------
AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
])
#------------------------------------------------------------------------
@@ -3989,6 +3798,7 @@ AC_DEFUN([TEA_PATH_CONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4223,6 +4033,45 @@ AC_DEFUN([TEA_PATH_CELIB], [
fi
])
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
###
# Tip 430 - ZipFS Modifications
###
diff --git a/tcl8.6/pkgs/sqlite3.21.0/tests/all.tcl b/tcl8.6/pkgs/sqlite3.25.3/tests/all.tcl
index 3ed02eb..3ed02eb 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/tests/all.tcl
+++ b/tcl8.6/pkgs/sqlite3.25.3/tests/all.tcl
diff --git a/tcl8.6/pkgs/sqlite3.21.0/tests/leapsecond.test b/tcl8.6/pkgs/sqlite3.25.3/tests/leapsecond.test
index ae1d2a0..ae1d2a0 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/tests/leapsecond.test
+++ b/tcl8.6/pkgs/sqlite3.25.3/tests/leapsecond.test
diff --git a/tcl8.6/pkgs/sqlite3.21.0/win/makefile.vc b/tcl8.6/pkgs/sqlite3.25.3/win/makefile.vc
index 22c57f9..4800ade 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/win/makefile.vc
+++ b/tcl8.6/pkgs/sqlite3.25.3/win/makefile.vc
@@ -28,11 +28,11 @@ PRJ_OBJS = $(TMP_DIR)\tclsqlite3.obj
# Preprocessor macros specific to sqlite3.
PRJ_DEFINES = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE \
- -DSQLITE_ENABLE_DBSTAT_VTAB=1 \
+ -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 \
-DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 \
-DSQLITE_ENABLE_JSON=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \
- -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
+ -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 \
-DSQLITE_UNTESTABLE=1 -DSQLITE_OMIT_LOOKASIDE=1 \
-DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DDSQLITE_USE_ALLOCA=1 \
diff --git a/tcl8.6/pkgs/sqlite3.21.0/win/nmakehlp.c b/tcl8.6/pkgs/sqlite3.25.3/win/nmakehlp.c
index 025bb99..b759020 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/win/nmakehlp.c
+++ b/tcl8.6/pkgs/sqlite3.25.3/win/nmakehlp.c
@@ -14,13 +14,8 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
-#define NO_SHLWAPI_GDI
-#define NO_SHLWAPI_STREAM
-#define NO_SHLWAPI_REG
-#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
-#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>
@@ -74,7 +69,7 @@ main(
char msg[300];
DWORD dwWritten;
int chars;
- char *s;
+ const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
@@ -688,6 +683,17 @@ SubstituteFile(
return 0;
}
+BOOL FileExists(LPCTSTR szPath)
+{
+#ifndef INVALID_FILE_ATTRIBUTES
+ #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+#endif
+ DWORD pathAttr = GetFileAttributes(szPath);
+ return (pathAttr != INVALID_FILE_ATTRIBUTES &&
+ !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+
/*
* QualifyPath --
*
@@ -701,13 +707,8 @@ QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
- char szTmp[MAX_PATH + 1];
- char *p;
- GetCurrentDirectory(MAX_PATH, szCwd);
- while ((p = strchr(szPath, '/')) && *p)
- *p = '\\';
- PathCombine(szTmp, szCwd, szPath);
- PathCanonicalize(szCwd, szTmp);
+
+ GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
@@ -765,7 +766,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath)
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
- if (PathFileExists(path)) {
+ if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
diff --git a/tcl8.6/pkgs/sqlite3.25.3/win/rules-ext.vc b/tcl8.6/pkgs/sqlite3.25.3/win/rules-ext.vc
new file mode 100644
index 0000000..531e070
--- /dev/null
+++ b/tcl8.6/pkgs/sqlite3.25.3/win/rules-ext.vc
@@ -0,0 +1,118 @@
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!if "$(TCLDIR)" != ""
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
+!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/sqlite3.21.0/win/rules.vc b/tcl8.6/pkgs/sqlite3.25.3/win/rules.vc
index fac9af9..13b3fba 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/win/rules.vc
+++ b/tcl8.6/pkgs/sqlite3.25.3/win/rules.vc
@@ -24,7 +24,7 @@ _RULES_VC = 1
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
+RULES_VERSION_MINOR = 2
# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
@@ -393,7 +393,7 @@ MSG = ^
!endif
-# If INSTALLDIR set to tcl installation root dir then reset to the
+# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
@@ -535,7 +535,6 @@ NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
-!message *** Using $(NMAKEHLPC)
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif
@@ -590,7 +589,6 @@ FPOPTS = $(FPOPTS) -QI0f
OPTIMIZATIONS = $(FPOPTS)
!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
OPTIMIZING = 1
OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
!else
@@ -1077,12 +1075,24 @@ TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
!if $(TCLINSTALL) # Building against an installed Tcl
+# When building extensions, we need to locate tclsh. Depending on version
+# of Tcl we are building against, this may or may not have a "t" suffix.
+# Try various possibilities in turn.
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist("$(TCLSH)") && $(TCL_THREADS)
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
+!if !exist("$(TCLSH)")
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+
TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
TCL_LIBRARY = $(_TCLDIR)\lib
TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
@@ -1095,8 +1105,16 @@ TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
+!if !exist($(TCLSH))
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
TCL_LIBRARY = $(_TCLDIR)\library
TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
@@ -1140,11 +1158,23 @@ TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
WISH = $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+!endif
TK_INCLUDES = -I"$(_TKDIR)\include"
!else # Building against Tk sources
WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+!endif
TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif # TKINSTALL
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
@@ -1179,7 +1209,7 @@ RESFILE = $(TMP_DIR)\$(PROJECT).res
# SCRIPT_INSTALL_DIR - where scripts should be installed
# INCLUDE_INSTALL_DIR - where C include files should be installed
# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
!if $(DOING_TCL) || $(DOING_TK)
LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
@@ -1201,7 +1231,7 @@ BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include
!endif
@@ -1705,7 +1735,6 @@ TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!message *** Output directory will be '$(OUT_DIR)'
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
+!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/targets.vc b/tcl8.6/pkgs/sqlite3.25.3/win/targets.vc
index 312022d..7f1d388 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/targets.vc
+++ b/tcl8.6/pkgs/sqlite3.25.3/win/targets.vc
@@ -1,98 +1,98 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbc1.0.6/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbc1.0.6/pkgIndex.tcl.in
deleted file mode 100644
index d95e958..0000000
--- a/tcl8.6/pkgs/tdbc1.0.6/pkgIndex.tcl.in
+++ /dev/null
@@ -1,12 +0,0 @@
-# Index file to load the TDBC package.
-
-# Make sure that TDBC is running in a compatible version of Tcl, and
-# that TclOO is available.
-
-if {[catch {package present Tcl @TCL_VERSION_REQ@}]} {
- return
-}
-package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \
- "package require TclOO @TCLOO_VERSION_REQ@-;\
- [list load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@]\;\
- [list source [file join $dir @PACKAGE_NAME@.tcl]]"
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/ChangeLog b/tcl8.6/pkgs/tdbc1.0.6/tclconfig/ChangeLog
deleted file mode 100644
index 9504def..0000000
--- a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/ChangeLog
+++ /dev/null
@@ -1,1003 +0,0 @@
-2016-03-11 Sean Woods <yoda@etoyoc.com>
- *tcl.m4 Fixed the search for Tcl and Wish shells under MinGW. Static builds and threaded builds
- get an "s" or "t" added to the name.
-
-2015-08-28 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Rfe [00189c4afc]: Allow semi-static UCRT build on
- Windows with VC 14.0
-
-2013-10-08 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [172223e008]: Wrong filename in
- --disable-shared compile on MinGW
-
-2013-10-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: stub library is no longer linked with msvcrt??.dll.
-
-2013-10-01 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Workaround for MinGW bug #2065: "gcc --shared" links
- with libgcc_s_dw2-1.dll when using 64-bit division in C
-
-2013-07-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [3324676]: AC_PROG_INSTALL incompat,
- Bug [3606445]: Unneeded -DHAVE_NO_SEH=1 when not building on Windows
-
-2013-07-02 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
- (thanks to Brian Griffin)
-
-2013-06-20 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Use X11/Xlib.h for checking where X11 can be found
- in stead of X11/XIntrinsic.h. Suggested by Pietro Cerutti.
-
-2013-06-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Eliminate NO_VIZ macro as current
- zlib uses HAVE_HIDDEN in stead. One more last-moment
- fix for FreeBSD by Pietro Cerutti
-
-2013-05-19 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Fix for FreeBSD, and remove support for old
- FreeBSD versions. Patch by Pietro Cerutti
-
-2013-03-12 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Patch by Andrew Shadura, providing better support for
- * three architectures they have in Debian.
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Added "-DNDEBUG" to CFLAGS_DEFAULT
- when building with --disable-symbols.
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: [Bug 3555058]: Checkin [30736d63f0] broke
- CFLAGS_DEFAULT, LDFLAGS_DEFAULT
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
-
-2012-08-07 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
-
-2012-07-25 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: My previous commit (2012-04-03) broke the ActiveTcl
- build for AMD64, because of the quotes in "C:/<path>/AMD64/cl.exe".
- It turns out that the AC_TRY_COMPILE macro cannot handle that.
-
-2012-07-22 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Tidy: consistency, spelling, phrasing, whitespace.
- No functional change.
-
-2012-04-03 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 3511806] Compiler checks too early
- This change allows to build the cygwin and mingw32 ports of
- Tcl/Tk extensions to build out-of-the-box using a native or
- cross-compiler, e.g. on Cygwin, Linux or Darwin.
-
-2011-04-02 Jan Nijtmans <nijtmans@users.sf.net>
-
- * install-sh: Fix issue with library stripping in install-sh
- (backported from kevin_walzer's patch from Tcl 8.6 trunk)
-
-2011-04-05 Andreas Kupries <andreask@activestate.com>
-
- * tcl.m4: Applied patch by Jeff Lawson. Nicer error message when
- tclConfig.sh was not found.
-
-2010-12-15 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * install-sh: Upgrade to newer install-sh and use it.
- * tcl.m4:
-
-2010-12-14 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Better building on OpenBSD.
-
-2010-12-14 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: when using gcc, don't try to determine Win64 SDK
-
-2010-12-12 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Determine correctly a cross-compiler-windres
-
-2010-11-23 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: add some cross-compile support, borrowed from Tcl 8.6
-
-2010-09-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct HP-UX LDFLAGS (only used when building big shell)
-
-2010-09-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add extra if check for .manifest file generation
- Add notice about package name and version being built.
-
-2010-09-09 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [FREQ #3058486] TEA_LOAD_CONFIG doesn't set all BUILD_ vars
- Slightly related: defining BUILD_$1 on all platforms - not only win -
- allows the -fvisibility feature to be used in extensions as well, at
- least if you compile against tcl >= 8.5.
-
-2010-08-26 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: ensure safe quoting for autoheader usage
-
-2010-08-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add TEA_ADD_CLEANFILES macro to make adding cleanfiles
- easier, and add *.exp to CLEANFILES Windows default.
- (TEA_MAKE_LIB): Enhanced to check for MSVC that requires manifests
- and auto-embed it into proj DLL via MAKE_SHARED_LIB. Also define
- VC_MANIFEST_EMBED_DLL and VC_MANIFEST_EMBED_EXE that do the same
- magic in case it is needed for extended TEA projects.
-
-2010-08-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.9 ***
- If upgrading from TEA_VERSION 3.8, copy over tcl.m4, change
- TEA_INIT to use 3.9 and reconfigure (ac-2.59+).
- BUILD_${PACKAGE_NAME} will be auto-defined on Windows for
- correct setting of TCL_STORAGE_CLASS.
- TEA_LOAD_CONFIG users should remove the SHLIB_LD_LIBS setting done
- in configure.in (LIBS will be automagically populated by
- TEA_LOAD_CONFIG).
- TEA_EXPORT_CONFIG has been added for ${pkg}Config.sh creators
- SHLIB_LD_FLAGS was deprecated a while ago, remove it if it is
- still in your Makefile.in.
-
- * tcl.m4: add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
- Auto-define BUILD_$PACKAGE_NAME so users don't need to. This
- needs to correspond with $pkg.h define magic for TCL_STORAGE_CLASS.
- Auto-define CLEANFILES. Users can expand it.
- (SHLIB_LD_LIBS): define to '${LIBS}' default and change it only if
- necessary. Platforms not using this may simply not work or have
- very funky linkers.
- (TEA_LOAD_CONFIG): When loading config for another extension,
- auto-add stub libraries found with TEA_ADD_LIBS. Eases
- configure.in for modules like itk and img::*.
- (TEA_EXPORT_CONFIG): Add standardized function for exporting a
- ${pkg}Config.sh. See use by img::* and itcl.
-
-2010-08-12 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.8 ***
- If upgrading from TEA_VERSION 3.7, copy over tcl.m4, change
- TEA_INIT to use 3.8 and reconfigure (ac-2.59+).
- No other changes should be necessary.
-
- * tcl.m4: remove more vestigial bits from removed platforms.
- Add back SCO_SV-3.2*.
- Remove use of DL_LIBS and DL_OBJS and related baggage - these are
- only needed by the core to support 'load'.
- Allow for macosx in TEA_ADD_SOURCES.
- Correct check for found_xincludes=no in TEA_PATH_UNIX_X.
-
-2010-08-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove the following old platform configurations:
- UNIX_SV*|UnixWare-5*, SunOS-4.*, SINIX*5.4*, SCO_SV-3.2*<readded>,
- OSF1-1.*, NEXTSTEP-*, NetBSD-1.*|FreeBSD-[[1-2]].*, MP-RAS-*,
- IRIX-5.*, HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*, dgux*,
- BSD/OS-2.1*|BSD/OS-3*
- (AIX): drop AIX-pre4 support and use of ldAix, use -bexpall/-brtl
-
-2010-07-05 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Patch #1055668] removal of exported internals from
- tclInt.h (EXTERN macro)
-
-2010-04-14 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4 - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4
- - Fix determination of CYGPATH for CYGWIN
- With those fixes, itcl and tdbc compile fine with CYGWIN
-
-2010-04-06 Jan Nijtmans <nijtmans@users.sf.net>
-
- * install-sh [Bug 2982540] configure and install* script files
- should always have LF
-
-2010-02-19 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Correct compiler/linker flags for threaded builds on
- OpenBSD.
-
-2010-01-19 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Detect CYGWIN variant: win32 or unix
-
-2010-01-03 Donal K. Fellows <dkf@users.sf.net>
-
- * unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the
- configuration for modern FreeBSD suggested by the FreeBSD porter.
-
-2009-10-22 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS
-
-2009-04-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on
- AIX with threads.
-
-2009-04-10 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): check for 64-bit TkAqua.
-
-2009-03-26 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS
- together with SHLIB_LD definition to unbreak building on HPUX.
-
-2009-03-20 Andreas Kupries <andreask@activestate.com>
-
- * tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak
- building on HPUX.
-
-2009-03-16 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC}
- (found in tkConfig.sh) when trying to guess where tk.h might be
- [Patch 1960628].
-
-2009-03-11 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at
- configure-time [Patch 1960628]. Also fix some comment typos,
- and an uninitialized variable bug-waiting-to-happen.
-
-2008-12-21 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX
- (this bug report was for Tcl, but holds for TEA as well.)
-
-2008-12-20 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: sync with tdbc tcl.m4 changes
- (SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS
-
-2008-12-02 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.7 ***
-
- * tcl.m4: in private header check, check for <plat>Port.h instead
- of Int.h to ensure all private headers are available.
-
-2008-11-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of
- Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS.
-
-2008-11-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error
- when tclConfig.sh cannot be found. [Bug #1997760]
- (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for
- finding the headers installed in the public areas, e.g. a result of
- make install-private-headers. [Bug #1631922]
-
-2008-08-12 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): link shlib with current and compatiblity version
- flags; look for libX11.dylib when searching for X11 libraries.
-
-2008-06-12 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
-
-2008-03-27 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
-
-2008-02-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with
- more modern VC versions. Currently just made the linker flags more
- flexible; more work may be needed.
-
-2007-10-26 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add support for 64-bit X11.
-
-2007-10-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Tagged tea-3-branch to start TEA 4 development on HEAD ***
-
-2007-09-17 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable'
- to build shared libraries on current NetBSDs [Bug 1749251].
-
-2007-09-15 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: replace all direct references to compiler by ${CC} to
- enable CC overriding at configure & make time.
- (SunOS-5.1x): replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
- 'cc' compiler driver.
-
-2007-08-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: check Ttk dir for Tk private headers (8.5).
- Add some comments to other bits.
-
-2007-06-25 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added.
-
-2007-06-13 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: fix --with-tkinclude alignment. [Bug 1506111]
-
-2007-06-06 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds.
-
-2007-05-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * tcl.m4: Added quoting so that paths with spaces cause fewer
- problems.
-
-2007-03-07 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check.
-
-2007-02-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct private header check to search in generic subdir
-
-2007-02-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.6 ***
-
- * tcl.m4: correct -d to -f
- (TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058]
-
-2007-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check
- that the dirs actually have private headers. [Bug 1631922]
-
-2007-02-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: add caching to -pipe check.
-
-2007-01-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
- move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
- avoid errors about multiple -isysroot flags from some older gcc builds.
-
-2006-01-19 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
- (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
- present in CFLAGS to avoid discrepancies between what headers configure
- sees during preprocessing tests and compiling tests.
-
-2006-12-19 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag
- succeeds before enabling 64bit build.
-
-2006-12-16 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Linux): fix previous change to use makefile variable
- LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker
- flags in sampleextension Makefile are picked up.
-
-2006-11-26 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558]
-
-2006-08-18 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
- universal builds including x86_64 and for use of -mmacosx-version-min
- instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit
- arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor
- TkX11 can be built for 64-bit at present.
-
-2006-03-28 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: []-quote AC_DEFUN functions.
- (TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh.
- (TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs.
-
-2006-03-07 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
- as per the other *BSD variants [Bug 1334613].
-
-2006-01-25 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA version 3.5 ***
-
- * tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous
- with core tcl.m4 meaning.
-
-2006-01-24 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of
- LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile
- are picked up. [Bug 1403343]
-
-2006-01-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for
- *Config.sh on Windows. [Bug 1407544]
-
-2006-01-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS
- like in the Tk configure, as neither TkAqua nor TkX11 can be built for
- 64bit at present (no 64bit GUI libraries).
-
-2006-01-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: restore system=windows on Windows.
- Remove error if 'ar' isn't found (it may not be on Windows).
- Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default.
- Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at
- configure time.
-
-2006-01-10 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL
- where possible, consistent message quoting, sync relevant
- tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences
- (notably sunc removal of support for for ancient BSD's, IRIX 4,
- RISCos and Ultrix by kennykb), Darwin improvements to
- TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks
- installed in arbitrary location, change TEA_PROG_* search order
- (look in *_BIN_DIR parents before *_PREFIX).
-
-2006-01-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add dkf's system config refactor
-
-2006-01-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove extraneous ' that causes bash 3.1 to choke
-
-2005-12-19 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c
- in ${libdir}, where they are installed by default [Patch #1377407].
-
-2005-12-05 Don Porter <dgp@users.sf.net>
-
- * tcl.m4 (TEA_PUBLIC_*_HEADERS): Better support for finding
- header files for uninstalled Tcl and Tk.
-
-2005-12-02 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correctly bump TEA_VERSION var to 3.4
-
-2005-12-01 Daniel Steffen <das@users.sourceforge.net>
-
- * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
-
-2005-11-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: *** Bump to TEA version 3.4 ***
- Add Windows x64 build support.
- Remove TEA_PATH_NOSPACE and handle the problem with ""s where
- necessary - the macro relied on TCLSH_PROG which didn't work for
- cross-compiles.
-
-2005-11-27 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to
- support passing -isysroot in env(CFLAGS) to configure (flag can't
- be present twice, so can't be in both CFLAGS and LDFLAGS during
- configure), don't use -prebind when deploying on 10.4.
- (TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching.
-
-2005-10-30 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that
- should have been for `uname -s` = "Darwin" instead; added some
- missing quoting.
- (TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that
- install location of tclConfig.sh/tkConfig.sh allows to determine
- the tclsh/wish install dir via ../bin. Indeed tcl/tk can be
- configured with arbitrary --libdir and --bindir (independent of
- prefix) and such a configuration is in fact standard with Darwin
- framework builds. At least now also check ${TCL_PREFIX}/bin
- resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk
- have been configured with arbitrary --bindir, this will still not
- find them, for a general solution *Config.sh would need to contain
- the values of bindir/libdir/includedir passed to configure).
-
-2005-10-07 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds.
-
-2005-10-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro
- (TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func
-
-2005-09-13 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: *** Update to TEA version 3.3 ***
- define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG.
- Make --enable-threads the default (users can --disable-threads).
- Improve AIX ${CC}_r fix to better check existing ${CC} value.
- Do the appropriate evals to not require the *TOP_DIR_NATIVE vars
- be set for extensions that use private headers.
- Make aqua check for Xlib compat headers the same as win32.
-
-2005-07-26 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
- TEA_PROG_WISH, TEA_BUILD_WISH): Remove
- TEA_BUILD_TCLSH and TEA_BUILD_WISH because
- of complaints that it broke the build when
- only an installed version of Tcl was available
- at extension build time. The TEA_PROG_TCLSH and
- TEA_PROG_WISH macros will no longer search the
- path at all. The build tclsh or installed
- tclsh shell will now be found by TEA_PROG_TCLSH.
-
-2005-07-24 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
- TEA_PROG_WISH, TEA_BUILD_WISH):
- Split confused search for tclsh on PATH and
- build and install locations into two macros.
- TEA_PROG_TCLSH and TEA_PROG_WISH search the
- system PATH for an installed tclsh or wish.
- The TEA_BUILD_TCLSH and TEA_BUILD_WISH
- macros determine the name of tclsh or
- wish in the Tcl or Tk build directory even
- if tclsh or wish has not yet been built.
- [Tcl bug 1160114]
- [Tcl patch 1244153]
-
-2005-06-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to
- TK_INCLUDES when building against TkAqua.
-
- * tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE
-
- * tcl.m4: changes to better support framework builds of Tcl and Tk out
- of the box: search framework install locations for *Config.sh, and if in
- presence of a framework build, use the framework's Headers and
- PrivateHeaders directories for public and private includes. [FR 947735]
-
-2005-06-18 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
- ensure we can always relocate binaries with install_name_tool.
-
-2005-06-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib
- compat headers are available in tkheaders location, otherwise add xlib
- sourcedir to TK_XINCLUDES.
-
-2005-04-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow
- use with autoheader.
- (Darwin): added configure checks for recently added linker flags
- -single_module and -search_paths_first to allow building with older
- tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD.
- (TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check.
- (TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4).
-
-2005-03-24 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide
- int type only on Windows when __int64 is detected as valid.
-
-2005-03-24 Don Porter <dgp@users.sf.net>
-
- * README.txt: Update reference to "SC_* macros" to "TEA_* macros".
- * tcl.m4: Incorporated recent improvements in SC_PATH_TCLCONFIG
- and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG.
- Corrected search path in TEA_PATH_CONFIG and added
- AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load
- the configuration of another package can know where they loaded
- it from.
-
-2005-03-18 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have
- variant LD_SEARCH_FLAGS for gcc and cc builds.
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check.
-
-2005-03-17 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Correct gcc build and HP-UX-11.
-
-2005-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -.
- (TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build.
- (TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed).
-
-2005-02-01 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: redo of 2005-01-27 changes to correctly handle paths
- with spaces. Win/CE and Win/64 builds now require a prebuilt
- tclsh to handle conversion to short pathnames. This is done in
- the new TEA_PATH_NOSPACE macro. For Win/CE|64, make CC just the
- compiler and move the necessary includes to CFLAGS.
- (TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support.
- (TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to
- be set in the env and prevent resetting.
- (TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib
- args to -lfoo, for use with mingw.
- *** POTENTIAL INCOMPATABILITY ***
- (TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box.
- Bumped TEA to 3.2.
-
-2005-01-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove cygpath calls to support msys.
- Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003".
- Make STLIB_LD use $LINKBIN -lib.
-
-2005-01-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): fixed bug with static build linking to dynamic
- library in /usr/lib etc instead of linking to static library earlier
- in search path. [Tcl Bug 956908]
- Removed obsolete references to Rhapsody.
-
-2004-12-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS
- options, using better default -O levels. [Bug 1092952, 1091967]
-
-2004-12-29 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Do not use ${DBGX} suffix when building
- shared libraries [patch #1081595, TIP #34]
-
-2004-09-07 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds
-
-2004-08-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to
- work around subdir configures since autoconf only propagates the
- prefix (not exec_prefix).
-
-2004-07-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with
- Tcl 8.5 HEAD config, removed core specific & obsolete settings.
-
-2004-07-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if
- we are compiling on Aqua. Add TEA_WINDOWINGSYSTEM var that
- reflects 'tk windowingsystem' value.
-
-2004-07-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when
- building against a threaded core.
- (CFLAGS_WARNING): Remove -Wconversion for gcc builds
- (TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build
- configuration, replacing EXTRA_CFLAGS with CFLAGS. [Bug #874058]
- Update to latest Tcl 8.5 head config settings.
- Call this TEA version 3.1.
-
-2004-04-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with
- AC_TRY_COMPILE for the long vs. long long check. (kenny)
-
-2004-04-26 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to
- define TCL_WIDE_INT_IS_LONG if 'using long'.
-
-2004-03-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB
-
-2004-02-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct TCL_INCLUDES for private headers on Windows - it
- doesn't need the eval.
-
-2004-02-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the
- DIR_NATIVE vars defined when using private headers on unix.
- Allow $... to TEA_ADD_SOURCES for constructs like
- TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to
- place more in the Makefile.in.
- tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
- CHECK on limits.h
-
-2003-12-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * Makefile.in: added TEA_ADD_LIBS, TEA_ADD_INCLUDES and
- * configure: TEA_ADD_CFLAGS to configurable parameters with
- * configure.in: PKG_* equivs in the Makefile. This allows the
- * tclconfig/tcl.m4: user to worry less about actual magic VAR names.
- Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires
- exact file names.
-
-2003-12-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff)
-
-2003-12-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * configure:
- * configure.in:
- * Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the
- first part of VPATH can get chopped off.
- Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes.
- * tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub
- generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as
- the way the user specifies library files.
-
-2003-12-03 Jeff Hobbs <jeffh@ActiveState.com>
-
- * configure: Update of TEA spec to (hopefully) simplify
- * configure.in: some aspects of TEA by making use of more
- * Makefile.in: AC 2.5x features. Use PACKAGE_NAME (instead
- * generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of
- * tclconfig/tcl.m4: VERSION) arguments to AC_INIT as the TEA
- package name and version.
- Provide a version argument to TEA_INIT - starting with 3.0.
- Drop all use of interior shell substs that older makefiles didn't
- like. Use PKG_* naming convention instead.
- Move specification of source files and public headers into
- configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS. These will
- be munged during ./configure into the right obj file names (no
- $(SOURCES:.c=.obj) needed).
- There is almost nothing that should be touched in Makefile.in now
- for the developer. May want to add a TEA_ADD_TCL_SOURCES for the
- RUNTIME_SOURCES that remains.
- Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does.
- Only specify the user requested LDFLAGS/CFLAGS in the Makefile,
- don't mention the _OPTIMIZE/_DEBUG variants.
-
-2003-10-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the
- TEA_SETUP_COMPILER macro. They are split so the check for CC
- occurs before any use of CC. Also add AC_PROG_CPP to the compiler
- checks.
-
-2003-10-06 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Updated for autoconf 2.5x prereq.
- Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks
- in tcl.h, which also handles TCL_LL_MODIFIER* properly.
-
-2003-04-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct default setting of ARCH for WinCE builds.
- Correct \ escaping for CE sed macros.
-
-2003-04-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: replace $(syscal) construct with older `syscall` for
- systems where sh != bash.
-
-2003-04-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib
- options for Windows/CE compilation support. Requires the
- Microsoft eMbedded SDK and Keuchel's celib emulation layer.
-
-2003-02-18 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on
- the link line when checking for the pthread_attr_setstacksize
- symbol. (dejong)
-
- * tcl.m4 (TEA_SETUP_COMPILER): added default calls to
- TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS,
- TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD.
-
-2003-02-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct HP-UX ia64 --enable-64bit build flags
-
-2003-01-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: check $prefix/lib as well as $exec_prefix/lib when
- looking for tcl|tkConfig.sh, as this check is done before we would
- set exec_prefix when the user does not define it.
-
-2003-01-21 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support
- for mingw, the previous implementation would
- use VC++ when compiling with mingw gcc. Don't
- pass -fPIC since gcc always compiles pic code
- under win32. Change some hard coded cases
- of gcc to ${CC}.
-
-2002-10-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to
- TEA_MAKE_LIB because setting too early confuses other AC_* macros.
- Correct the HP-11 SHLIB_LD_LIBS setting.
-
- * tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and
- make it pick up the env CFLAGS at configure time.
-
-2002-10-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG.
- Improved AIX 64-bit build support, allow it on AIX-4 as well.
- Enable 64-bit HP-11 compilation with gcc.
- Enable 64-bit IRIX64-6 cc build support.
- Correct FreeBSD thread library linkage.
- Add OSF1 static build support.
- Improve SunOS-5 shared build SHLIB_LD macro.
-
-2002-07-20 Zoran Vasiljevic <zoran@archiware.com>
-
- * tcl.m4: Added MINGW32 to list of systems checked for Windows build.
- Also, fixes some indentation issues with "--with-XXX" options.
-
-2002-04-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to
- use new threaded allocatory by default on Unix for Tcl 8.4.
- (TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+.
-
-2002-04-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that
- we can use autoconf 2.5x as well as 2.13. This prevents us from
- being able to warn against the use of cygwin gcc at configure
- time, but allows autoconf 2.5x, which is what is shipped with most
- newer systems.
-
-2002-04-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Enabled COFF as well as CV style debug info with
- --enable-symbols to allow Dr. Watson users to see function info.
- More info on debugging levels can be obtained at:
- http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
-
-2002-04-03 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: change all SC_* macros to TEA_*. The SC_ was for
- Scriptics, which is no more. TEA represents a better, independent
- prefix that won't need changing.
- Added preliminary mingw gcc support. [Patch #538772]
- Added TEA_PREFIX macro that handles defaulting the prefix and
- exec_prefix vars to those used by Tcl if none were specified.
- Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC
- check and several other basic AC_PROG checks needed for making
- executables. This greatly simplifies user's configure.in files.
- Collapsed AIX-5 defines into AIX-* with extra checks for doing the
- ELF stuff on AIX-5-ia64.
- Updated TEA_ENABLE_THREADS to take an optional arg to allow
- switching it on by default (for Thread) and add sanity checking to
- warn the user if configuring threads incompatibly.
-
-2002-03-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT.
- Removed --enable-64bit support for AIX-4 because it wasn't correct.
- Added -MT or -MD Windows linker switches to properly support
- symbols-enabled builds.
-
-2002-03-28 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first
- instead of calling it as that inlines it each time in shell code.
- Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti.
- Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds.
- A few changes to support itcl (and perhaps others):
- Added support for making your own stub libraries to SC_MAKE_LIB.
- New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg
- and find that ${pkg}Config.sh file. itk uses this for itcl.
-
-2002-03-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk
- build dir setup.
- Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS.
- Added XLIBSW onto LIBS when it is defined.
- Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS
- instead to not rely as much on tclConfig.sh cached info.
- Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH.
- These move towards making TEA much more independent of *Config.sh.
-
-2002-03-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and
- SHLIB_SUFFIX defines for Win.
- (SC_PATH_X): made this only do the check on unix platforms.
-
-2002-03-12 Jeff Hobbs <jeffh@ActiveState.com>
-
- * README.txt: updated to reflect fewer files
-
-2002-03-06 Jeff Hobbs <jeffh@ActiveState.com>
-
- * config.guess (removed):
- * config.sub (removed): removed unnecessary files
-
- * installFile.tcl (removed):
- * mkinstalldirs (removed): these aren't really necessary for
- making TEA work
-
- * tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't
- check /usr(/local)/include for includes on Windows when not using
- gcc
-
-2002-03-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: added warnings on Windows, removed RELPATH define and
- added TCL_LIBS to MAKE_LIB macro.
-
- This import represents 2.0.0, or a new start at attempting to
- make TEA much easier for C extension developers.
-
- **** moved from tclpro project to core tcl project, ****
- **** renamed to 'tclconfig' ****
-
-2001-03-15 Karl Lehenbauer <karl@procplace.com>
-
- * installFile.tcl: Added updating of the modification time of
- the target file whether we overwrote it or decided that it
- hadn't changed. This was necessary for us to be able to
- determine whether or not a module install touched the file.
-
-2001-03-08 Karl Lehenbauer <karl@procplace.com>
-
- * installFile.tcl: Added support for converting new-style (1.1+)
- Cygnus drive paths to Tcl-style.
-
-2001-01-15 <brent.welch@interwoven.com>
-
- * tcl.m4: Added FreeBSD clause.
-
-2001-01-03 <brent.welch@interwoven.com>
-
- * tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking
- for exec-prefix.
-
-2000-12-01 <brent.welch@interwoven.com>
-
- * tcl.m4: Concatenated most of the Ajuba acsite.m4 file
- so we don't need to modify the autoconf installation.
- * config.guess:
- * config.sub:
- * installFile.tcl:
- Added files from the itcl config subdirectory,
- which should go away.
-
-2000-7-29 <welch@ajubasolutions.com>
-
- * Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within
- TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent
- change from $(srcdir) to $(srcdir)/..
diff --git a/tcl8.6/pkgs/tdbc1.0.6/ChangeLog b/tcl8.6/pkgs/tdbc1.1.0/ChangeLog
index 57bbdc5..57bbdc5 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/ChangeLog
+++ b/tcl8.6/pkgs/tdbc1.1.0/ChangeLog
diff --git a/tcl8.6/pkgs/tdbc1.0.6/Makefile.in b/tcl8.6/pkgs/tdbc1.1.0/Makefile.in
index c66ff8f..501ddad 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/Makefile.in
+++ b/tcl8.6/pkgs/tdbc1.1.0/Makefile.in
@@ -61,7 +61,7 @@ PKG_LIB_FILE = @PKG_LIB_FILE@
PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE)
-BINARIES = $(lib_BINARIES) tdbc.tcl
+BINARIES = $(lib_BINARIES)
SHELL = @SHELL@
@@ -83,10 +83,10 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
-top_builddir = .
+top_builddir = @abs_top_builddir@
INSTALL_OPTIONS =
-INSTALL = @INSTALL@ ${INSTALL_OPTIONS}
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -133,15 +133,15 @@ TCLLIBPATH = $(top_builddir)
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(TCLLIBPATH)" \
- TDBC_LIBRARY=`@CYGPATH@ $(srcdir)/library`
+ TDBC_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+ TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
-#WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
+#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
@@ -168,6 +168,11 @@ AR = @AR@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
.SUFFIXES: .c .$(OBJEXT)
#========================================================================
@@ -238,25 +243,27 @@ install-doc: doc
done
test: binaries libraries
- @$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
- -load "package ifneeded ${PACKAGE_NAME} ${PACKAGE_VERSION} \
- [list source `@CYGPATH@ $(srcdir)/library/tdbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
+ $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
- $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
-VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
- --leak-check=yes --show-reachable=yes -v
+gdb-test: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) \
+ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
+ $(TESTFLAGS) -singleproc 1 \
+ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+ [list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
valgrind: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
- `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
+ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
depend:
@@ -281,13 +288,6 @@ $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
#========================================================================
-# Tcl sources.
-#========================================================================
-
-tdbc.tcl:
- cp $(srcdir)/library/tdbc.tcl .
-
-#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
# In the following lines, $(srcdir) refers to the toplevel directory
@@ -317,32 +317,38 @@ COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
+
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
$(INSTALL_DATA_DIR) $(DIST_DIR)
- cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
- $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
- $(srcdir)/configure.ac $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
-
- for i in $(srcdir)/*.[ch]; do \
- if [ -f $$i ]; then \
- cp -p $$i $(DIST_DIR)/ ; \
- fi; \
- done;
+
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
- cp -p $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
- $(srcdir)/tclconfig/ChangeLog $(srcdir)/tclconfig/README.txt \
- $(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
-
- mkdir $(DIST_DIR)/doc
- cp -p $(srcdir)/doc/tdbc.n $(srcdir)/doc/tdbc_connection.n \
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(srcdir)/tdbcConfig.sh.in \
+ $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/doc
+ $(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc.n \
+ $(srcdir)/doc/tdbc_connection.n \
$(srcdir)/doc/tdbc_resultset.n \
$(srcdir)/doc/tdbc_statement.n \
$(srcdir)/doc/tdbc_mapSqlState.n \
@@ -350,31 +356,31 @@ dist: dist-clean
$(srcdir)/doc/Tdbc_Init.3 \
$(DIST_DIR)/doc/
- mkdir $(DIST_DIR)/generic
- cp -p $(srcdir)/generic/tdbc.c $(srcdir)/generic/tdbc.decls \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/generic
+ $(DIST_INSTALL_DATA) $(srcdir)/generic/tdbc.c $(srcdir)/generic/tdbc.decls \
$(srcdir)/generic/tdbc.h $(srcdir)/generic/tdbcDecls.h \
$(srcdir)/generic/tdbcInt.h $(srcdir)/generic/tdbcStubInit.c \
$(srcdir)/generic/tdbcStubLib.c \
$(srcdir)/generic/tdbcTokenize.c $(DIST_DIR)/generic/
- mkdir $(DIST_DIR)/library
- cp -p $(srcdir)/library/tdbc.tcl $(DIST_DIR)/library/
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/library
+ $(DIST_INSTALL_DATA) $(srcdir)/library/tdbc.tcl $(DIST_DIR)/library/
- mkdir $(DIST_DIR)/tests
- cp -p $(srcdir)/tests/all.tcl \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tests
+ $(DIST_INSTALL_DATA) $(srcdir)/tests/all.tcl \
$(srcdir)/tests/tdbc.test \
$(srcdir)/tests/tokenize.test \
$(DIST_DIR)/tests/
- mkdir $(DIST_DIR)/tools
- cp -p $(srcdir)/tools/genExtStubs.tcl \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tools
+ $(DIST_INSTALL_DATA) $(srcdir)/tools/genExtStubs.tcl \
$(srcdir)/tools/genStubs.tcl \
$(srcdir)/tools/tdbc-man2html.tcl \
$(DIST_DIR)/tools/
- mkdir $(DIST_DIR)/win
- cp -p $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
- $(srcdir)/win/rules-ext.vc $(srcdir)/win/targets.vc \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/win
+ $(DIST_INSTALL_DATA) $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
+ $(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
$(srcdir)/win/rules.vc $(srcdir)/win/tdbc.rc \
$(DIST_DIR)/win/
@@ -424,14 +430,6 @@ install-lib-binaries: binaries
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
- stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
- if test "x$$stub" = "xstub"; then \
- echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
- else \
- echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
- fi; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
@@ -491,6 +489,7 @@ uninstall-binaries:
done
.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb gdb-test valgrind valgrindshell
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tcl8.6/pkgs/tdbc1.0.6/README b/tcl8.6/pkgs/tdbc1.1.0/README
index cd99e42..e561860 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/README
+++ b/tcl8.6/pkgs/tdbc1.1.0/README
@@ -1,6 +1,6 @@
README: tdbc
- This is the 1.0.6 source distribution of Tcl Database Connectivity
+ This is the 1.1.0 source distribution of Tcl Database Connectivity
(TDBC). TDBC is available from a Fossil version control repository
at http://tdbc.tcl.tk/ .
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/aclocal.m4 b/tcl8.6/pkgs/tdbc1.1.0/aclocal.m4
index 83d361c..83d361c 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/aclocal.m4
+++ b/tcl8.6/pkgs/tdbc1.1.0/aclocal.m4
diff --git a/tcl8.6/pkgs/tdbc1.0.6/configure b/tcl8.6/pkgs/tdbc1.1.0/configure
index a791fc3..1333d76 100755
--- a/tcl8.6/pkgs/tdbc1.0.6/configure
+++ b/tcl8.6/pkgs/tdbc1.1.0/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tdbc 1.0.6.
+# Generated by GNU Autoconf 2.69 for tdbc 1.1.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='tdbc'
PACKAGE_TARNAME='tdbc'
-PACKAGE_VERSION='1.0.6'
-PACKAGE_STRING='tdbc 1.0.6'
+PACKAGE_VERSION='1.1.0'
+PACKAGE_STRING='tdbc 1.1.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -661,17 +661,10 @@ 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
TCLOO_VERSION_REQ
TCL_VERSION_DESIRED
@@ -706,6 +699,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1320,7 +1319,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 tdbc 1.0.6 to adapt to many kinds of systems.
+\`configure' configures tdbc 1.1.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1381,7 +1380,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tdbc 1.0.6:";;
+ short | recursive ) echo "Configuration of tdbc 1.1.0:";;
esac
cat <<\_ACEOF
@@ -1484,7 +1483,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tdbc configure 1.0.6
+tdbc configure 1.1.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1758,98 +1757,11 @@ $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 tdbc $as_me 1.0.6, which was
+It was created by tdbc $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2205,26 +2117,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2233,7 +2135,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2325,6 +2227,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2434,6 +2385,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2460,13 +2414,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -3564,6 +3522,7 @@ $as_echo "$as_me: WARNING: --with-tcloo argument should refer to directory conta
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4458,20 +4417,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -5143,470 +5088,11 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
+#-----------------------------------------------------------------------
+# Setup inlining if available.
+#-----------------------------------------------------------------------
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
@@ -5652,6 +5138,7 @@ esac
#-----------------------------------------------------------------------
+# __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,
@@ -5769,6 +5256,7 @@ fi
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -5779,9 +5267,21 @@ fi
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
-CLEANFILES="$CLEANFILES tdbc.tcl"
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -5873,6 +5373,11 @@ $as_echo "${ac_cv_c_tclh}" >&6; }
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -7578,7 +7083,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8212,9 +7717,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -8829,17 +8334,6 @@ $as_echo "enabled $tcl_ok debugging" >&6; }
#--------------------------------------------------------------------
-# 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
-
-
-#--------------------------------------------------------------------
# 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.
@@ -8996,11 +8490,12 @@ $as_echo_n "checking for tclsh... " >&6; }
$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.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
# Develop a fully qualified path for the package source dir
@@ -9609,7 +9104,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 tdbc $as_me 1.0.6, which was
+This file was extended by tdbc $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9662,7 +9157,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="\\
-tdbc config.status 1.0.6
+tdbc config.status 1.1.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/tdbc1.0.6/configure.ac b/tcl8.6/pkgs/tdbc1.1.0/configure.ac
index e411c4c..d1a8517 100755..100644
--- a/tcl8.6/pkgs/tdbc1.0.6/configure.ac
+++ b/tcl8.6/pkgs/tdbc1.1.0/configure.ac
@@ -4,14 +4,22 @@ dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
+# Sample configure.ac for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
#-----------------------------------------------------------------------
-AC_INIT([tdbc], [1.0.6])
+AC_INIT([tdbc], [1.1.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -19,7 +27,7 @@ AC_INIT([tdbc], [1.0.6])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
@@ -78,9 +86,15 @@ TEA_PREFIX
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# Setup inlining if available.
+#-----------------------------------------------------------------------
+
AC_C_INLINE
#-----------------------------------------------------------------------
+# __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,
@@ -102,6 +116,7 @@ TEA_ADD_STUB_SOURCES([tdbcStubLib.c])
TEA_ADD_TCL_SOURCES([library/tdbc.tcl])
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -112,9 +127,21 @@ TEA_ADD_TCL_SOURCES([library/tdbc.tcl])
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
-CLEANFILES="$CLEANFILES tdbc.tcl"
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -123,6 +150,11 @@ CLEANFILES="$CLEANFILES tdbc.tcl"
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -153,15 +185,6 @@ TEA_CONFIG_CFLAGS
TEA_ENABLE_SYMBOLS
#--------------------------------------------------------------------
-# Everyone should be linking against the Tcl stub library. If you
-# can't for some reason, remove this definition. If you aren't using
-# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
-# link against the non-stubbed Tcl library. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
-
-#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
@@ -178,11 +201,12 @@ TEA_MAKE_LIB
#--------------------------------------------------------------------
TEA_PROG_TCLSH
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
-# which require substituting th AC variables in. Include these here.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
# Develop a fully qualified path for the package source dir
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/Tdbc_Init.3 b/tcl8.6/pkgs/tdbc1.1.0/doc/Tdbc_Init.3
index 1409607..1409607 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/Tdbc_Init.3
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/Tdbc_Init.3
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc.n
index d486c3c..d486c3c 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_connection.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_connection.n
index f02f3ea..f02f3ea 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_connection.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_connection.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_mapSqlState.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_mapSqlState.n
index 16ec071..16ec071 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_mapSqlState.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_mapSqlState.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_resultset.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_resultset.n
index 5cd96a8..5cd96a8 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_resultset.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_resultset.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_statement.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_statement.n
index 501a54a..501a54a 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_statement.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_statement.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_tokenize.n b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_tokenize.n
index 030f0f9..030f0f9 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/doc/tdbc_tokenize.n
+++ b/tcl8.6/pkgs/tdbc1.1.0/doc/tdbc_tokenize.n
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.c b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.c
index 237cb33..237cb33 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.c
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.c
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.decls b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.decls
index 68645a1..68645a1 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.decls
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.decls
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.h b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.h
index 9e52f32..4f2c2ac 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbc.h
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbc.h
@@ -59,8 +59,8 @@ DLLIMPORT int Tdbc_Init(Tcl_Interp* interp);
* appear near the top of configure.ac.
*/
-#define TDBC_VERSION "1.0.6"
-#define TDBC_PATCHLEVEL "1.0.6"
+#define TDBC_VERSION "1.1.0"
+#define TDBC_PATCHLEVEL "1.1.0"
/*
* Include the Stubs declarations for the public API, generated from
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcDecls.h b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcDecls.h
index 24e4548..24e4548 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcDecls.h
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcDecls.h
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcInt.h b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcInt.h
index 755cb96..755cb96 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcInt.h
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcInt.h
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubInit.c b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubInit.c
index c63cd8e..c63cd8e 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubInit.c
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubInit.c
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubLib.c b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubLib.c
index babda72..babda72 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcStubLib.c
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcStubLib.c
diff --git a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcTokenize.c b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcTokenize.c
index 19e113a..19e113a 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/generic/tdbcTokenize.c
+++ b/tcl8.6/pkgs/tdbc1.1.0/generic/tdbcTokenize.c
diff --git a/tcl8.6/pkgs/tdbc1.0.6/library/tdbc.tcl b/tcl8.6/pkgs/tdbc1.1.0/library/tdbc.tcl
index 2a167cb..2a167cb 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/library/tdbc.tcl
+++ b/tcl8.6/pkgs/tdbc1.1.0/library/tdbc.tcl
diff --git a/tcl8.6/pkgs/tdbc1.0.6/license.terms b/tcl8.6/pkgs/tdbc1.1.0/license.terms
index 06b1977..06b1977 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/license.terms
+++ b/tcl8.6/pkgs/tdbc1.1.0/license.terms
diff --git a/tcl8.6/pkgs/tdbc1.1.0/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbc1.1.0/pkgIndex.tcl.in
new file mode 100644
index 0000000..379635b
--- /dev/null
+++ b/tcl8.6/pkgs/tdbc1.1.0/pkgIndex.tcl.in
@@ -0,0 +1,18 @@
+# Index file to load the TDBC package.
+
+# Make sure that TDBC is running in a compatible version of Tcl, and
+# that TclOO is available.
+
+if {[catch {package present Tcl @TCL_VERSION_REQ@}]} {
+ return
+}
+apply {{dir} {
+ set libraryfile [file join $dir @PACKAGE_NAME@.tcl]
+ if {![file exists $libraryfile] && [info exists ::env(TDBC_LIBRARY)]} {
+ set libraryfile [file join $::env(TDBC_LIBRARY) @PACKAGE_NAME@.tcl]
+ }
+ package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \
+ "package require TclOO @TCLOO_VERSION_REQ@-;\
+ [list load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@]\;\
+ [list source $libraryfile]"
+}} $dir
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/README.txt b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/README.txt
index 59b5a3e..59b5a3e 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/README.txt
+++ b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/README.txt
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/install-sh b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/install-sh
index 7c34c3f..7c34c3f 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/install-sh
+++ b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/tcl.m4
index e8234a2..2ec82a2 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/tcl.m4
+++ b/tcl8.6/pkgs/tdbc1.1.0/tclconfig/tcl.m4
@@ -11,10 +11,6 @@
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.10"
-
# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
@@ -109,6 +105,9 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -135,13 +134,17 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -265,6 +268,9 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tk.framework/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
@@ -280,8 +286,15 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
; do
if test -f "$i/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i; pwd)`"
@@ -1693,7 +1706,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LDFLAGS="$LDFLAGS -pthread"
])
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -2053,9 +2066,9 @@ dnl # preprocessing tests use only CPPFLAGS.
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -2305,96 +2318,6 @@ int main() {
])
#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
# TEA_PATH_X
#
# Locate the X11 header files and the X11 library archive. Try
@@ -2649,92 +2572,6 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
])
#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
# TEA_TCL_EARLY_FLAGS
#
# Check for what flags are needed to be passed so the correct OS
@@ -2895,23 +2732,14 @@ 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.10"
+ TEA_VERSION="3.13"
- AC_MSG_CHECKING([for correct TEA configuration])
+ AC_MSG_CHECKING([TEA configuration])
if test x"${PACKAGE_NAME}" = x ; then
AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.ac])
fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
# 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".
@@ -2920,7 +2748,7 @@ TEA version not specified.])
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
EXEEXT=".exe"
TEA_PLATFORM="windows"
@@ -2973,6 +2801,9 @@ TEA version not specified.])
AC_SUBST(PKG_INCLUDES)
AC_SUBST(PKG_LIBS)
AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
])
#------------------------------------------------------------------------
@@ -3264,20 +3095,6 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
AC_PROG_CC
AC_PROG_CPP
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -3336,14 +3153,6 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
#--------------------------------------------------------------------
AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
])
#------------------------------------------------------------------------
@@ -3989,6 +3798,7 @@ AC_DEFUN([TEA_PATH_CONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4223,6 +4033,45 @@ AC_DEFUN([TEA_PATH_CELIB], [
fi
])
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
###
# Tip 430 - ZipFS Modifications
###
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tdbcConfig.sh.in b/tcl8.6/pkgs/tdbc1.1.0/tdbcConfig.sh.in
index 7e74bfe..7e74bfe 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tdbcConfig.sh.in
+++ b/tcl8.6/pkgs/tdbc1.1.0/tdbcConfig.sh.in
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tests/all.tcl b/tcl8.6/pkgs/tdbc1.1.0/tests/all.tcl
index 314d64c..314d64c 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tests/all.tcl
+++ b/tcl8.6/pkgs/tdbc1.1.0/tests/all.tcl
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tests/tdbc.test b/tcl8.6/pkgs/tdbc1.1.0/tests/tdbc.test
index ffbfb76..ffbfb76 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tests/tdbc.test
+++ b/tcl8.6/pkgs/tdbc1.1.0/tests/tdbc.test
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tests/tokenize.test b/tcl8.6/pkgs/tdbc1.1.0/tests/tokenize.test
index 54ee615..54ee615 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tests/tokenize.test
+++ b/tcl8.6/pkgs/tdbc1.1.0/tests/tokenize.test
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tools/genExtStubs.tcl b/tcl8.6/pkgs/tdbc1.1.0/tools/genExtStubs.tcl
index 67ead5d..67ead5d 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tools/genExtStubs.tcl
+++ b/tcl8.6/pkgs/tdbc1.1.0/tools/genExtStubs.tcl
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tools/genStubs.tcl b/tcl8.6/pkgs/tdbc1.1.0/tools/genStubs.tcl
index 5aa5ecf..5aa5ecf 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tools/genStubs.tcl
+++ b/tcl8.6/pkgs/tdbc1.1.0/tools/genStubs.tcl
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tools/tdbc-man2html.tcl b/tcl8.6/pkgs/tdbc1.1.0/tools/tdbc-man2html.tcl
index e63c93c..e63c93c 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tools/tdbc-man2html.tcl
+++ b/tcl8.6/pkgs/tdbc1.1.0/tools/tdbc-man2html.tcl
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/makefile.vc b/tcl8.6/pkgs/tdbc1.1.0/win/makefile.vc
index efb5c30..c2a31ac 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/makefile.vc
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/makefile.vc
@@ -1,103 +1,103 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for TBDC Core
-#
-# Basic build, test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = tdbc
-RCFILE = tdbc.rc
-# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
-# without -DUNICODE using explicit W suffixes on wide character calls.
-# Keep that behaviour for now.
-USE_WIDECHAR_API = 0
-
-!include "rules-ext.vc"
-
-!if [echo REM = This file is generated from Makefile.vc > versions.vc]
-!endif
-!if [echo TCL_VERSION_REQ = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
-!endif
-!if [echo TCL_VERSION_DESIRED = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCL_VERSION_DESIRED >> versions.vc]
-!endif
-!if [echo TCLOO_VERSION_REQ = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCLOO_VERSION_REQ >> versions.vc]
-!endif
-
-!include "versions.vc"
-
-PRJ_OBJS = \
- $(TMP_DIR)\tdbc.obj \
- $(TMP_DIR)\tdbcStubInit.obj \
- $(TMP_DIR)\tdbcTokenize.obj
-
-PRJ_STUBOBJS = \
- $(TMP_DIR)\tdbcStubLib.obj
-
-PRJ_HEADERS_PUBLIC = \
- $(GENERICDIR)\tdbc.h \
- $(GENERICDIR)\tdbcDecls.h
-
-PRJ_HEADERS = \
- $(PRJ_HEADERS_PUBLIC) \
- $(GENERICDIR)\tdbcInt.h
-
-# Define the standard targets including install, test, shell
-!include "$(_RULESDIR)\targets.vc"
-
-# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
-# all replacements below so define our own it.
-pkgindex: $(OUT_DIR)\pkgIndex.tcl
-$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
- @nmakehlp -s << $** > $@
-@PACKAGE_NAME@ $(PROJECT)
-@PACKAGE_VERSION@ $(DOTVERSION)
-@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
-@TCL_VERSION_DESIRED@ $(TCL_VERSION_DESIRED)
-@TCLOO_VERSION_REQ@ $(TCLOO_VERSION_REQ)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-@TCL_VERSION@ $(TCL_DOTVERSION)
-<<
-
-.PHONY: $(OUT_DIR)\tdbcConfig.sh
-
-# TBD - this (meaning using nmake builds for autoconf) does not really work
-# and never has. Perhaps it should be removed.
-$(OUT_DIR)\tdbcConfig.sh: $(ROOT)\tdbcConfig.sh.in
- nmakehlp -s << $** > $@
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-@tdbc_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PRJLIBNAME)
-@PKG_STUB_LIB_FILE@ $(PRJSTUBLIBNAME)
-@tdbc_BUILD_STUB_LIB_SPEC@ $(PRJSTUBLIB)
-@tdbc_STUB_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PRJSTUBLIBNAME)
-@tdbc_BUILD_STUB_LIB_PATH@ $(PRJSTUBLIB)
-@tdbc_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(PRJSTUBLIBNAME)
-@tdbc_SRC_DIR@ $(ROOT)
-@tdbc_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR)
-@tdbc_BUILD_INCLUDE_SPEC@ -I$(GENERICDIR)
-@tdbc_LIB_DIR@ $(LIB_INSTALL_DIR)
-<<
-
-# TDBC has additional installation in addition to that provided by
-# the default installation targets.
-install: default-install-docs-n
-default-install-libraries: install-tdbc-extras
-
-install-tdbc-extras: $(OUT_DIR)\tdbcConfig.sh
- @$(CPY) $(OUT_DIR)\tdbcConfig.sh "$(LIB_INSTALL_DIR)"
-
-
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for TBDC Core
+#
+# Basic build, test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = tdbc
+RCFILE = tdbc.rc
+# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
+# without -DUNICODE using explicit W suffixes on wide character calls.
+# Keep that behaviour for now.
+USE_WIDECHAR_API = 0
+
+!include "rules-ext.vc"
+
+!if [echo REM = This file is generated from Makefile.vc > versions.vc]
+!endif
+!if [echo TCL_VERSION_REQ = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
+!endif
+!if [echo TCL_VERSION_DESIRED = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCL_VERSION_DESIRED >> versions.vc]
+!endif
+!if [echo TCLOO_VERSION_REQ = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCLOO_VERSION_REQ >> versions.vc]
+!endif
+
+!include "versions.vc"
+
+PRJ_OBJS = \
+ $(TMP_DIR)\tdbc.obj \
+ $(TMP_DIR)\tdbcStubInit.obj \
+ $(TMP_DIR)\tdbcTokenize.obj
+
+PRJ_STUBOBJS = \
+ $(TMP_DIR)\tdbcStubLib.obj
+
+PRJ_HEADERS_PUBLIC = \
+ $(GENERICDIR)\tdbc.h \
+ $(GENERICDIR)\tdbcDecls.h
+
+PRJ_HEADERS = \
+ $(PRJ_HEADERS_PUBLIC) \
+ $(GENERICDIR)\tdbcInt.h
+
+# Define the standard targets including install, test, shell
+!include "$(_RULESDIR)\targets.vc"
+
+# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
+# all replacements below so define our own it.
+pkgindex: $(OUT_DIR)\pkgIndex.tcl
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+ @nmakehlp -s << $** > $@
+@PACKAGE_NAME@ $(PROJECT)
+@PACKAGE_VERSION@ $(DOTVERSION)
+@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
+@TCL_VERSION_DESIRED@ $(TCL_VERSION_DESIRED)
+@TCLOO_VERSION_REQ@ $(TCLOO_VERSION_REQ)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+@TCL_VERSION@ $(TCL_DOTVERSION)
+<<
+
+.PHONY: $(OUT_DIR)\tdbcConfig.sh
+
+# TBD - this (meaning using nmake builds for autoconf) does not really work
+# and never has. Perhaps it should be removed.
+$(OUT_DIR)\tdbcConfig.sh: $(ROOT)\tdbcConfig.sh.in
+ nmakehlp -s << $** > $@
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+@tdbc_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PRJLIBNAME)
+@PKG_STUB_LIB_FILE@ $(PRJSTUBLIBNAME)
+@tdbc_BUILD_STUB_LIB_SPEC@ $(PRJSTUBLIB)
+@tdbc_STUB_LIB_SPEC@ $(LIB_INSTALL_DIR)\$(PRJSTUBLIBNAME)
+@tdbc_BUILD_STUB_LIB_PATH@ $(PRJSTUBLIB)
+@tdbc_STUB_LIB_PATH@ $(LIB_INSTALL_DIR)\$(PRJSTUBLIBNAME)
+@tdbc_SRC_DIR@ $(ROOT)
+@tdbc_INCLUDE_SPEC@ -I$(INCLUDE_INSTALL_DIR)
+@tdbc_BUILD_INCLUDE_SPEC@ -I$(GENERICDIR)
+@tdbc_LIB_DIR@ $(LIB_INSTALL_DIR)
+<<
+
+# TDBC has additional installation in addition to that provided by
+# the default installation targets.
+install: default-install-docs-n
+default-install-libraries: install-tdbc-extras
+
+install-tdbc-extras: $(OUT_DIR)\tdbcConfig.sh
+ @$(CPY) $(OUT_DIR)\tdbcConfig.sh "$(LIB_INSTALL_DIR)"
+
+
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/nmakehlp.c b/tcl8.6/pkgs/tdbc1.1.0/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/nmakehlp.c
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/sqlite3.21.0/win/rules-ext.vc b/tcl8.6/pkgs/tdbc1.1.0/win/rules-ext.vc
index 58c70fa..58c70fa 100644
--- a/tcl8.6/pkgs/sqlite3.21.0/win/rules-ext.vc
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/rules-ext.vc
diff --git a/tcl8.6/pkgs/thread2.8.2/win/rules.vc b/tcl8.6/pkgs/tdbc1.1.0/win/rules.vc
index 7fc51c1..7fc51c1 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/rules.vc
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/rules.vc
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/targets.vc b/tcl8.6/pkgs/tdbc1.1.0/win/targets.vc
index 312022d..7f1d388 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/targets.vc
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/targets.vc
@@ -1,98 +1,98 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/tdbc.rc b/tcl8.6/pkgs/tdbc1.1.0/win/tdbc.rc
index 2f014e4..2f014e4 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/tdbc.rc
+++ b/tcl8.6/pkgs/tdbc1.1.0/win/tdbc.rc
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/ChangeLog b/tcl8.6/pkgs/tdbcmysql1.1.0/ChangeLog
index b0c5b96..b0c5b96 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/ChangeLog
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/ChangeLog
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/Makefile.in b/tcl8.6/pkgs/tdbcmysql1.1.0/Makefile.in
index 4c6bd47..4f22053 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/Makefile.in
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/Makefile.in
@@ -13,6 +13,13 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
+
+#========================================================================
# Nothing of the variables below this line should need to be changed.
# Please check the TARGETS section below to make sure the make targets
# are correct.
@@ -29,6 +36,9 @@
PKG_SOURCES = @PKG_SOURCES@
PKG_OBJECTS = @PKG_OBJECTS@
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
#========================================================================
# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
@@ -48,6 +58,7 @@ PKG_HEADERS = @PKG_HEADERS@
#========================================================================
PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE)
BINARIES = $(lib_BINARIES)
@@ -72,10 +83,10 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
-top_builddir = .
+top_builddir = @abs_top_builddir@
INSTALL_OPTIONS =
-INSTALL = @INSTALL@ ${INSTALL_OPTIONS}
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -123,20 +134,20 @@ TDBC_LIB_FILE = @TDBC_LIB_FILE@
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
-TCLLIBPATH = $(top_builddir)
-TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
- TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@`
+TCLLIBPATH = $(top_builddir) $(TDBC_BIN_DIR)
+TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(TCLLIBPATH)" \
- TDBCMYSQL_LIBRARY=`@CYGPATH@ $(srcdir)/library`
+ TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` \
+ TDBCMYSQL_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+ TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
-#WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
+#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
@@ -163,6 +174,11 @@ AR = @AR@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
.SUFFIXES: .c .$(OBJEXT)
#========================================================================
@@ -231,25 +247,27 @@ install-doc: doc
test: binaries libraries
@$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::mysql $(PACKAGE_VERSION) \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcmysql.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcmysql.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
- $(TCLSH_ENV) $(PKG_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
-VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
- --leak-check=yes --show-reachable=yes -v
+gdb-test: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) \
+ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
+ $(TESTFLAGS) -singleproc 1 \
+ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+ [list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
valgrind: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
- `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
+ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
- $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
depend:
@@ -268,6 +286,11 @@ $(PKG_LIB_FILE): $(PKG_OBJECTS)
${MAKE_LIB}
$(RANLIB) $(PKG_LIB_FILE)
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+ -rm -f $(PKG_STUB_LIB_FILE)
+ ${MAKE_STUB_LIB}
+ $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
@@ -298,34 +321,40 @@ COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
+
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
$(INSTALL_DATA_DIR) $(DIST_DIR)
- cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
- $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
- $(srcdir)/configure.ac $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
-
- for i in $(srcdir)/*.[ch]; do \
- if [ -f $$i ]; then \
- cp -p $$i $(DIST_DIR)/ ; \
- fi; \
- done;
- $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
- cp -p $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
- $(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
- mkdir $(DIST_DIR)/doc
- cp -p $(srcdir)/doc/tdbc_mysql.n $(DIST_DIR)/doc/
-
- mkdir $(DIST_DIR)/generic
- cp -p $(srcdir)/generic/fakemysql.h \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/doc
+ $(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc_mysql.n $(DIST_DIR)/doc/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/generic
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/generic/fakemysql.h \
$(srcdir)/generic/mysqlStubDefs.txt \
$(srcdir)/generic/mysqlStubInit.c \
$(srcdir)/generic/mysqlStubs.h \
@@ -333,15 +362,15 @@ dist: dist-clean
$(srcdir)/generic/int2ptr_ptr2int.h \
$(DIST_DIR)/generic/
- mkdir $(DIST_DIR)/library
- cp -p $(srcdir)/library/tdbcmysql.tcl $(DIST_DIR)/library/
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/library
+ $(DIST_INSTALL_DATA) $(srcdir)/library/tdbcmysql.tcl $(DIST_DIR)/library/
- mkdir $(DIST_DIR)/tests
- cp -p $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcmysql.test \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tests
+ $(DIST_INSTALL_DATA) $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcmysql.test \
$(DIST_DIR)/tests/
- mkdir $(DIST_DIR)/win
- cp -p $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/win
+ $(DIST_INSTALL_DATA) $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
$(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
$(srcdir)/win/rules.vc $(DIST_DIR)/win/
@@ -397,14 +426,6 @@ install-lib-binaries: binaries
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
- stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
- if test "x$$stub" = "xstub"; then \
- echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
- else \
- echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
- fi; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
@@ -462,6 +483,7 @@ uninstall-binaries:
done
.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb gdb-test valgrind valgrindshell
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/README b/tcl8.6/pkgs/tdbcmysql1.1.0/README
index 22d216d..31b81b9 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/README
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/README
@@ -1,6 +1,6 @@
README: tdbcmysql
- This is the 1.0.6 source distribution of the driver for Tcl
+ This is the 1.1.0 source distribution of the driver for Tcl
Database Connectivity (TDBC) to access MySQL databases.. TDBC and
its drivers are available from a Fossil version control repository
at http://tdbc.tcl.tk/
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/aclocal.m4 b/tcl8.6/pkgs/tdbcmysql1.1.0/aclocal.m4
index 83d361c..83d361c 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/aclocal.m4
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/aclocal.m4
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/configure b/tcl8.6/pkgs/tdbcmysql1.1.0/configure
index e5b5dab..ffb4644 100755
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/configure
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tdbcodbc 1.0.6.
+# Generated by GNU Autoconf 2.69 for tdbcmysql 1.1.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -575,10 +575,10 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME='tdbcodbc'
-PACKAGE_TARNAME='tdbcodbc'
-PACKAGE_VERSION='1.0.6'
-PACKAGE_STRING='tdbcodbc 1.0.6'
+PACKAGE_NAME='tdbcmysql'
+PACKAGE_TARNAME='tdbcmysql'
+PACKAGE_VERSION='1.1.0'
+PACKAGE_STRING='tdbcmysql 1.1.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -648,17 +648,10 @@ 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
TDBC_LIB_FILE
TDBC_VERSION
@@ -694,6 +687,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1308,7 +1307,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 tdbcodbc 1.0.6 to adapt to many kinds of systems.
+\`configure' configures tdbcmysql 1.1.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1356,7 +1355,7 @@ Fine tuning of the installation directories:
--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/tdbcodbc]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/tdbcmysql]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1369,7 +1368,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tdbcodbc 1.0.6:";;
+ short | recursive ) echo "Configuration of tdbcmysql 1.1.0:";;
esac
cat <<\_ACEOF
@@ -1472,7 +1471,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tdbcodbc configure 1.0.6
+tdbcmysql configure 1.1.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1634,206 +1633,6 @@ $as_echo "$ac_res" >&6; }
} # 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
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2070,11 +1869,124 @@ rm -f conftest.val
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
+
+# 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
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 tdbcodbc $as_me 1.0.6, which was
+It was created by tdbcmysql $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2430,26 +2342,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2458,7 +2360,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2550,6 +2452,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2659,6 +2610,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2685,13 +2639,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -3792,6 +3750,7 @@ $as_echo "$as_me: WARNING: --with-tdbc argument should refer to directory contai
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4692,20 +4651,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -5377,470 +5322,11 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long, long.
+#-----------------------------------------------------------------------
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
@@ -5958,10 +5444,9 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-$as_echo "#define DONT_TD_VOID 1" >>confdefs.h
-
#-----------------------------------------------------------------------
+# __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,
@@ -5971,7 +5456,7 @@ $as_echo "#define DONT_TD_VOID 1" >>confdefs.h
#-----------------------------------------------------------------------
- vars="generic/tdbcodbc.c generic/odbcStubInit.c"
+ vars="generic/tdbcmysql.c generic/mysqlStubInit.c"
for i in $vars; do
case $i in
\$*)
@@ -6006,7 +5491,7 @@ $as_echo "#define DONT_TD_VOID 1" >>confdefs.h
- vars="generic/fakesql.h generic/odbcStubs.h"
+ vars="generic/fakemysql.h generic/mysqlStubs.h"
for i in $vars; do
# check for existence, be strict because it is installed
if test ! -f "${srcdir}/$i" ; then
@@ -6103,7 +5588,7 @@ fi
- vars="library/tdbcodbc.tcl"
+ vars="library/tdbcmysql.tcl"
for i in $vars; do
# check for existence, be strict because it is installed
if test ! -f "${srcdir}/$i" ; then
@@ -6115,16 +5600,7 @@ fi
#--------------------------------------------------------------------
-# The new loader needs to know the shared lib suffix.
-#--------------------------------------------------------------------
-
-
-cat >>confdefs.h <<_ACEOF
-#define TCL_SHLIB_EXT "${TCL_SHLIB_SUFFIX}"
-_ACEOF
-
-
-#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -6136,8 +5612,20 @@ _ACEOF
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -6229,6 +5717,11 @@ $as_echo "${ac_cv_c_tclh}" >&6; }
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -7934,7 +7427,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8568,9 +8061,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -9263,113 +8756,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. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-
-$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
-
-
-#--------------------------------------------------------------------
-# Locate the ws2_32 library; we need it for ntohs and friends
-#--------------------------------------------------------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lws2_32" >&5
-$as_echo_n "checking for main in -lws2_32... " >&6; }
-if ${ac_cv_lib_ws2_32_main+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lws2_32 $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_ws2_32_main=yes
-else
- ac_cv_lib_ws2_32_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_ws2_32_main" >&5
-$as_echo "$ac_cv_lib_ws2_32_main" >&6; }
-if test "x$ac_cv_lib_ws2_32_main" = xyes; then :
-
- vars="-lws2_32"
- 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
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lwinsock" >&5
-$as_echo_n "checking for main in -lwinsock... " >&6; }
-if ${ac_cv_lib_winsock_main+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lwinsock $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_winsock_main=yes
-else
- ac_cv_lib_winsock_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_winsock_main" >&5
-$as_echo "$ac_cv_lib_winsock_main" >&6; }
-if test "x$ac_cv_lib_winsock_main" = xyes; then :
-
- vars="-lwinsock"
- 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
-
-
-fi
-
-
-fi
-
-
-#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
@@ -9526,11 +8912,12 @@ $as_echo_n "checking for tclsh... " >&6; }
$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.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
@@ -10079,7 +9466,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 tdbcodbc $as_me 1.0.6, which was
+This file was extended by tdbcmysql $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -10132,7 +9519,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="\\
-tdbcodbc config.status 1.0.6
+tdbcmysql config.status 1.1.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/configure.ac b/tcl8.6/pkgs/tdbcmysql1.1.0/configure.ac
index f405030..81a533f 100755..100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/configure.ac
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/configure.ac
@@ -4,14 +4,22 @@ dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
+# Sample configure.ac for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
#-----------------------------------------------------------------------
-AC_INIT([tdbcmysql], [1.0.6])
+AC_INIT([tdbcmysql], [1.1.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -19,7 +27,7 @@ AC_INIT([tdbcmysql], [1.0.6])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
@@ -85,15 +93,20 @@ TEA_PREFIX
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long, long.
+#-----------------------------------------------------------------------
+
AC_C_INLINE
AC_CHECK_TYPE([long long],[
AC_DEFINE([HAVE_LONG_LONG],[1])
AC_CHECK_SIZEOF([long long])
],[],[])
AC_CHECK_SIZEOF([long])
-AC_DEFINE([DONT_TD_VOID],[1])
#-----------------------------------------------------------------------
+# __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,
@@ -122,6 +135,7 @@ TEA_ADD_STUB_SOURCES()
TEA_ADD_TCL_SOURCES([library/tdbcmysql.tcl])
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -133,8 +147,20 @@ TEA_ADD_TCL_SOURCES([library/tdbcmysql.tcl])
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -143,6 +169,11 @@ TEA_ADD_TCL_SOURCES([library/tdbcmysql.tcl])
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -180,15 +211,6 @@ AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_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. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
-
-#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
@@ -205,11 +227,12 @@ TEA_MAKE_LIB
#--------------------------------------------------------------------
TEA_PROG_TCLSH
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
-# which require substituting th AC variables in. Include these here.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/doc/tdbc_mysql.n b/tcl8.6/pkgs/tdbcmysql1.1.0/doc/tdbc_mysql.n
index 6cd86d6..6cd86d6 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/doc/tdbc_mysql.n
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/doc/tdbc_mysql.n
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/fakemysql.h b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/fakemysql.h
index 19dc40e..19dc40e 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/fakemysql.h
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/fakemysql.h
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/int2ptr_ptr2int.h b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/int2ptr_ptr2int.h
index 4b0a15d..4b0a15d 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/int2ptr_ptr2int.h
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/int2ptr_ptr2int.h
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubDefs.txt b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubDefs.txt
index 27b37e9..27b37e9 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubDefs.txt
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubDefs.txt
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubInit.c b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubInit.c
index e9e5b61..e9e5b61 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubInit.c
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubInit.c
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubs.h b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubs.h
index 8a1596d..8a1596d 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/mysqlStubs.h
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/mysqlStubs.h
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/tdbcmysql.c b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/tdbcmysql.c
index 5bcebfb..5bcebfb 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/tdbcmysql.c
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/generic/tdbcmysql.c
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/library/tdbcmysql.tcl b/tcl8.6/pkgs/tdbcmysql1.1.0/library/tdbcmysql.tcl
index caa334c..caa334c 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/library/tdbcmysql.tcl
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/library/tdbcmysql.tcl
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/license.terms b/tcl8.6/pkgs/tdbcmysql1.1.0/license.terms
index 6f644fd..6f644fd 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/license.terms
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/license.terms
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbcmysql1.1.0/pkgIndex.tcl.in
index fa95064..3365c76 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/pkgIndex.tcl.in
@@ -1,4 +1,4 @@
-# Package index file for tdbc::mysql
+# Index file to load the TDBC MySQL package.
if {[catch {package require Tcl @TCL_VERSION_REQ@}]} {
return
diff --git a/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/README.txt b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension. For more information on TEA see:
+
+ http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+ http://tcl.sourceforge.net/
+
+This package is a freely available open source package. You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt This file
+
+install-sh Program used for copying binaries and script files
+ to their install locations.
+
+tcl.m4 Collection of Tcl autoconf macros. Included by a package's
+ aclocal.m4 to define TEA_* macros.
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/install-sh b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/tclconfig/install-sh
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/itcl4.1.1/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/tcl.m4
index e8234a2..2ec82a2 100644
--- a/tcl8.6/pkgs/itcl4.1.1/tclconfig/tcl.m4
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/tclconfig/tcl.m4
@@ -11,10 +11,6 @@
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.10"
-
# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
@@ -109,6 +105,9 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -135,13 +134,17 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -265,6 +268,9 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tk.framework/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
@@ -280,8 +286,15 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
; do
if test -f "$i/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i; pwd)`"
@@ -1693,7 +1706,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LDFLAGS="$LDFLAGS -pthread"
])
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -2053,9 +2066,9 @@ dnl # preprocessing tests use only CPPFLAGS.
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -2305,96 +2318,6 @@ int main() {
])
#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
# TEA_PATH_X
#
# Locate the X11 header files and the X11 library archive. Try
@@ -2649,92 +2572,6 @@ AC_DEFUN([TEA_BUGGY_STRTOD], [
])
#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
# TEA_TCL_EARLY_FLAGS
#
# Check for what flags are needed to be passed so the correct OS
@@ -2895,23 +2732,14 @@ 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.10"
+ TEA_VERSION="3.13"
- AC_MSG_CHECKING([for correct TEA configuration])
+ AC_MSG_CHECKING([TEA configuration])
if test x"${PACKAGE_NAME}" = x ; then
AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.ac])
fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
# 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".
@@ -2920,7 +2748,7 @@ TEA version not specified.])
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
EXEEXT=".exe"
TEA_PLATFORM="windows"
@@ -2973,6 +2801,9 @@ TEA version not specified.])
AC_SUBST(PKG_INCLUDES)
AC_SUBST(PKG_LIBS)
AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
])
#------------------------------------------------------------------------
@@ -3264,20 +3095,6 @@ AC_DEFUN([TEA_SETUP_COMPILER_CC], [
AC_PROG_CC
AC_PROG_CPP
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -3336,14 +3153,6 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
#--------------------------------------------------------------------
AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
])
#------------------------------------------------------------------------
@@ -3989,6 +3798,7 @@ AC_DEFUN([TEA_PATH_CONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4223,6 +4033,45 @@ AC_DEFUN([TEA_PATH_CELIB], [
fi
])
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
###
# Tip 430 - ZipFS Modifications
###
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/all.tcl b/tcl8.6/pkgs/tdbcmysql1.1.0/tests/all.tcl
index b3b13a6..b3b13a6 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/all.tcl
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/tests/all.tcl
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/tests/tdbcmysql.test b/tcl8.6/pkgs/tdbcmysql1.1.0/tests/tdbcmysql.test
index faebddc..faebddc 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/tests/tdbcmysql.test
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/tests/tdbcmysql.test
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/win/makefile.vc b/tcl8.6/pkgs/tdbcmysql1.1.0/win/makefile.vc
index 691d627..b68df3c 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/win/makefile.vc
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/win/makefile.vc
@@ -1,111 +1,111 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for TBDC MySQL interface
-#
-# Basic build, test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir test
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = tdbcmysql
-# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
-# without -DUNICODE. Keep that behaviour for now. TBD
-USE_WIDECHAR_API = 0
-
-!include "rules-ext.vc"
-
-# nmakehelp -V <file> <tag> will search the file for tag, skips until a
-# number and returns all character until a character not in [0-9.ab]
-# is read.
-!if [echo REM = This file is generated from Makefile.vc > versions.vc]
-!endif
-!if [echo TCL_VERSION_REQ = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
-!endif
-!include "versions.vc"
-
-PRJ_OBJS = \
- $(TMP_DIR)\tdbcmysql.obj \
- $(TMP_DIR)\mysqlStubInit.obj
-
-# Uncomment the following line if you want to build and install stubs
-# PRJ_STUBOBJS = $(TMP_DIR)\mysqlStubInit.obj
-
-PRJ_HEADERS = \
- $(GENERICDIR)\fakemysql.h \
- $(GENERICDIR)\mysqlStubs.h
-
-# Locate TDBC headers and libraries.
-# In principle, we don't need the TDBC source directory, and an installed
-# TDBC should suffice. But that needs additional machinery not implemented
-# yet.
-!if [echo TDBC_DIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
-!error Could not locate TDBC source directory.
-!endif
-!include nmakehlp.out
-
-# Get the TDBC version from its configure.ac
-!if [echo TDBC_DOTVERSION = \> versions.vc] \
- && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
-!error Could not retrieve TDBC version.
-!endif
-!include versions.vc
-
-TDBC_VERSION = $(TDBC_DOTVERSION:.=)
-TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
-TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
-TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
-TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
-TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
-
-PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
-
-!if !$(STATIC_BUILD)
-PRJ_LIBS = $(TDBCSTUBLIB)
-!endif
-
-# Disable standard test target because we have a custom one
-DISABLE_TARGET_test = 1
-!include "$(_RULESDIR)\targets.vc"
-
-# Our install has a few more steps than the default install
-install: default-install-docs-n
-
-# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
-# all replacements below so define our own.
-pkgindex: $(OUT_DIR)\pkgIndex.tcl
-$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
- @nmakehlp -s << $** > $@
-@PACKAGE_NAME@ $(PROJECT)
-@PACKAGE_VERSION@ $(DOTVERSION)
-@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-test: setup $(PROJECT)
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
- @set TDBC_LIBRARY=$(LIBDIR:\=/)
- @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
- -load "package ifneeded tdbc::mysql $(DOTVERSION) \
- {source {$(LIBDIR:\=/)/tdbcmysql.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
- package ifneeded tdbc $(TDBC_DOTVERSION) \
- {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
-!endif
-
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for TBDC MySQL interface
+#
+# Basic build, test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir test
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = tdbcmysql
+# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
+# without -DUNICODE. Keep that behaviour for now. TBD
+USE_WIDECHAR_API = 0
+
+!include "rules-ext.vc"
+
+# nmakehelp -V <file> <tag> will search the file for tag, skips until a
+# number and returns all character until a character not in [0-9.ab]
+# is read.
+!if [echo REM = This file is generated from Makefile.vc > versions.vc]
+!endif
+!if [echo TCL_VERSION_REQ = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
+!endif
+!include "versions.vc"
+
+PRJ_OBJS = \
+ $(TMP_DIR)\tdbcmysql.obj \
+ $(TMP_DIR)\mysqlStubInit.obj
+
+# Uncomment the following line if you want to build and install stubs
+# PRJ_STUBOBJS = $(TMP_DIR)\mysqlStubInit.obj
+
+PRJ_HEADERS = \
+ $(GENERICDIR)\fakemysql.h \
+ $(GENERICDIR)\mysqlStubs.h
+
+# Locate TDBC headers and libraries.
+# In principle, we don't need the TDBC source directory, and an installed
+# TDBC should suffice. But that needs additional machinery not implemented
+# yet.
+!if [echo TDBC_DIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
+!error Could not locate TDBC source directory.
+!endif
+!include nmakehlp.out
+
+# Get the TDBC version from its configure.ac
+!if [echo TDBC_DOTVERSION = \> versions.vc] \
+ && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
+!error Could not retrieve TDBC version.
+!endif
+!include versions.vc
+
+TDBC_VERSION = $(TDBC_DOTVERSION:.=)
+TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
+TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
+TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
+TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
+TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
+
+PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
+
+!if !$(STATIC_BUILD)
+PRJ_LIBS = $(TDBCSTUBLIB)
+!endif
+
+# Disable standard test target because we have a custom one
+DISABLE_TARGET_test = 1
+!include "$(_RULESDIR)\targets.vc"
+
+# Our install has a few more steps than the default install
+install: default-install-docs-n
+
+# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
+# all replacements below so define our own.
+pkgindex: $(OUT_DIR)\pkgIndex.tcl
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+ @nmakehlp -s << $** > $@
+@PACKAGE_NAME@ $(PROJECT)
+@PACKAGE_VERSION@ $(DOTVERSION)
+@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+test: setup $(PROJECT)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+ @set TDBC_LIBRARY=$(LIBDIR:\=/)
+ @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
+ -load "package ifneeded tdbc::mysql $(DOTVERSION) \
+ {source {$(LIBDIR:\=/)/tdbcmysql.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
+ package ifneeded tdbc $(TDBC_DOTVERSION) \
+ {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
+!endif
+
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/nmakehlp.c b/tcl8.6/pkgs/tdbcmysql1.1.0/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/nmakehlp.c
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/rules-ext.vc b/tcl8.6/pkgs/tdbcmysql1.1.0/win/rules-ext.vc
index ab86876..58c70fa 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/rules-ext.vc
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/win/rules-ext.vc
@@ -1,118 +1,118 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!ifdef TCLDIR
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/rules.vc b/tcl8.6/pkgs/tdbcmysql1.1.0/win/rules.vc
index bbb412d..7fc51c1 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/rules.vc
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/win/rules.vc
@@ -1,1723 +1,1723 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 0
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!message *** Using $(NMAKEHLPC)
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+# Old linkers (Visual C++ 6 in particular) will link for fast loading
+# on Win98. Since we do not support Win98 any more, we specify nowin98
+# as recommended for NT and later. However, this is only required by
+# IX86 on older compilers and only needed if we are not doing a static build.
+
+!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
+# Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!endif
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/win/targets.vc b/tcl8.6/pkgs/tdbcmysql1.1.0/win/targets.vc
index 312022d..7f1d388 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/win/targets.vc
+++ b/tcl8.6/pkgs/tdbcmysql1.1.0/win/targets.vc
@@ -1,98 +1,98 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubInit.c b/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubInit.c
deleted file mode 100644
index 62050a9..0000000
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubInit.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * odbcStubInit.c --
- *
- * Stubs tables for the foreign ODBC libraries so that
- * Tcl extensions can use them without the linker's knowing about them.
- *
- * @CREATED@ 2017-06-05 16:16:37Z by genExtStubs.tcl from ../generic/odbcStubDefs.txt
- *
- * Copyright (c) 2010 by Kevin B. Kenny.
- *
- * Please refer to the file, 'license.terms' for the conditions on
- * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES.
- *
- *-----------------------------------------------------------------------------
- */
-
-#include <tcl.h>
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include "fakesql.h"
-
-/*
- * Static data used in this file
- */
-
-/*
- * Names of the libraries that might contain the ODBC API
- */
-
-
-/* Uncomment or -DTDBC_NEW_LOADER=1 to use the new loader */
-/*#define TDBC_NEW_LOADER 1*/
-
-
-#ifdef TDBC_NEW_LOADER
-
-#include <stdlib.h>
-
-/* Sorted by name asc. */
-static const char *const odbcStubLibNames[] = {
- "odbc", "odbc32", NULL
-};
-/* Sorted by num desc. No leading dots. Empty first. */
-static const char *const odbcStubLibNumbers[] = {
- "", "1.2", "0.1", NULL
-};
-/* Sorted by name asc. */
-static const char *const odbcOptLibNames[] = {
- "odbccp", "odbccp32", "odbcinst", NULL
-};
-/* Sorted by num desc. No leading dots. Empty first. */
-static const char *const odbcOptLibNumbers[] = {
- "", "2.6", "0.0", NULL
-};
-
-#else
-
-static const char *const odbcStubLibNames[] = {
- /* @LIBNAMES@: DO NOT EDIT THESE NAMES */
- "odbc32", "odbc", "libodbc32", "libodbc", NULL
- /* @END@ */
-};
-static const char *const odbcOptLibNames[] = {
- "odbccp", "odbccp32", "odbcinst",
- "libodbccp", "libodbccp32", "libodbcinst", NULL
-};
-
-#endif
-
-
-/*
- * Names of the functions that we need from ODBC
- */
-
-static const char *const odbcSymbolNames[] = {
- /* @SYMNAMES@: DO NOT EDIT THESE NAMES */
- "SQLAllocHandle",
- "SQLBindParameter",
- "SQLCloseCursor",
- "SQLColumnsW",
- "SQLDataSourcesW",
- "SQLDescribeColW",
- "SQLDescribeParam",
- "SQLDisconnect",
- "SQLDriverConnectW",
- "SQLDriversW",
- "SQLEndTran",
- "SQLExecute",
- "SQLFetch",
- "SQLForeignKeysW",
- "SQLFreeHandle",
- "SQLGetConnectAttr",
- "SQLGetData",
- "SQLGetDiagFieldA",
- "SQLGetDiagRecW",
- "SQLGetTypeInfo",
- "SQLMoreResults",
- "SQLNumParams",
- "SQLNumResultCols",
- "SQLPrepareW",
- "SQLPrimaryKeysW",
- "SQLRowCount",
- "SQLSetConnectAttr",
- "SQLSetConnectOption",
- "SQLSetEnvAttr",
- "SQLTablesW",
- NULL
- /* @END@ */
-};
-
-/*
- * Table containing pointers to the functions named above.
- */
-
-static odbcStubDefs odbcStubsTable;
-const odbcStubDefs* odbcStubs = &odbcStubsTable;
-
-/*
- * Pointers to optional functions in ODBCINST
- */
-
-BOOL (INSTAPI* SQLConfigDataSourceW)(HWND, WORD, LPCWSTR, LPCWSTR)
-= NULL;
-BOOL (INSTAPI* SQLConfigDataSource)(HWND, WORD, LPCSTR, LPCSTR)
-= NULL;
-BOOL (INSTAPI* SQLInstallerError)(WORD, DWORD*, LPSTR, WORD, WORD*)
-= NULL;
-
-
-#ifdef TDBC_NEW_LOADER
-
-#ifndef TCL_SHLIB_EXT
-# define TCL_SHLIB_EXT ".so"
-#endif
-
-#ifndef LIBPREFIX
-# ifdef __CYGWIN__
-# define LIBPREFIX "cyg"
-# else
-# define LIBPREFIX "lib"
-# endif
-#endif
-
-#ifdef __CYGWIN__
-# define TDBC_SHLIB_SEP "-"
-#else
-# define TDBC_SHLIB_SEP "."
-#endif
-
-const char *const tdbcLibFormats[] = {
- LIBPREFIX "%s" TCL_SHLIB_EXT "%s" "%s",
- "%s" TCL_SHLIB_EXT "%s" "%s",
- NULL
-};
-
-/*
- *-----------------------------------------------------------------------------
- *
- * tdbcLoadLib --
- *
- * Tries to load a shared library given a list of lib names and/or
- * all combinations of LIBPREFIX, no LIBPREFIX, lib names and lib numbers.
- * Takes CYGWIN into account.
- *
- * Results:
- * Returns the handle to the loaded ODBC client library and leaves the
- * name of the the loaded ODBC client library in the interpreter, or NULL
- * if the load is unsuccessful and leaves a list of error message(s) in the
- * interpreter.
- *
- *-----------------------------------------------------------------------------
- */
-
-static Tcl_LoadHandle
-tdbcLoadLib (
- Tcl_Interp *interp, /* Receives errors or lib name if successful */
- const char *const soNames[], /* Lib names. Kwazy lookup not done if NULL */
- const char *const soNumbers[], /* Lib numbers for kwazy lookup */
- const char *const soSymbolNames[], /* Passed to Tcl_LoadFile */
- const void *soStubDefs, /* Passed to Tcl_LoadFile */
- const char *soList, /* Lib name list to try first if not NULL */
- const char *const soFormats[] /* Lib name printf formats for kwazy lookup.
- Default used if NULL.
- Maybe not useful as a parameter. */
-) {
- const char *const *nam; /* Name */
- const char *const *num; /* Number */
- const char *const *fmt; /* Format */
- Tcl_Obj *lib; /* Holds lib name during kwazy lookup */
- Tcl_Obj *result; /* List of errors or lib name if successful */
- Tcl_LoadHandle handle; /* NULL or handle to loaded lib if successful */
-
- result = NULL; /* Important! This is eventually returned. */
- handle = NULL; /* Important! This is eventually returned. */
-
- /*
- * Try to load a lib from a string claiming to be a list of libs?
- */
- if (soList != NULL) { /* Yes! */
- Tcl_Obj *l;
- Tcl_Obj **els;
- int nels;
- int i;
-
- /*
- * Make list from string.
- * Caller is responsible for listability and utf8ness.
- */
- l = Tcl_NewStringObj(soList, -1);
- Tcl_IncrRefCount(l);
-
- if (Tcl_ListObjGetElements(interp, l, &nels, &els) != TCL_OK) {
- Tcl_DecrRefCount(l);
- return NULL;
- }
-
- result = Tcl_NewListObj(0, NULL);
- Tcl_IncrRefCount(result);
-
- /*
- * Left-to-right, trying to load a lib at each iteration.
- */
- for (i = 0; i < nels; i++) {
- if (Tcl_LoadFile(interp, els[i], soSymbolNames, 0, (void *) soStubDefs, &handle) == TCL_OK) {
- /* Lib found and loaded. Cleanup and setup result. */
- Tcl_DecrRefCount(result); /* Throw away any errors collected. */
- result = Tcl_DuplicateObj(els[i]);
- Tcl_IncrRefCount(result);
- break;
- }
- Tcl_ListObjAppendElement(NULL, result, Tcl_GetObjResult(interp)); /* Collect error. */
- handle = NULL; /* Important! This is eventually returned. */
- }
- Tcl_DecrRefCount(l);
- if (handle != NULL) {
- goto loadDone;
- }
- }
-
- /*
- * At this point no lib list was provided or no lib was found in the list.
- */
-
- /*
- * Done if names not provided.
- */
- if (soNames == NULL) {
- goto loadDone;
- }
-
- /*
- * Use default format(s) if not supplied.
- */
- if (soFormats == NULL) {
- soFormats = tdbcLibFormats;
- }
-
- if (result == NULL) {
- result = Tcl_NewListObj(0, NULL);
- Tcl_IncrRefCount(result);
- }
-
- /*
- * Try every possible combination (aka Kwazy Lookup).
- */
- for (nam = &soNames[0]; *nam != NULL; nam++) {
- for (num = &soNumbers[0]; *num != NULL; num++) {
- for (fmt = &soFormats[0]; *fmt != NULL; fmt++) {
- lib = Tcl_ObjPrintf(*fmt, *nam, (*num[0] == '\0' ? "" : TDBC_SHLIB_SEP), *num);
- Tcl_IncrRefCount(lib);
- if (Tcl_LoadFile(interp, lib, soSymbolNames, 0, (void *) soStubDefs, &handle) == TCL_OK) {
- /* Lib found and loaded. Cleanup and setup result. */
- Tcl_DecrRefCount(result); /* Throw away any errors collected. */
- result = lib;
- goto loadDone;
- }
- Tcl_ListObjAppendElement(NULL, result, Tcl_GetObjResult(interp)); /* Collect error. */
- Tcl_DecrRefCount(lib);
- handle = NULL; /* Important! This is eventually returned. */
- }}}
-
-loadDone:
-
- if (result != NULL) {
- Tcl_SetObjResult(interp, result);
- Tcl_DecrRefCount(result);
- }
-
- return handle; /* Like I said... */
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * OdbcInitStubs --
- *
- * Initialize the Stubs table for the ODBC API
- *
- * Results:
- * Returns the handle to the loaded ODBC client library, or NULL
- * if the load is unsuccessful. Leaves an error message in the
- * interpreter.
- *
- *-----------------------------------------------------------------------------
- */
-
-MODULE_SCOPE Tcl_LoadHandle
-OdbcInitStubs(Tcl_Interp* interp,
- /* Tcl interpreter */
- Tcl_LoadHandle* handle2Ptr)
- /* Pointer to a second load handle
- * that represents the ODBCINST library */
-{
- Tcl_LoadHandle handle; /* Handle to a load module */
- int status; /* Status of Tcl library calls for ODBC lib */
- int status2; /* Status of Tcl library calls for ODBCINST lib */
-
- SQLConfigDataSourceW = NULL;/* Symbols maybe in ODBCINST lib */
- SQLConfigDataSource = NULL;
- SQLInstallerError = NULL;
-
- /*
- * Try to load a client library and resolve the ODBC API within it.
- */
-
- handle = tdbcLoadLib(interp,
- odbcStubLibNames, odbcStubLibNumbers,
- odbcSymbolNames, odbcStubs,
- getenv("TDBC_ODBC_ODBCLIBS"), NULL
- );
- status = (handle == NULL ? TCL_ERROR : TCL_OK);
-
- /*
- * We've run out of library names (in which case status==TCL_ERROR
- * and the error message reflects the last unsuccessful load attempt).
- */
-
- if (status != TCL_OK) {
- return NULL;
- }
-
- /*
- * If a client library is found, then try to load ODBCINST as well.
- */
-
- *handle2Ptr = tdbcLoadLib(interp,
- odbcOptLibNames, odbcOptLibNumbers,
- NULL, NULL,
- getenv("TDBC_ODBC_ODBCINSTLIBS"), NULL
- );
- status2 = (*handle2Ptr == NULL ? TCL_ERROR : TCL_OK);
-
- if (status2 == TCL_OK) {
- SQLConfigDataSourceW =
- (BOOL (INSTAPI*)(HWND, WORD, LPCWSTR, LPCWSTR))
- Tcl_FindSymbol(NULL, *handle2Ptr, "SQLConfigDataSourceW");
- if (SQLConfigDataSourceW == NULL) {
- SQLConfigDataSource =
- (BOOL (INSTAPI*)(HWND, WORD, LPCSTR, LPCSTR))
- Tcl_FindSymbol(NULL, *handle2Ptr,
- "SQLConfigDataSource");
- }
- SQLInstallerError =
- (BOOL (INSTAPI*)(WORD, DWORD*, LPSTR, WORD, WORD*))
- Tcl_FindSymbol(NULL, *handle2Ptr, "SQLInstallerError");
- } else {
- Tcl_ResetResult(interp);
- }
-
- /*
- * We've successfully loaded a library.
- */
-
- return handle;
-}
-
-#else
-
-/*
- *-----------------------------------------------------------------------------
- *
- * OdbcInitStubs --
- *
- * Initialize the Stubs table for the ODBC API
- *
- * Results:
- * Returns the handle to the loaded ODBC client library, or NULL
- * if the load is unsuccessful. Leaves an error message in the
- * interpreter.
- *
- *-----------------------------------------------------------------------------
- */
-
-MODULE_SCOPE Tcl_LoadHandle
-OdbcInitStubs(Tcl_Interp* interp,
- /* Tcl interpreter */
- Tcl_LoadHandle* handle2Ptr)
- /* Pointer to a second load handle
- * that represents the ODBCINST library */
-{
- int i;
- int status; /* Status of Tcl library calls */
- Tcl_Obj* path; /* Path name of a module to be loaded */
- Tcl_Obj* shlibext; /* Extension to use for load modules */
- Tcl_LoadHandle handle = NULL;
- /* Handle to a load module */
-
- SQLConfigDataSourceW = NULL;
- SQLConfigDataSource = NULL;
- SQLInstallerError = NULL;
-
- /*
- * Determine the shared library extension
- */
- status = Tcl_EvalEx(interp, "::info sharedlibextension", -1,
- TCL_EVAL_GLOBAL);
- if (status != TCL_OK) return NULL;
- shlibext = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(shlibext);
-
- /*
- * Walk the list of possible library names to find an ODBC client
- */
- status = TCL_ERROR;
- for (i = 0; status == TCL_ERROR && odbcStubLibNames[i] != NULL; ++i) {
- path = Tcl_NewStringObj(odbcStubLibNames[i], -1);
- Tcl_AppendObjToObj(path, shlibext);
- Tcl_IncrRefCount(path);
- Tcl_ResetResult(interp);
-
- /*
- * Try to load a client library and resolve the ODBC API within it.
- */
- status = Tcl_LoadFile(interp, path, odbcSymbolNames, 0,
- (void*)odbcStubs, &handle);
- Tcl_DecrRefCount(path);
- }
-
- /*
- * If a client library is found, then try to load ODBCINST as well.
- */
- if (status == TCL_OK) {
- int status2 = TCL_ERROR;
- for (i = 0; status2 == TCL_ERROR && odbcOptLibNames[i] != NULL; ++i) {
- path = Tcl_NewStringObj(odbcOptLibNames[i], -1);
- Tcl_AppendObjToObj(path, shlibext);
- Tcl_IncrRefCount(path);
- status2 = Tcl_LoadFile(interp, path, NULL, 0, NULL, handle2Ptr);
- if (status2 == TCL_OK) {
- SQLConfigDataSourceW =
- (BOOL (INSTAPI*)(HWND, WORD, LPCWSTR, LPCWSTR))
- Tcl_FindSymbol(NULL, *handle2Ptr, "SQLConfigDataSourceW");
- if (SQLConfigDataSourceW == NULL) {
- SQLConfigDataSource =
- (BOOL (INSTAPI*)(HWND, WORD, LPCSTR, LPCSTR))
- Tcl_FindSymbol(NULL, *handle2Ptr,
- "SQLConfigDataSource");
- }
- SQLInstallerError =
- (BOOL (INSTAPI*)(WORD, DWORD*, LPSTR, WORD, WORD*))
- Tcl_FindSymbol(NULL, *handle2Ptr, "SQLInstallerError");
- } else {
- Tcl_ResetResult(interp);
- }
- Tcl_DecrRefCount(path);
- }
- }
-
- /*
- * Either we've successfully loaded a library (status == TCL_OK),
- * or we've run out of library names (in which case status==TCL_ERROR
- * and the error message reflects the last unsuccessful load attempt).
- */
- Tcl_DecrRefCount(shlibext);
- if (status != TCL_OK) {
- return NULL;
- }
- return handle;
-}
-
-#endif
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/win/rules-ext.vc b/tcl8.6/pkgs/tdbcodbc1.0.6/win/rules-ext.vc
deleted file mode 100644
index ab86876..0000000
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/win/rules-ext.vc
+++ /dev/null
@@ -1,118 +0,0 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
-!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/win/targets.vc b/tcl8.6/pkgs/tdbcodbc1.0.6/win/targets.vc
deleted file mode 100644
index 312022d..0000000
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/win/targets.vc
+++ /dev/null
@@ -1,98 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/ChangeLog b/tcl8.6/pkgs/tdbcodbc1.1.0/ChangeLog
index fc6675f..fc6675f 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/ChangeLog
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/ChangeLog
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/Makefile.in b/tcl8.6/pkgs/tdbcodbc1.1.0/Makefile.in
index a0cbac2..85d07b5 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/Makefile.in
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/Makefile.in
@@ -11,8 +11,13 @@
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: Makefile.in,v 1.64 2007/10/23 22:08:06 hobbs Exp $
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
#========================================================================
# Nothing of the variables below this line should need to be changed.
@@ -31,6 +36,9 @@
PKG_SOURCES = @PKG_SOURCES@
PKG_OBJECTS = @PKG_OBJECTS@
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
#========================================================================
# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
@@ -50,6 +58,7 @@ PKG_HEADERS = @PKG_HEADERS@
#========================================================================
PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE)
BINARIES = $(lib_BINARIES)
@@ -63,7 +72,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
-datarootdir = @datarootdir@
+datarootdir = @datarootdir@
datadir = @datadir@
mandir = @mandir@
@@ -74,15 +83,15 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
-top_builddir = .
+top_builddir = @abs_top_builddir@
-INSTALL_OPTIONS =
-INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
-INSTALL_DATA_DIR = ${INSTALL} -d -m 755
-INSTALL_PROGRAM = ${INSTALL} -m 755
-INSTALL_DATA = ${INSTALL} -m 444
-INSTALL_SCRIPT = ${INSTALL_PROGRAM}
-INSTALL_LIBRARY = ${INSTALL_DATA}
+INSTALL_OPTIONS =
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@@ -125,25 +134,25 @@ TDBC_LIB_FILE = @TDBC_LIB_FILE@
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
-TCLLIBPATH = $(top_builddir)
-TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
- TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@`
+TCLLIBPATH = $(top_builddir) $(TDBC_BIN_DIR)
+TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(TCLLIBPATH)" \
- TDBCODBC_LIBRARY=`@CYGPATH@ $(srcdir)/library`
+ TDBCODBC_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+ TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` \
+ TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
-#WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
+#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
-# INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
+#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
PKG_CFLAGS = @PKG_CFLAGS@
@@ -165,8 +174,12 @@ AR = @AR@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-VALGRIND = valgrind
-VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high --leak-check=yes --show-reachable=yes -v
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
+.SUFFIXES: .c .$(OBJEXT)
#========================================================================
# Start of user-definable TARGETS section
@@ -174,7 +187,7 @@ VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high --leak-c
#========================================================================
# TEA TARGETS. Please note that the "libraries:" target refers to platform
-# independent files, and the "binaries:" target inclues executable programs and
+# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries. Modify these targets so that they install
# the various pieces of your package. The make and install rules
# for the BINARIES that you specified above have already been done.
@@ -235,47 +248,39 @@ test: test-jet test-sqlserver test-sqlite
test-jet: binaries libraries
@echo testing tdbcodbc against Jet
- TDBCODBC_TYPE=jet \
+ TDBCODBC_TEST_TYPE=jet \
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::odbc $(PACKAGE_VERSION) \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
test-sqlserver: binaries libraries
@echo testing tdbcodbc against SQL Server
- TDBCODBC_TYPE=sqlserver \
+ TDBCODBC_TEST_TYPE=sqlserver \
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::odbc ${PACKAGE_VERSION} \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
test-sqlite: binaries libraries
@echo testing tdbcodbc against SQLite
- TDBCODBC_TYPE=sqlite \
+ TDBCODBC_TEST_TYPE=sqlite \
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::odbc ${PACKAGE_VERSION} \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
valgrind-sqlite: binaries libraries
- TDBCODBC_TYPE=sqlite \
+ TDBCODBC_TEST_TYPE=sqlite \
$(PKG_ENV) $(TCLSH_ENV) \
LD_PRELOAD=$(PKG_LIB_FILE) \
$(VALGRIND) $(VALGRINDARGS) \
$(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::odbc ${PACKAGE_VERSION} \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcodbc.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
- $(TCLSH_ENV) $(PKG_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
depend:
@@ -294,6 +299,11 @@ $(PKG_LIB_FILE): $(PKG_OBJECTS)
${MAKE_LIB}
$(RANLIB) $(PKG_LIB_FILE)
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+ -rm -f $(PKG_STUB_LIB_FILE)
+ ${MAKE_STUB_LIB}
+ $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
@@ -324,49 +334,55 @@ COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
+
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
- mkdir -p $(DIST_DIR)
- cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
- $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
- $(srcdir)/configure.ac $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
-
- for i in $(srcdir)/*.[ch]; do \
- if [ -f $$i ]; then \
- cp -p $$i $(DIST_DIR)/ ; \
- fi; \
- done;
-
- mkdir $(DIST_DIR)/tclconfig
- cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
- $(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
-
- mkdir $(DIST_DIR)/doc
- cp -p $(srcdir)/doc/tdbc_odbc.n $(DIST_DIR)/doc/
-
- mkdir $(DIST_DIR)/generic
- cp -p $(srcdir)/generic/fakesql.h $(srcdir)/generic/odbcStubDefs.txt \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)
+
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/doc
+ $(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc_odbc.n $(DIST_DIR)/doc/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/generic
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/generic/fakesql.h $(srcdir)/generic/odbcStubDefs.txt \
$(srcdir)/generic/odbcStubInit.c $(srcdir)/generic/odbcStubs.h \
$(srcdir)/generic/tdbcodbc.c \
$(srcdir)/generic/int2ptr_ptr2int.h \
$(DIST_DIR)/generic/
- mkdir $(DIST_DIR)/library
- cp -p $(srcdir)/library/tdbcodbc.tcl $(DIST_DIR)/library/
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/library
+ $(DIST_INSTALL_DATA) $(srcdir)/library/tdbcodbc.tcl $(DIST_DIR)/library/
- mkdir $(DIST_DIR)/tests
- cp -p $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcodbc.test \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tests
+ $(DIST_INSTALL_DATA) $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcodbc.test \
$(srcdir)/tests/test.mdb \
$(DIST_DIR)/tests/
- mkdir $(DIST_DIR)/win
- cp -p $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/win
+ $(DIST_INSTALL_DATA) $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
$(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
$(srcdir)/win/rules.vc $(DIST_DIR)/win/
@@ -420,16 +436,8 @@ install-lib-binaries: binaries
@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
@list='$(lib_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
- echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
- $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
- stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
- if test "x$$stub" = "xstub"; then \
- echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
- else \
- echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
- fi; \
+ echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
@@ -470,8 +478,6 @@ install-bin-binaries: binaries
fi; \
done
-.SUFFIXES: .c .$(OBJEXT)
-
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
@@ -489,6 +495,7 @@ uninstall-binaries:
done
.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/README b/tcl8.6/pkgs/tdbcodbc1.1.0/README
index 7e4348f..dd6ccee 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/README
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/README
@@ -1,6 +1,6 @@
README: tdbcodbc
- This is the 1.0.6 source distribution of the bridge between Tcl
+ This is the 1.1.0 source distribution of the bridge between Tcl
Database Connectivity (TDBC) and Open Database Connectivity
(ODBC), a database-neutral API layer available on all Windows
systems and many others.. TDBC and its drivers are available from
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/aclocal.m4 b/tcl8.6/pkgs/tdbcodbc1.1.0/aclocal.m4
index 83d361c..83d361c 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/aclocal.m4
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/aclocal.m4
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/configure b/tcl8.6/pkgs/tdbcodbc1.1.0/configure
index e5c49a8..dedfd50 100755
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/configure
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tdbcmysql 1.0.6.
+# Generated by GNU Autoconf 2.69 for tdbcodbc 1.1.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -575,10 +575,10 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME='tdbcmysql'
-PACKAGE_TARNAME='tdbcmysql'
-PACKAGE_VERSION='1.0.6'
-PACKAGE_STRING='tdbcmysql 1.0.6'
+PACKAGE_NAME='tdbcodbc'
+PACKAGE_TARNAME='tdbcodbc'
+PACKAGE_VERSION='1.1.0'
+PACKAGE_STRING='tdbcodbc 1.1.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -648,17 +648,10 @@ 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
TDBC_LIB_FILE
TDBC_VERSION
@@ -694,6 +687,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1308,7 +1307,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 tdbcmysql 1.0.6 to adapt to many kinds of systems.
+\`configure' configures tdbcodbc 1.1.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1356,7 +1355,7 @@ Fine tuning of the installation directories:
--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/tdbcmysql]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/tdbcodbc]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1369,7 +1368,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tdbcmysql 1.0.6:";;
+ short | recursive ) echo "Configuration of tdbcodbc 1.1.0:";;
esac
cat <<\_ACEOF
@@ -1472,7 +1471,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tdbcmysql configure 1.0.6
+tdbcodbc configure 1.1.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1634,206 +1633,6 @@ $as_echo "$ac_res" >&6; }
} # 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
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2070,11 +1869,124 @@ rm -f conftest.val
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
+
+# 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
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 tdbcmysql $as_me 1.0.6, which was
+It was created by tdbcodbc $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2430,26 +2342,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2458,7 +2360,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2550,6 +2452,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2659,6 +2610,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2685,13 +2639,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -3792,6 +3750,7 @@ $as_echo "$as_me: WARNING: --with-tdbc argument should refer to directory contai
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4692,20 +4651,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -5377,470 +5322,11 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long.
+#-----------------------------------------------------------------------
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
@@ -5958,10 +5444,9 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-$as_echo "#define DONT_TD_VOID 1" >>confdefs.h
-
#-----------------------------------------------------------------------
+# __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,
@@ -5971,7 +5456,7 @@ $as_echo "#define DONT_TD_VOID 1" >>confdefs.h
#-----------------------------------------------------------------------
- vars="generic/tdbcmysql.c generic/mysqlStubInit.c"
+ vars="generic/tdbcodbc.c generic/odbcStubInit.c"
for i in $vars; do
case $i in
\$*)
@@ -6006,7 +5491,7 @@ $as_echo "#define DONT_TD_VOID 1" >>confdefs.h
- vars="generic/fakemysql.h generic/mysqlStubs.h"
+ vars="generic/fakesql.h generic/odbcStubs.h"
for i in $vars; do
# check for existence, be strict because it is installed
if test ! -f "${srcdir}/$i" ; then
@@ -6103,7 +5588,7 @@ fi
- vars="library/tdbcmysql.tcl"
+ vars="library/tdbcodbc.tcl"
for i in $vars; do
# check for existence, be strict because it is installed
if test ! -f "${srcdir}/$i" ; then
@@ -6115,6 +5600,7 @@ fi
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -6126,8 +5612,20 @@ fi
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -6219,6 +5717,11 @@ $as_echo "${ac_cv_c_tclh}" >&6; }
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -7924,7 +7427,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8558,9 +8061,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -9253,14 +8756,99 @@ 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.
+# Locate the ws2_32 library; we need it for ntohs and friends
#--------------------------------------------------------------------
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lws2_32" >&5
+$as_echo_n "checking for main in -lws2_32... " >&6; }
+if ${ac_cv_lib_ws2_32_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lws2_32 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
-$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ws2_32_main=yes
+else
+ ac_cv_lib_ws2_32_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_ws2_32_main" >&5
+$as_echo "$ac_cv_lib_ws2_32_main" >&6; }
+if test "x$ac_cv_lib_ws2_32_main" = xyes; then :
+
+ vars="-lws2_32"
+ 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
+
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lwinsock" >&5
+$as_echo_n "checking for main in -lwinsock... " >&6; }
+if ${ac_cv_lib_winsock_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lwinsock $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_winsock_main=yes
+else
+ ac_cv_lib_winsock_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_winsock_main" >&5
+$as_echo "$ac_cv_lib_winsock_main" >&6; }
+if test "x$ac_cv_lib_winsock_main" = xyes; then :
+
+ vars="-lwinsock"
+ 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
+
+
+fi
+
+
+fi
#--------------------------------------------------------------------
@@ -9420,11 +9008,12 @@ $as_echo_n "checking for tclsh... " >&6; }
$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.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
@@ -9973,7 +9562,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 tdbcmysql $as_me 1.0.6, which was
+This file was extended by tdbcodbc $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -10026,7 +9615,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="\\
-tdbcmysql config.status 1.0.6
+tdbcodbc config.status 1.1.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/configure.ac b/tcl8.6/pkgs/tdbcodbc1.1.0/configure.ac
index 2c809f8..93e2b2b 100755..100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/configure.ac
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/configure.ac
@@ -4,14 +4,22 @@ dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
+# Sample configure.ac for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
#-----------------------------------------------------------------------
-AC_INIT([tdbcodbc], [1.0.6])
+AC_INIT([tdbcodbc], [1.1.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -19,7 +27,7 @@ AC_INIT([tdbcodbc], [1.0.6])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
@@ -85,15 +93,20 @@ TEA_PREFIX
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long.
+#-----------------------------------------------------------------------
+
AC_C_INLINE
AC_CHECK_TYPE([long long],[
AC_DEFINE([HAVE_LONG_LONG],[1])
AC_CHECK_SIZEOF([long long])
],[],[])
AC_CHECK_SIZEOF([long])
-AC_DEFINE([DONT_TD_VOID],[1])
#-----------------------------------------------------------------------
+# __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,
@@ -122,13 +135,7 @@ TEA_ADD_STUB_SOURCES()
TEA_ADD_TCL_SOURCES([library/tdbcodbc.tcl])
#--------------------------------------------------------------------
-# The new loader needs to know the shared lib suffix.
-#--------------------------------------------------------------------
-
-AC_DEFINE_UNQUOTED(TCL_SHLIB_EXT,"${TCL_SHLIB_SUFFIX}",
- [What is the default extension for shared libraries?])
-
-#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -140,8 +147,20 @@ AC_DEFINE_UNQUOTED(TCL_SHLIB_EXT,"${TCL_SHLIB_SUFFIX}",
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -150,6 +169,11 @@ AC_DEFINE_UNQUOTED(TCL_SHLIB_EXT,"${TCL_SHLIB_SUFFIX}",
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -187,15 +211,6 @@ AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_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. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
-
-#--------------------------------------------------------------------
# Locate the ws2_32 library; we need it for ntohs and friends
#--------------------------------------------------------------------
@@ -220,11 +235,12 @@ TEA_MAKE_LIB
#--------------------------------------------------------------------
TEA_PROG_TCLSH
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
-# which require substituting th AC variables in. Include these here.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/doc/tdbc_odbc.n b/tcl8.6/pkgs/tdbcodbc1.1.0/doc/tdbc_odbc.n
index 4a73521..4a73521 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/doc/tdbc_odbc.n
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/doc/tdbc_odbc.n
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/fakesql.h b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/fakesql.h
index 099f9af..7bde20e 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/fakesql.h
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/fakesql.h
@@ -92,6 +92,7 @@ typedef HWND SQLHWND;
#define SQL_NULL_HANDLE ((SQLHANDLE) 0)
#define SQL_NULL_HENV ((SQLHENV) 0)
+#define SQL_NULL_HDBC ((SQLHDBC) 0)
#define SQL_NULL_HSTMT ((SQLHSTMT) 0)
/* SQL data types */
@@ -144,6 +145,7 @@ enum _SQL_DATATYPE {
#define SQL_NO_TOTAL (-4)
#define SQL_SUCCESS 0
#define SQL_SUCCESS_WITH_INFO 1
+#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0)
/* Diagnostic fields */
@@ -175,6 +177,7 @@ enum _SQL_DIAG {
#define SQL_ATTR_CONNECTION_TIMEOUT 113
#define SQL_ATTR_ODBC_VERSION 200
#define SQL_ATTR_TXN_ISOLATION SQL_TXN_ISOLATION
+#define SQL_ATTR_AUTOCOMMIT SQL_AUTOCOMMIT
/* Nullable? */
@@ -187,6 +190,7 @@ enum _SQL_DIAG {
/* ODBC versions */
#define SQL_OV_ODBC3 3UL
+#define SQL_ODBC_VER 10
/* SQLDriverConnect flags */
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/int2ptr_ptr2int.h b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/int2ptr_ptr2int.h
index 4b0a15d..4b0a15d 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/int2ptr_ptr2int.h
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/int2ptr_ptr2int.h
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubDefs.txt b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubDefs.txt
index 544991e..54a699d 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubDefs.txt
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubDefs.txt
@@ -12,7 +12,6 @@
#-----------------------------------------------------------------------------
* STUBSTRUCT: odbcStubs
-* LIBRARY: odbc32 odbc libodbc32 libodbc
* CONVENTION: SQL_API
SQLRETURN SQLAllocHandle(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
@@ -34,6 +33,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC,SQLINTEGER,SQLPOINTER,SQLINTEGER,SQLINTEGER*
SQLRETURN SQLGetData(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
SQLRETURN SQLGetDiagFieldA(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
SQLRETURN SQLGetDiagRecW(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
+SQLRETURN SQLGetInfoW(SQLHANDLE,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
SQLRETURN SQLGetTypeInfo(SQLHSTMT,SQLSMALLINT);
SQLRETURN SQLMoreResults(SQLHSTMT);
SQLRETURN SQLNumParams(SQLHSTMT,SQLSMALLINT*);
diff --git a/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubInit.c b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubInit.c
new file mode 100644
index 0000000..b283aad
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubInit.c
@@ -0,0 +1,214 @@
+/*
+ * odbcStubInit.c --
+ *
+ * Stubs tables for the foreign ODBC libraries so that
+ * Tcl extensions can use them without the linker's knowing about them.
+ *
+ * @CREATED@ 2018-05-12 16:18:48Z by genExtStubs.tcl from odbcStubDefs.txt
+ *
+ * Copyright (c) 2010 by Kevin B. Kenny.
+ *
+ * Please refer to the file, 'license.terms' for the conditions on
+ * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#include <tcl.h>
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+#include "fakesql.h"
+
+/*
+ * Static data used in this file
+ */
+
+/*
+ * Names of the libraries that might contain the ODBC API
+ */
+
+static const char *const odbcStubLibNames[] = {
+#if defined(__APPLE__)
+ "libiodbc.2",
+#elif defined(__OpenBSD__)
+ "libiodbc",
+#else
+ "odbc32", "odbc", "libodbc32", "libodbc", "libiodbc",
+#endif
+ NULL
+ /* @END@ */
+};
+static const char *const odbcOptLibNames[] = {
+#if defined(__APPLE__)
+ "libiodbcinst.2",
+#elif defined(__OpenBSD__)
+ "libiodbcinst",
+#else
+ "odbccp", "odbccp32", "odbcinst",
+ "libodbccp", "libodbccp32", "libodbcinst", "libiodbcinst",
+#endif
+ NULL
+};
+
+/*
+ * Names of the functions that we need from ODBC
+ */
+
+static const char *const odbcSymbolNames[] = {
+ /* @SYMNAMES@: DO NOT EDIT THESE NAMES */
+ "SQLAllocHandle",
+ "SQLBindParameter",
+ "SQLCloseCursor",
+ "SQLColumnsW",
+ "SQLDataSourcesW",
+ "SQLDescribeColW",
+ "SQLDescribeParam",
+ "SQLDisconnect",
+ "SQLDriverConnectW",
+ "SQLDriversW",
+ "SQLEndTran",
+ "SQLExecute",
+ "SQLFetch",
+ "SQLForeignKeysW",
+ "SQLFreeHandle",
+ "SQLGetConnectAttr",
+ "SQLGetData",
+ "SQLGetDiagFieldA",
+ "SQLGetDiagRecW",
+ "SQLGetInfoW",
+ "SQLGetTypeInfo",
+ "SQLMoreResults",
+ "SQLNumParams",
+ "SQLNumResultCols",
+ "SQLPrepareW",
+ "SQLPrimaryKeysW",
+ "SQLRowCount",
+ "SQLSetConnectAttr",
+ "SQLSetConnectOption",
+ "SQLSetEnvAttr",
+ "SQLTablesW",
+ NULL
+ /* @END@ */
+};
+
+/*
+ * Table containing pointers to the functions named above.
+ */
+
+static odbcStubDefs odbcStubsTable;
+const odbcStubDefs* odbcStubs = &odbcStubsTable;
+
+/*
+ * Pointers to optional functions in ODBCINST
+ */
+
+BOOL (INSTAPI* SQLConfigDataSourceW)(HWND, WORD, LPCWSTR, LPCWSTR)
+= NULL;
+BOOL (INSTAPI* SQLConfigDataSource)(HWND, WORD, LPCSTR, LPCSTR)
+= NULL;
+BOOL (INSTAPI* SQLInstallerError)(WORD, DWORD*, LPSTR, WORD, WORD*)
+= NULL;
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * OdbcInitStubs --
+ *
+ * Initialize the Stubs table for the ODBC API
+ *
+ * Results:
+ * Returns the handle to the loaded ODBC client library, or NULL
+ * if the load is unsuccessful. Leaves an error message in the
+ * interpreter.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+MODULE_SCOPE Tcl_LoadHandle
+OdbcInitStubs(Tcl_Interp* interp,
+ /* Tcl interpreter */
+ Tcl_LoadHandle* handle2Ptr)
+ /* Pointer to a second load handle
+ * that represents the ODBCINST library */
+{
+ int i;
+ int status; /* Status of Tcl library calls */
+ Tcl_Obj* path; /* Path name of a module to be loaded */
+ Tcl_Obj* shlibext; /* Extension to use for load modules */
+ Tcl_LoadHandle handle = NULL;
+ /* Handle to a load module */
+
+ SQLConfigDataSourceW = NULL;
+ SQLConfigDataSource = NULL;
+ SQLInstallerError = NULL;
+
+ /*
+ * Determine the shared library extension
+ */
+ status = Tcl_EvalEx(interp, "::info sharedlibextension", -1,
+ TCL_EVAL_GLOBAL);
+ if (status != TCL_OK) return NULL;
+ shlibext = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(shlibext);
+
+ /*
+ * Walk the list of possible library names to find an ODBC client
+ */
+ status = TCL_ERROR;
+ for (i = 0; status == TCL_ERROR && odbcStubLibNames[i] != NULL; ++i) {
+ path = Tcl_NewStringObj(odbcStubLibNames[i], -1);
+ Tcl_AppendObjToObj(path, shlibext);
+ Tcl_IncrRefCount(path);
+ Tcl_ResetResult(interp);
+
+ /*
+ * Try to load a client library and resolve the ODBC API within it.
+ */
+ status = Tcl_LoadFile(interp, path, odbcSymbolNames, 0,
+ (void*)odbcStubs, &handle);
+ Tcl_DecrRefCount(path);
+ }
+
+ /*
+ * If a client library is found, then try to load ODBCINST as well.
+ */
+ if (status == TCL_OK) {
+ int status2 = TCL_ERROR;
+ for (i = 0; status2 == TCL_ERROR && odbcOptLibNames[i] != NULL; ++i) {
+ path = Tcl_NewStringObj(odbcOptLibNames[i], -1);
+ Tcl_AppendObjToObj(path, shlibext);
+ Tcl_IncrRefCount(path);
+ status2 = Tcl_LoadFile(interp, path, NULL, 0, NULL, handle2Ptr);
+ if (status2 == TCL_OK) {
+ SQLConfigDataSourceW =
+ (BOOL (INSTAPI*)(HWND, WORD, LPCWSTR, LPCWSTR))
+ Tcl_FindSymbol(NULL, *handle2Ptr, "SQLConfigDataSourceW");
+ if (SQLConfigDataSourceW == NULL) {
+ SQLConfigDataSource =
+ (BOOL (INSTAPI*)(HWND, WORD, LPCSTR, LPCSTR))
+ Tcl_FindSymbol(NULL, *handle2Ptr,
+ "SQLConfigDataSource");
+ }
+ SQLInstallerError =
+ (BOOL (INSTAPI*)(WORD, DWORD*, LPSTR, WORD, WORD*))
+ Tcl_FindSymbol(NULL, *handle2Ptr, "SQLInstallerError");
+ } else {
+ Tcl_ResetResult(interp);
+ }
+ Tcl_DecrRefCount(path);
+ }
+ }
+
+ /*
+ * Either we've successfully loaded a library (status == TCL_OK),
+ * or we've run out of library names (in which case status==TCL_ERROR
+ * and the error message reflects the last unsuccessful load attempt).
+ */
+ Tcl_DecrRefCount(shlibext);
+ if (status != TCL_OK) {
+ return NULL;
+ }
+ return handle;
+}
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubs.h b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubs.h
index 0295a5f..00a5cc7 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/odbcStubs.h
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/odbcStubs.h
@@ -1,20 +1,17 @@
/*
*-----------------------------------------------------------------------------
*
- * ../generic/odbcStubs.h --
+ * odbcStubs.h --
*
* Stubs for procedures in odbcStubDefs.txt
*
* Generated by genExtStubs.tcl: DO NOT EDIT
- * 2017-06-05 16:16:37Z
+ * 2018-05-12 16:18:48Z
*
*-----------------------------------------------------------------------------
*/
typedef struct odbcStubDefs {
-
- /* Functions from libraries: odbc32 odbc libodbc32 libodbc */
-
SQLRETURN (SQL_API*SQLAllocHandlePtr)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
SQLRETURN (SQL_API*SQLBindParameterPtr)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
SQLRETURN (SQL_API*SQLCloseCursorPtr)(SQLHSTMT);
@@ -34,6 +31,7 @@ typedef struct odbcStubDefs {
SQLRETURN (SQL_API*SQLGetDataPtr)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
SQLRETURN (SQL_API*SQLGetDiagFieldAPtr)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
SQLRETURN (SQL_API*SQLGetDiagRecWPtr)(SQLSMALLINT,SQLHANDLE,SQLSMALLINT,SQLWCHAR*,SQLINTEGER*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
+ SQLRETURN (SQL_API*SQLGetInfoWPtr)(SQLHANDLE,SQLUSMALLINT,SQLPOINTER,SQLSMALLINT,SQLSMALLINT*);
SQLRETURN (SQL_API*SQLGetTypeInfoPtr)(SQLHSTMT,SQLSMALLINT);
SQLRETURN (SQL_API*SQLMoreResultsPtr)(SQLHSTMT);
SQLRETURN (SQL_API*SQLNumParamsPtr)(SQLHSTMT,SQLSMALLINT*);
@@ -65,6 +63,7 @@ typedef struct odbcStubDefs {
#define SQLGetData (odbcStubs->SQLGetDataPtr)
#define SQLGetDiagFieldA (odbcStubs->SQLGetDiagFieldAPtr)
#define SQLGetDiagRecW (odbcStubs->SQLGetDiagRecWPtr)
+#define SQLGetInfoW (odbcStubs->SQLGetInfoWPtr)
#define SQLGetTypeInfo (odbcStubs->SQLGetTypeInfoPtr)
#define SQLMoreResults (odbcStubs->SQLMoreResultsPtr)
#define SQLNumParams (odbcStubs->SQLNumParamsPtr)
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/tdbcodbc.c b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/tdbcodbc.c
index 2dd4e12..c74dc43 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/generic/tdbcodbc.c
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/generic/tdbcodbc.c
@@ -49,6 +49,8 @@ static Tcl_LoadHandle odbcInstLoadHandle = NULL;
static SQLHENV hEnv = SQL_NULL_HENV;
/* Handle to the global ODBC environment */
static int hEnvRefCount = 0; /* Reference count on the global environment */
+static int sizeofSQLWCHAR = sizeof(SQLWCHAR);
+ /* Preset, will be autodetected later */
/*
* Objects to create within the literal pool
@@ -389,7 +391,7 @@ static int GetResultSetDescription(Tcl_Interp* interp, ResultSetData* rdata);
static int ConfigureConnection(Tcl_Interp* interp,
SQLHDBC hDBC,
PerInterpData* pidata,
- int objc, Tcl_Obj *CONST objv[],
+ int objc, Tcl_Obj *const objv[],
SQLUSMALLINT* connectFlagsPtr,
HWND* hParentWindowPtr);
static int ConnectionConstructor(ClientData clientData, Tcl_Interp* interp,
@@ -783,10 +785,33 @@ DStringAppendWChars(
int len /* Length of the input string in characters */
) {
int i;
- char buf[TCL_UTF_MAX];
- for (i = 0; i < len; ++i) {
- int bytes = Tcl_UniCharToUtf((int) ws[i], buf);
- Tcl_DStringAppend(ds, buf, bytes);
+ char buf[4] = "";
+
+ if (sizeofSQLWCHAR == sizeof(unsigned short)) {
+ unsigned short* ptr16 = (unsigned short*) ws;
+
+ for (i = 0; i < len; ++i) {
+ unsigned int ch;
+ int bytes;
+
+ ch = ptr16[i];
+ bytes = Tcl_UniCharToUtf(ch, buf);
+ Tcl_DStringAppend(ds, buf, bytes);
+ }
+ } else {
+ unsigned int* ptr32 = (unsigned int*) ws;
+
+ for (i = 0; i < len; ++i) {
+ unsigned int ch;
+ int bytes;
+
+ ch = ptr32[i];
+ if (ch > 0x10ffff) {
+ ch = 0xfffd;
+ }
+ bytes = Tcl_UniCharToUtf(ch, buf);
+ Tcl_DStringAppend(ds, buf, bytes);
+ }
}
}
@@ -813,20 +838,88 @@ GetWCharStringFromObj(
Tcl_Obj* obj, /* Tcl object whose string rep is desired */
int* lengthPtr /* Length of the string */
) {
- int len = Tcl_GetCharLength(obj);
- /* Length of the input string in characters */
- SQLWCHAR* retval = (SQLWCHAR*) ckalloc((len + 1) * sizeof(SQLWCHAR));
- /* Buffer to hold the converted string */
- char* bytes = Tcl_GetString(obj);
+ int len; /* Length of the input string in bytes */
+ char* bytes = Tcl_GetStringFromObj(obj, &len);
/* UTF-8 representation of the input string */
- int i;
- Tcl_UniChar ch;
+ char* end = bytes + len; /* End of UTF-8 representation */
+ SQLWCHAR* retval; /* Buffer to hold the converted string */
+ SQLWCHAR* wcPtr;
+ int shrink = 0;
+ Tcl_UniChar ch = 0;
+
+ len = (len + 1) * sizeofSQLWCHAR;
+ if (sizeofSQLWCHAR < sizeof(Tcl_UniChar)) {
+ len *= 2; /* doubled space for surrogates */
+ shrink = 1;
+ }
+ retval = wcPtr = (SQLWCHAR*) ckalloc(len);
+
+ if (sizeofSQLWCHAR == sizeof(unsigned short)) {
+ unsigned short *ptr16 = (unsigned short*) wcPtr;
+
+ while (bytes < end) {
+ unsigned int uch;
+
+ if (Tcl_UtfCharComplete(bytes, end - bytes)) {
+ bytes += Tcl_UtfToUniChar(bytes, &ch);
+ } else {
+ ch = *bytes++ & 0x00ff;
+ }
+ uch = ch;
+#if TCL_UTF_MAX > 4
+ if (uch > 0xffff) {
+ *ptr16++ = (((uch - 0x10000) >> 10) & 0x3ff) | 0xd800;
+ uch = ((uch - 0x10000) & 0x3ff) | 0xdc00;
+ }
+#endif
+ if (uch > 0x7f) {
+ shrink = 1;
+ }
+ *ptr16++ = uch;
+ }
+ *ptr16 = 0;
+ len = ptr16 - (unsigned short*) retval;
+ wcPtr = (SQLWCHAR*) ptr16;
+ } else {
+ unsigned int *ptr32 = (unsigned int*) wcPtr;
+
+ while (bytes < end) {
+ unsigned int uch;
+
+ if (Tcl_UtfCharComplete(bytes, end - bytes)) {
+ bytes += Tcl_UtfToUniChar(bytes, &ch);
+ } else {
+ ch = *bytes++ & 0x00ff;
+ }
+ uch = ch;
+#if TCL_UTF_MAX <= 4
+ if ((uch & 0xfc00) == 0xd800) {
+ if (Tcl_UtfCharComplete(bytes, end - bytes)) {
+ len = Tcl_UtfToUniChar(bytes, &ch);
+ if ((ch & 0xfc00) == 0xdc00) {
+ bytes += len;
+ uch = (((uch & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
+ }
+ }
+ }
+#endif
+ if (uch > 0x7f) {
+ shrink = 1;
+ }
+ *ptr32++ = uch;
+ }
+ *ptr32 = 0;
+ len = ptr32 - (unsigned int*) retval;
+ wcPtr = (SQLWCHAR*) ptr32;
+ }
- for (i = 0; i < len; ++i) {
- bytes += Tcl_UtfToUniChar(bytes, &ch);
- retval[i] = ch;
+ if (shrink) {
+ /* Shrink buffer to fit result */
+ wcPtr = (SQLWCHAR*) ckrealloc(retval, (len + 1) * sizeofSQLWCHAR);
+ if (wcPtr != NULL) {
+ retval = wcPtr;
+ }
}
- retval[i] = 0;
if (lengthPtr != NULL) {
*lengthPtr = len;
}
@@ -860,10 +953,10 @@ TransferSQLError(
SQLHANDLE handle, /* Handle that reported the error */
const char* info /* Additional information to report */
) {
- SQLWCHAR state[6]; /* SQL state code */
+ SQLWCHAR state[6*2]; /* SQL state code */
SQLINTEGER nativeError; /* Native error code */
SQLSMALLINT msgLen; /* Length of the error message */
- SQLWCHAR msg[SQL_MAX_MESSAGE_LENGTH];
+ SQLWCHAR msg[(SQL_MAX_MESSAGE_LENGTH+1)*2];
/* Buffer to hold the error message */
SQLSMALLINT i; /* Loop index for going through diagnostics */
const char* sep = ""; /* Separator string for messages */
@@ -872,8 +965,7 @@ TransferSQLError(
Tcl_Obj* codeObj; /* Error code object */
Tcl_Obj* lineObj; /* Object holding one diagnostic */
Tcl_DString bufferDS; /* Buffer for transferring messages */
-
- SQLRETURN sqlreturn;
+ SQLRETURN rc; /* SQL result */
resultObj = Tcl_NewObj();
codeObj = Tcl_NewStringObj("TDBC", -1);
@@ -881,9 +973,15 @@ TransferSQLError(
/* Loop through the diagnostics */
i = 1;
- while ((sqlreturn = SQLGetDiagRecW(handleType, handle, i, state, &nativeError,
- msg, SQL_MAX_MESSAGE_LENGTH, &msgLen))
- != SQL_NO_DATA && sqlreturn >= 0) {
+ while (1) {
+ msg[0] = msg[1] = 0;
+ msgLen = 0;
+ state[0] = state[1] = 0;
+ rc = SQLGetDiagRecW(handleType, handle, i, state, &nativeError,
+ msg, SQL_MAX_MESSAGE_LENGTH, &msgLen);
+ if (!SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA) {
+ break;
+ }
/* Add the diagnostic to ::errorCode */
@@ -955,11 +1053,17 @@ SQLStateIs(
SQLCHAR state[6]; /* SQL state code from the diagnostic record */
SQLSMALLINT stateLen; /* String length of the state code */
SQLSMALLINT i; /* Loop index */
+ SQLRETURN rc; /* SQL result */
i = 1;
- while (SQLGetDiagFieldA(handleType, handle, i, SQL_DIAG_SQLSTATE,
- (SQLPOINTER) state, sizeof (state), &stateLen)
- != SQL_NO_DATA) {
+ while (1) {
+ state[0] = 0;
+ stateLen = 0,
+ rc = SQLGetDiagFieldA(handleType, handle, i, SQL_DIAG_SQLSTATE,
+ (SQLPOINTER) state, sizeof(state), &stateLen);
+ if (!SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA) {
+ break;
+ }
if (stateLen >= 0 && !strcmp(sqlstate, (const char*) state)) {
return 1;
}
@@ -1083,11 +1187,11 @@ GetHEnv(
* Allocate the ODBC environment
*/
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
- if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+ if (SQL_SUCCEEDED(rc)) {
rc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3, 0);
}
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
/*
* The call failed. Report the error.
*/
@@ -1105,6 +1209,53 @@ GetHEnv(
Tcl_SetErrorCode(interp, "TDBC", "GENERAL_ERROR",
"HY001", "ODBC", "-1", NULL);
}
+ } else {
+ /*
+ * Detect real size of SQLWCHAR used by the driver manager.
+ */
+ SQLHDBC hDBC = SQL_NULL_HDBC;
+
+ sizeofSQLWCHAR = sizeof(SQLWCHAR); /* fallback */
+ rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDBC);
+ if (SQL_SUCCEEDED(rc)) {
+ SQLSMALLINT infoLen;
+ int i;
+ char info[64];
+
+ rc = SQLGetInfoW(hDBC, SQL_ODBC_VER, (SQLPOINTER) info,
+ sizeof(info), &infoLen);
+ if (SQL_SUCCEEDED(rc) && infoLen >= 8) {
+ static const char BE32sig[] = {
+ '\0', '\0', '\0', '#', '\0', '\0', '\0', '#'
+ };
+ static const char LE32sig[] = {
+ '#', '\0', '\0', '\0', '#', '\0', '\0', '\0'
+ };
+ static const char BE16sig[] = {
+ '\0', '#', '\0', '#'
+ };
+ static const char LE16sig[] = {
+ '#', '\0', '#', '\0'
+ };
+
+ if (infoLen > sizeof(info)) {
+ infoLen = sizeof(info);
+ }
+ for (i = 0; i < infoLen; i++) {
+ if (info[i] >= '0' && info[i] <= '9') {
+ info[i] = '#';
+ }
+ }
+ if (memcmp(info, BE32sig, sizeof(BE32sig)) == 0 ||
+ memcmp(info, LE32sig, sizeof(LE32sig)) == 0) {
+ sizeofSQLWCHAR = 4;
+ } else if (memcmp(info, BE16sig, sizeof(BE16sig)) == 0 ||
+ memcmp(info, LE16sig, sizeof(LE16sig)) == 0) {
+ sizeofSQLWCHAR = 2;
+ }
+ }
+ SQLFreeHandle(SQL_HANDLE_DBC, hDBC);
+ }
}
}
/*
@@ -1180,13 +1331,13 @@ AllocAndPrepareStatement(
return SQL_NULL_HSTMT;
}
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &hStmt);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
return SQL_NULL_HSTMT;
}
rc = SQLPrepareW(hStmt, sdata->nativeSqlW, sdata->nativeSqlLen);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_STMT, hStmt,
"(preparing statement)");
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
@@ -1223,7 +1374,7 @@ GetResultSetDescription(
SQLRETURN rc; /* Return code from ODBC operations */
Tcl_Obj* colNames; /* List of the column names */
SQLSMALLINT nColumns; /* Number of result set columns */
- SQLWCHAR colNameBuf[40]; /* Buffer to hold the column name */
+ SQLWCHAR colNameBuf[41*2]; /* Buffer to hold the column name */
SQLSMALLINT colNameLen = 40;
/* Length of the column name */
SQLSMALLINT colNameAllocLen = 40;
@@ -1252,7 +1403,7 @@ GetResultSetDescription(
/* Count the columns of the result set */
rc = SQLNumResultCols(hStmt, &nColumns);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_STMT, hStmt,
"(getting number of result columns)");
return TCL_ERROR;
@@ -1293,14 +1444,14 @@ GetResultSetDescription(
ckfree((char*) colNameW);
}
colNameW = (SQLWCHAR*)
- ckalloc(colNameAllocLen * sizeof(SQLWCHAR));
+ ckalloc(colNameAllocLen * sizeofSQLWCHAR);
retry = 1;
}
} while (retry);
/* Bail out on an ODBC error */
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char info[80];
sprintf(info, "(describing result column #%d)", i+1);
TransferSQLError(interp, SQL_HANDLE_STMT, hStmt, info);
@@ -1400,7 +1551,7 @@ ConfigureConnection(
SQLHDBC hDBC, /* Handle to the connection */
PerInterpData* pidata, /* Package-global data */
int objc, /* Option count */
- Tcl_Obj *CONST objv[], /* Option vector */
+ Tcl_Obj *const objv[], /* Option vector */
SQLUSMALLINT* connectFlagsPtr,
/* Pointer to the driver connection options */
HWND* hParentWindowPtr /* Handle to the parent window for a
@@ -1473,7 +1624,7 @@ ConfigureConnection(
rc = SQLGetConnectAttr(hDBC, SQL_ATTR_TXN_ISOLATION,
(SQLPOINTER) &mode, 0, NULL);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(getting isolation level of connection)");
return TCL_ERROR;
@@ -1486,7 +1637,7 @@ ConfigureConnection(
rc = SQLGetConnectAttr(hDBC, SQL_ATTR_ACCESS_MODE,
(SQLPOINTER) &mode, 0, NULL);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(getting access mode of connection)");
return TCL_ERROR;
@@ -1499,7 +1650,7 @@ ConfigureConnection(
rc = SQLGetConnectAttr(hDBC, SQL_ATTR_CONNECTION_TIMEOUT,
(SQLPOINTER)&seconds, 0, NULL);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
if (SQLStateIs(SQL_HANDLE_DBC, hDBC, "HYC00")) {
seconds = 0;
} else {
@@ -1544,7 +1695,7 @@ ConfigureConnection(
case COPTION_ISOLATION:
rc = SQLGetConnectAttr(hDBC, SQL_ATTR_TXN_ISOLATION,
(SQLPOINTER) &mode, 0, NULL);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(getting isolation level of connection)");
return TCL_ERROR;
@@ -1565,7 +1716,7 @@ ConfigureConnection(
case COPTION_READONLY:
rc = SQLGetConnectAttr(hDBC, SQL_ATTR_ACCESS_MODE,
(SQLPOINTER) &mode, 0, NULL);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(getting access mode of connection)");
return TCL_ERROR;
@@ -1580,7 +1731,7 @@ ConfigureConnection(
if (SQLStateIs(SQL_HANDLE_DBC, hDBC, "HYC00")) {
seconds = 0;
} else {
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(getting connection timeout value)");
return TCL_ERROR;
@@ -1640,8 +1791,8 @@ ConfigureConnection(
}
mode = isol;
rc = SQLSetConnectAttr(hDBC, SQL_ATTR_TXN_ISOLATION,
- (SQLPOINTER)mode, 0);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ (SQLPOINTER)(INT2PTR(mode)), 0);
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(setting isolation level of connection)");
return TCL_ERROR;
@@ -1711,8 +1862,8 @@ ConfigureConnection(
mode = SQL_MODE_READ_WRITE;
}
rc = SQLSetConnectAttr(hDBC, SQL_ATTR_ACCESS_MODE,
- (SQLPOINTER)mode, 0);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ (SQLPOINTER)(INT2PTR(mode)), 0);
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(setting access mode of connection)");
return TCL_ERROR;
@@ -1727,8 +1878,8 @@ ConfigureConnection(
}
seconds = (SQLINTEGER)((j + 999) / 1000);
rc = SQLSetConnectAttr(hDBC, SQL_ATTR_CONNECTION_TIMEOUT,
- (SQLPOINTER)seconds, 0);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ (SQLPOINTER)(INT2PTR(seconds)), 0);
+ if (!SQL_SUCCEEDED(rc)) {
/*
* A failure is OK if the SQL state is "Optional
* Function Not Implemented" and we were trying to set
@@ -1779,14 +1930,15 @@ ConnectionConstructor(
/* The current connection object */
int skip = Tcl_ObjectContextSkippedArgs(objectContext);
/* Number of leading args to skip */
- SQLHDBC hDBC; /* Handle to the database connection */
+ SQLHDBC hDBC = SQL_NULL_HDBC;
+ /* Handle to the database connection */
SQLRETURN rc; /* Return code from ODBC calls */
HWND hParentWindow = NULL; /* Windows handle of the main window */
SQLWCHAR* connectionStringReq;
/* Connection string requested by the caller */
int connectionStringReqLen;
/* Length of the requested connection string */
- SQLWCHAR connectionString[1025];
+ SQLWCHAR connectionString[1025*2];
/* Connection string actually used */
SQLSMALLINT connectionStringLen;
/* Length of the actual connection string */
@@ -1812,7 +1964,7 @@ ConnectionConstructor(
*/
rc = SQLAllocHandle(SQL_HANDLE_DBC, pidata->hEnv, (SQLHANDLE*) &hDBC);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_ENV, pidata->hEnv,
"(allocating connection handle)");
return TCL_ERROR;
@@ -1844,7 +1996,7 @@ ConnectionConstructor(
Tcl_SetObjResult(interp, Tcl_NewStringObj("operation cancelled", -1));
SQLFreeHandle(SQL_HANDLE_DBC, hDBC);
return TCL_ERROR;
- } else if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ } else if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, hDBC,
"(connecting to database)");
SQLFreeHandle(SQL_HANDLE_DBC, hDBC);
@@ -2043,7 +2195,7 @@ ConnectionEndXcnMethod(
rc = SQLEndTran(SQL_HANDLE_DBC, cdata->hDBC, completionType);
cdata->flags &= ~ CONNECTION_FLAG_XCN_ACTIVE;
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(ending the transaction)");
return TCL_ERROR;
@@ -2176,20 +2328,9 @@ SetAutocommitFlag(
SQLINTEGER flag /* Auto-commit indicator */
) {
SQLRETURN rc;
-#if 0
- /*
- * This form is allegedly preferred, but fails with the Windows
- * SQLite3 driver
- */
rc = SQLSetConnectAttr(cdata->hDBC, SQL_ATTR_AUTOCOMMIT,
- (SQLPOINTER) flag, 0);
-#else
- /*
- * This form is deprecated, but actually works.
- */
- rc = SQLSetConnectOption(cdata->hDBC, SQL_AUTOCOMMIT, flag);
-#endif
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ (SQLPOINTER)(INT2PTR(flag)), 0);
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(changing the 'autocommit' attribute)");
return TCL_ERROR;
@@ -2499,7 +2640,7 @@ StatementConstructor(
sdata->params[j].flags = PARAM_IN;
}
rc = SQLNumParams(sdata->hStmt, &nParams);
- if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+ if (SQL_SUCCEEDED(rc)) {
if (nParams != i) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("The SQL statement appears "
@@ -2523,7 +2664,7 @@ StatementConstructor(
&(sdata->params[i].precision),
&(sdata->params[i].scale),
&(sdata->params[i].nullable));
- if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+ if (SQL_SUCCEEDED(rc)) {
/*
* FIXME: SQLDescribeParam doesn't actually describe
* the direction of parameter transmission for
@@ -2858,7 +2999,7 @@ TablesStatementConstructor(
/* Allocate an ODBC statement handle */
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &(sdata->hStmt));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
goto freeSData;
@@ -2961,7 +3102,7 @@ ColumnsStatementConstructor(
/* Allocate an ODBC statement handle */
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &(sdata->hStmt));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
goto freeSData;
@@ -3064,7 +3205,7 @@ PrimarykeysStatementConstructor(
/* Allocate an ODBC statement handle */
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &(sdata->hStmt));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
goto freeSData;
@@ -3214,7 +3355,7 @@ ForeignkeysStatementConstructor(
/* Allocate an ODBC statement handle */
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &(sdata->hStmt));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
goto freeSData;
@@ -3314,7 +3455,7 @@ TypesStatementConstructor(
/* Allocate an ODBC statement handle */
rc = SQLAllocHandle(SQL_HANDLE_STMT, cdata->hDBC, &(sdata->hStmt));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_DBC, cdata->hDBC,
"(allocating statement handle)");
goto freeSData;
@@ -3699,7 +3840,7 @@ ResultSetConstructor(
rdata->bindStrings[nBound] = (SQLCHAR*)
GetWCharStringFromObj(paramValObj, &paramLen);
rdata->bindStringLengths[nBound] = paramExternalLen =
- paramLen * sizeof(SQLWCHAR);
+ paramLen * sizeofSQLWCHAR;
} else {
@@ -3743,7 +3884,7 @@ ResultSetConstructor(
rdata->bindStrings[nBound],
paramExternalLen,
rdata->bindStringLengths + nBound);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char* info = ckalloc(80 * strlen(paramName));
sprintf(info, "(binding the '%s' parameter)", paramName);
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt, info);
@@ -3775,8 +3916,7 @@ ResultSetConstructor(
} else {
rc = SQLExecute(rdata->hStmt);
}
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO
- && rc != SQL_NO_DATA) {
+ if (!SQL_SUCCEEDED(rc) && rc != SQL_NO_DATA) {
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
"(executing the statement)");
return TCL_ERROR;
@@ -3788,13 +3928,20 @@ ResultSetConstructor(
return TCL_ERROR;
}
- /* Determine and store the row count */
+ /* Determine and store the row count. Note: iodbc makes it illegal
+ * to call SQLRowCount after an operation has returned SQL_NO_DATA,
+ * so bypass the SQLRowCount call if there are no results.
+ */
- rc = SQLRowCount(rdata->hStmt, &(rdata->rowCount));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
- TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
- "(counting rows in the result)");
- return TCL_ERROR;
+ if (rc == SQL_NO_DATA) {
+ rdata->rowCount = 0;
+ } else {
+ rc = SQLRowCount(rdata->hStmt, &(rdata->rowCount));
+ if (!SQL_SUCCEEDED(rc)) {
+ TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
+ "(counting rows in the result)");
+ return TCL_ERROR;
+ }
}
return TCL_OK;
@@ -3907,7 +4054,7 @@ ResultSetNextresultsMethod(
Tcl_SetObjResult(interp, literals[LIT_0]);
return TCL_OK;
}
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
"(advancing to next result set)");
return TCL_ERROR;
@@ -3919,7 +4066,7 @@ ResultSetNextresultsMethod(
/* Determine and store the row count */
rc = SQLRowCount(rdata->hStmt, &(rdata->rowCount));
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
"(counting rows in the result)");
return TCL_ERROR;
@@ -4019,7 +4166,7 @@ ResultSetNextrowMethod(
if (rc == SQL_NO_DATA) {
Tcl_SetObjResult(interp, literals[LIT_0]);
return TCL_OK;
- } else if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ } else if (!SQL_SUCCEEDED(rc)) {
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt,
"(fetching the next row of the result set)");
return TCL_ERROR;
@@ -4095,12 +4242,13 @@ GetCell(
StatementData* sdata = rdata->sdata;
ConnectionData* cdata = sdata->cdata;
SQLSMALLINT dataType; /* Type of character data to retrieve */
- SQLWCHAR colWBuf[BUFSIZE+1];/* Buffer to hold the string value of a
+ SQLWCHAR colWBuf[(BUFSIZE+1)*2];
+ /* Buffer to hold the string value of a
* column */
SQLCHAR* colBuf = (SQLCHAR*) colWBuf;
SQLCHAR* colPtr = colBuf; /* Pointer to the current allocated buffer
* (which may have grown) */
- SQLLEN colAllocLen = BUFSIZE * sizeof(SQLWCHAR);
+ SQLLEN colAllocLen = BUFSIZE * sizeofSQLWCHAR;
/* Current allocated size of the buffer,
* in bytes */
SQLLEN colLen; /* Actual size of the return value, in bytes */
@@ -4154,7 +4302,7 @@ GetCell(
colLen = sizeof(colWide); colWide = 0;
rc = SQLGetData(rdata->hStmt, i+1, SQL_C_SBIGINT,
(SQLPOINTER) &colWide, sizeof(colWide), &colLen);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char info[80];
sprintf(info, "(retrieving result set column #%d)\n", i+1);
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt, info);
@@ -4174,7 +4322,7 @@ GetCell(
colLen = sizeof(colLong); colLong = 0;
rc = SQLGetData(rdata->hStmt, i+1, SQL_C_SLONG,
(SQLPOINTER) &colLong, sizeof(colLong), &colLen);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char info[80];
sprintf(info, "(retrieving result set column #%d)\n", i+1);
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt, info);
@@ -4208,7 +4356,7 @@ GetCell(
rc = SQLGetData(rdata->hStmt, i+1, SQL_C_DOUBLE,
(SQLPOINTER) &colDouble, sizeof(colDouble),
&colLen);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char info[80];
sprintf(info, "(retrieving result set column #%d)\n", i+1);
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt, info);
@@ -4278,7 +4426,7 @@ GetCell(
} else if (dataType == SQL_C_CHAR) {
--offset;
} else {
- offset -= sizeof(SQLWCHAR);
+ offset -= sizeofSQLWCHAR;
}
if (colLen == SQL_NO_TOTAL) {
/*
@@ -4291,16 +4439,16 @@ GetCell(
colAllocLen += colLen;
}
if (colPtr == colBuf) {
- colPtr = (SQLCHAR*) ckalloc(colAllocLen + sizeof(SQLWCHAR));
- memcpy(colPtr, colBuf, BUFSIZE * sizeof(SQLWCHAR));
+ colPtr = (SQLCHAR*) ckalloc(colAllocLen + sizeofSQLWCHAR);
+ memcpy(colPtr, colBuf, BUFSIZE * sizeofSQLWCHAR);
} else {
colPtr = (SQLCHAR*)
- ckrealloc((char*)colPtr, colAllocLen + sizeof(SQLWCHAR));
+ ckrealloc((char*)colPtr, colAllocLen + sizeofSQLWCHAR);
}
retry = 1;
}
} while (retry);
- if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
+ if (!SQL_SUCCEEDED(rc)) {
char info[80];
sprintf(info, "(retrieving result set column #%d)\n", i+1);
TransferSQLError(interp, SQL_HANDLE_STMT, rdata->hStmt, info);
@@ -4322,7 +4470,7 @@ GetCell(
} else {
DStringAppendWChars(&colDS, (SQLWCHAR*) colPtr,
(int)((colLen + offset)
- / sizeof(SQLWCHAR)));
+ / sizeofSQLWCHAR));
}
colObj = Tcl_NewStringObj(Tcl_DStringValue(&colDS),
Tcl_DStringLength(&colDS));
@@ -4531,7 +4679,7 @@ DatasourcesObjCmd(
};
int flagIndex;
SQLRETURN rc; /* SQL result code */
- SQLWCHAR serverName[SQL_MAX_DSN_LENGTH + 1];
+ SQLWCHAR serverName[(SQL_MAX_DSN_LENGTH+1)*2];
/* Data source name */
SQLSMALLINT serverNameLen; /* Length of the DSN */
SQLWCHAR *description; /* Data source descroption */
@@ -4573,7 +4721,7 @@ DatasourcesObjCmd(
finished = 1;
descAllocLen = descLenNeeded;
description = (SQLWCHAR*)
- ckalloc(sizeof(SQLWCHAR) * (descAllocLen + 1));
+ ckalloc(sizeofSQLWCHAR * (descAllocLen + 1));
Tcl_SetListObj(retval, 0, NULL);
/* Enumerate the data sources */
@@ -4592,7 +4740,7 @@ DatasourcesObjCmd(
finished = 0;
break;
- } else if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+ } else if (SQL_SUCCEEDED(rc)) {
/* Got a data source; add key and value to the dictionary */
@@ -4704,11 +4852,11 @@ DriversObjCmd(
finished = 1;
driverAllocLen = driverLenNeeded;
driver = (SQLWCHAR*)
- ckalloc(sizeof(SQLWCHAR) * (driverAllocLen + 1));
+ ckalloc(sizeofSQLWCHAR * (driverAllocLen + 1));
*driver = 0;
attrAllocLen = attrLenNeeded;
attributes = (SQLWCHAR*)
- ckalloc(sizeof(SQLWCHAR) * (attrAllocLen + 1));
+ ckalloc(sizeofSQLWCHAR * (attrAllocLen + 1));
*attributes = 0;
Tcl_SetListObj(retval, 0, NULL);
direction = SQL_FETCH_FIRST;
@@ -4739,7 +4887,7 @@ DriversObjCmd(
}
if (finished) {
- if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
+ if (SQL_SUCCEEDED(rc)) {
/* Got a data source; add key and value to the dictionary */
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/library/tdbcodbc.tcl b/tcl8.6/pkgs/tdbcodbc1.1.0/library/tdbcodbc.tcl
index 0b19a4b..0b19a4b 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/library/tdbcodbc.tcl
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/library/tdbcodbc.tcl
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/license.terms b/tcl8.6/pkgs/tdbcodbc1.1.0/license.terms
index 6f644fd..6f644fd 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/license.terms
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/license.terms
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbcodbc1.1.0/pkgIndex.tcl.in
index 448b4ba..98522ca 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/pkgIndex.tcl.in
@@ -1,4 +1,4 @@
-# Package index file for tdbc::odbc
+# Index file to load the TDBC ODBC package.
if {[catch {package require Tcl @TCL_VERSION_REQ@}]} {
return
diff --git a/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/README.txt b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension. For more information on TEA see:
+
+ http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+ http://tcl.sourceforge.net/
+
+This package is a freely available open source package. You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt This file
+
+install-sh Program used for copying binaries and script files
+ to their install locations.
+
+tcl.m4 Collection of Tcl autoconf macros. Included by a package's
+ aclocal.m4 to define TEA_* macros.
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/install-sh b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/tclconfig/install-sh
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/tcl.m4
new file mode 100644
index 0000000..2ec82a2
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tclconfig/tcl.m4
@@ -0,0 +1,4184 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+# 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
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig="${withval}")
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 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/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/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
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig="${withval}")
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+ else
+ no_tk=
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_PATCH_LEVEL)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ AC_MSG_CHECKING([platform])
+ hold_cc=$CC; CC="$TCL_CC"
+ AC_TRY_COMPILE(,[
+ #ifdef _WIN32
+ #error win32
+ #endif
+ ], [
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+ ], [
+ TEA_PLATFORM="windows"
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
+ )
+ CC=$hold_cc
+ AC_MSG_RESULT($TEA_PLATFORM)
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+ AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+ [Building extension source?])
+ # 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:
+ AC_SUBST(CLEANFILES)
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FLAG)
+ AC_SUBST(TK_LIB_SPEC)
+
+ AC_SUBST(TK_STUB_LIB_FILE)
+ AC_SUBST(TK_STUB_LIB_FLAG)
+ AC_SUBST(TK_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+# --enable-stubs=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+# 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)]),
+ [shared_ok=$enableval], [shared_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ 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
+
+ # 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, [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)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol defaults to
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $PACKAGE_VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${PACKAGE_VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # 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
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+ ], [
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+ ])
+ AC_CHECK_TOOL(AR, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
+ 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
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[[4-9]]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+ TEA_ADD_LIBS([ucrt.lib])
+ ;;
+ *)
+ ;;
+ 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
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ 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
+ AC_CHECK_TOOL(RC, windres)
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ AC_CACHE_CHECK(for cross-compile version of gcc,
+ ac_cv_cross,
+ AC_TRY_COMPILE([
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+ ], [],
+ ac_cv_cross=yes,
+ ac_cv_cross=no)
+ )
+ 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-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+ ], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+ ])
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ 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.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ 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} ${CFLAGS} ${LDFLAGS} -shared'
+ AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ ])
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ CFLAGS_OPTIMIZE="-O2"
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+ ])
+ # 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} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ;;
+ DragonFly-*|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=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+ 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}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and 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:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ tcl_cv_cc_visibility_hidden=yes
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+ tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+ tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done])
+ ])
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ ], [
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+ ])
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ 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.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # 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.
+
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
+ IRIX*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [extern],
+ [No Compiler support for module scope symbols])
+ ])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+ AC_TRY_RUN([
+#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;
+ }
+ ],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+ )
+ if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH, 1,
+ [Defined when mingw does not support SEH])
+ 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.
+ #
+ AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+ tcl_cv_eh_disposition,
+ AC_TRY_COMPILE([
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+ ],[
+ EXCEPTION_DISPOSITION x;
+ ],
+ tcl_cv_eh_disposition=yes,
+ tcl_cv_eh_disposition=no)
+ )
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+ AC_DEFINE(EXCEPTION_DISPOSITION, int,
+ [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+ 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.
+
+ AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+ tcl_cv_winnt_ignore_void,
+ AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+ ], [
+ CHAR c;
+ SHORT s;
+ LONG l;
+ ],
+ tcl_cv_winnt_ignore_void=yes,
+ tcl_cv_winnt_ignore_void=no)
+ )
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+ [Defined when cygwin/mingw ignores VOID define in winnt.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.
+
+ AC_CACHE_CHECK(for cast to union support,
+ tcl_cv_cast_to_union,
+ AC_TRY_COMPILE([],
+ [
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+ ],
+ tcl_cv_cast_to_union=yes,
+ tcl_cv_cast_to_union=no)
+ )
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+ AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+ [Defined when compiler supports casting to union type.])
+ fi
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# Locate the X11 header files and the X11 library archive. Try
+# the ac_path_x macro first, but if it doesn't find the X stuff
+# (e.g. because there's no xmkmf program) then check through
+# a list of possible directories. Under some conditions the
+# autoconf macro will return an include directory that contains
+# no include files, so double-check its result just to be safe.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Xlib.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Xlib.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test "$found_xincludes" = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" (provided by Tcl) that corrects the error.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ TEA_VERSION="3.13"
+
+ AC_MSG_CHECKING([TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.ac])
+ fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+
+ # 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_*|*MINGW64_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ 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
+
+ AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
+ i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+# Specify one or more CLEANFILES.
+#
+# Arguments:
+# one or more file names to clean target
+#
+# Results:
+#
+# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+ CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ AC_PROG_CC
+ AC_PROG_CPP
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_CHECK_TOOL(RANLIB, ranlib)
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ AC_CACHE_CHECK([if the compiler understands -pipe],
+ tcl_cv_cc_pipe, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+ ], [
+ # 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}"
+ TEA_ADD_CLEANFILES([*.manifest])
+ ])
+ 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
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+ AC_SUBST(VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(VC_MANIFEST_EMBED_EXE)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tcl<Plat>Port.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tk<Plat>Port.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ fi
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+ $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ AS_IF([test "x$2" = x], [
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+ [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+ [TEA_LOAD_CONFIG_LIB($1_STUB)])
+ ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+# Helper function to load correct library from another extension's
+# ${PACKAGE}Config.sh.
+#
+# Results:
+# Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+ AC_MSG_CHECKING([For $1 library for LIBS])
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${$1_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+ TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+ AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+ else
+ TEA_ADD_LIBS([${$1_LIB_SPEC}])
+ AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+ fi
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+# Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1
+#
+# Results:
+# Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+ #--------------------------------------------------------------------
+ # These are for $1Config.sh
+ #--------------------------------------------------------------------
+
+ # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+ eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+ if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+ else
+ eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ fi
+ $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
+ $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
+ $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
+ $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
+
+ AC_SUBST($1_BUILD_LIB_SPEC)
+ AC_SUBST($1_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_PATH)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ AC_SUBST(MAJOR_VERSION)
+ AC_SUBST(MINOR_VERSION)
+ AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
+###
+# Tip 430 - ZipFS Modifications
+###
+#------------------------------------------------------------------------
+# SC_ZIPFS_SUPPORT
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+# TCL_ZIPFS_FLAG
+# ZIP_PROG
+#------------------------------------------------------------------------
+
+#------------------------------------------------------------------------
+# SC_PROG_ZIP
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# ZIP_PROG
+# ZIP_PROG_OPTIONS
+# ZIP_PROG_VFSSEARCH
+# ZIP_INSTALL_OBJS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ZIPFS_SUPPORT], [
+ AC_MSG_CHECKING([for zipfs support])
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ INSTALL_MSGS=""
+ # If our native tclsh processes the "install" command line option
+ # we can use it to mint zip files
+ AS_IF([$TCLSH_PROG install],[
+ ZIP_PROG=${TCLSH_PROG}
+ ZIP_PROG_OPTIONS="install mkzip"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
+ ])
+ if test "x$ZIP_PROG" = "x" ; then
+ AC_CACHE_VAL(ac_cv_path_zip, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip "
+ AC_MSG_RESULT([$ZIP_PROG])
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Found INFO Zip in environment])
+ # Use standard arguments for zip
+ fi
+ fi
+ if test "x$ZIP_PROG" = "x" ; then
+ # It is not an error if an installed version of Zip can't be located.
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ else
+ # ZIPFS Support
+ eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
+ if test ${TCL_ZIP_FILE} = "" ; then
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ INSTALL_LIBRARIES=install-libraries
+ INSTALL_MSGS=install-msgs
+ else
+ if test ${SHARED_BUILD} = 1 ; then
+ TCL_ZIPFS_SUPPORT=1
+ INSTALL_LIBRARIES=install-libraries-zipfs-shared
+ else
+ TCL_ZIPFS_SUPPORT=2
+ INSTALL_LIBRARIES=install-libraries-zipfs-static
+ fi
+ TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
+ fi
+ fi
+
+ AC_SUBST(TCL_ZIP_FILE)
+ AC_SUBST(TCL_ZIPFS_SUPPORT)
+ AC_SUBST(TCL_ZIPFS_FLAG)
+ AC_SUBST(ZIP_PROG)
+ AC_SUBST(ZIP_PROG_OPTIONS)
+ AC_SUBST(ZIP_PROG_VFSSEARCH)
+ AC_SUBST(INSTALL_LIBRARIES)
+ AC_SUBST(INSTALL_MSGS)
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/tests/all.tcl b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/all.tcl
index b3b13a6..b3b13a6 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/tests/all.tcl
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/all.tcl
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/tdbcodbc.test b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/tdbcodbc.test
index 4bafb37..c287ed2 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/tdbcodbc.test
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/tdbcodbc.test
@@ -132,7 +132,7 @@ test tdbc::odbc-1.3 {create a connection, failure} {*}{
list $status $::errorCode
}
-match glob
- -result {1 {TDBC DRIVER_ERROR IM002 ODBC *}}
+ -result {1 *}
}
@@ -2237,7 +2237,7 @@ test tdbc::odbc-14.4 {commit - not in transaction} {*}{
list [catch {::db commit} result] $result $::errorCode
}
-match glob
- -result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY010 ODBC *}}
+ -result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY* ODBC *}}
}
test tdbc::odbc-14.5 {rollback - not in transaction} {*}{
@@ -2245,7 +2245,7 @@ test tdbc::odbc-14.5 {rollback - not in transaction} {*}{
list [catch {::db rollback} result] $result $::errorCode
}
-match glob
- -result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY010 ODBC *}}
+ -result {1 {no transaction is in progress} {TDBC GENERAL_ERROR HY* ODBC *}}
}
test tdbc::odbc-14.6 {empty transaction} {*}{
@@ -2701,7 +2701,8 @@ test tdbc::odbc-19.3 {$connection configure - inappropriate arg} {*}{
-body {
list [catch {::db configure -parent} result] $::errorCode
}
- -result {1 {TDBC GENERAL_ERROR HY010 ODBC -1}}
+ -match glob
+ -result {1 {TDBC GENERAL_ERROR HY* ODBC -1}}
}
test tdbc::odbc-19.4 {$connection configure - set unknown arg} {*}{
@@ -2717,7 +2718,8 @@ test tdbc::odbc-19.5 {$connection configure - set inappropriate arg} {*}{
-body {
list [catch {::db configure -parent .} result] $::errorCode
}
- -result {1 {TDBC GENERAL_ERROR HY010 ODBC -1}}
+ -match glob
+ -result {1 {TDBC GENERAL_ERROR HY* ODBC -1}}
}
test tdbc::odbc-19.6 {$connection configure - wrong # args} {*}{
@@ -2766,7 +2768,7 @@ test tdbc::odbc-19.10 {$connection configure - -isolation} {*}{
}
test tdbc::odbc-19.11a {$connection configure - -isolation} {*}{
- -constraints !win||!sqlite
+ -constraints !sqlite
-body {
list [::db configure -isolation readcommitted] \
[::db configure -isolation]
@@ -2774,7 +2776,7 @@ test tdbc::odbc-19.11a {$connection configure - -isolation} {*}{
-result {{} readcommitted}
}
test tdbc::odbc-19.11b {$connection configure - -isolation} {*}{
- -constraints win&&sqlite
+ -constraints sqlite
-body {
list [::db configure -isolation readcommitted] \
[::db configure -isolation]
@@ -3062,7 +3064,7 @@ test tdbc::odbc-25.1a {error code} {*}{
} result] $result $::errorCode
}
-match glob
- -result {1 * {TDBC GENERAL_ERROR HY000 ODBC *}}
+ -result {1 * {TDBC GENERAL_ERROR HY* ODBC *}}
}
test tbdc::odbc-25.1b {error code} {*}{
@@ -3664,8 +3666,6 @@ test tdbc::odbc-30.3 {Multiple result sets - try to read past end} {*}{
if {[$resultset nextresults] == 0} break
}
lappend rowsets [catch {$resultset nextresults} msg] $msg
- lappend rowsets [catch {$resultset nextrow foo} msg] \
- $::errorCode
set rowsets
} results
rename $resultset {}
@@ -3675,7 +3675,7 @@ test tdbc::odbc-30.3 {Multiple result sets - try to read past end} {*}{
set results
}
-match glob
- -result {{{idnum 2 name wilma}} 0 0 1 {TDBC GENERAL_ERROR HY010 *}}
+ -result {{{idnum 2 name wilma}} 0 0}
}
test tdbc::odbc-30.4 {Multiple result sets - foreach} {*}{
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/test.mdb b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/test.mdb
index 09dfd7f..09dfd7f 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/tests/test.mdb
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/tests/test.mdb
Binary files differ
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/win/makefile.vc b/tcl8.6/pkgs/tdbcodbc1.1.0/win/makefile.vc
index 6f0c19b..912df06 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/win/makefile.vc
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/win/makefile.vc
@@ -1,159 +1,159 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for TBDC ODBC interface
-#
-# Basic build, test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir test
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = tdbcodbc
-# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
-# without -DUNICODE. Keep that behaviour for now.
-USE_WIDECHAR_API = 0
-
-!include "rules-ext.vc"
-
-# nmakehelp -V <file> <tag> will search the file for tag, skips until a
-# number and returns all character until a character not in [0-9.ab]
-# is read.
-!if [echo REM = This file is generated from Makefile.vc > versions.vc]
-!endif
-!if [echo TCL_VERSION_REQ = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
-!endif
-!include "versions.vc"
-
-PRJ_OBJS = \
- $(TMP_DIR)\tdbcodbc.obj \
- $(TMP_DIR)\odbcStubInit.obj
-
-
-# Uncomment the following line if you want to build and install stubs
-# PRJ_STUBOBJS = $(TMP_DIR)\odbcStubInit.obj
-
-PRJ_HEADERS = \
- $(GENERICDIR)\fakesql.h \
- $(GENERICDIR)\odbcStubs.h
-
-# Locate TDBC headers and libraries.
-# In principle, we don't need the TDBC source directory, and an installed
-# TDBC should suffice. But that needs additional machinery not implemented
-# yet.
-!if [echo TDBC_DIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
-!error Could not locate TDBC source directory.
-!endif
-!include nmakehlp.out
-
-# Get the TDBC version from its configure.ac
-!if [echo TDBC_DOTVERSION = \> versions.vc] \
- && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
-!error Could not retrieve TDBC version.
-!endif
-!include versions.vc
-
-TDBC_VERSION = $(TDBC_DOTVERSION:.=)
-TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
-TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
-TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
-TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
-TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
-
-PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
-PRJ_DEFINES = -Dinline=__inline
-
-!if !$(STATIC_BUILD)
-PRJ_LIBS = $(TDBCSTUBLIB)
-!endif
-
-# Disable standard tes target because we have a custom one.
-DISABLE_TARGET_test = 1
-!include "$(_RULESDIR)\targets.vc"
-
-# Install needs some extra default actions.
-install: default-install-docs-n
-
-# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
-# all replacements below so define our own it.
-pkgindex: $(OUT_DIR)\pkgIndex.tcl
-$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
- @nmakehlp -s << $** > $@
-@PACKAGE_NAME@ $(PROJECT)
-@PACKAGE_VERSION@ $(DOTVERSION)
-@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-test: test-jet test-sqlserver test-sqlite
-
-test: setup $(PROJECT)
-
-test-jet: setup $(PROJECT)
- @echo testing tdbcodbc against Jet
- @set TDBCODBC_TYPE=jet
-# the following is identical for all 3 tests
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
- @set TDBC_LIBRARY=$(LIBDIR:\=/)
- @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
- -load "package ifneeded tdbc::odbc $(DOTVERSION) \
- {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
- package ifneeded tdbc $(TDBC_DOTVERSION) \
- {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
-!endif
-
-test-sqlserver: setup $(PROJECT)
- @echo testing tdbcodbc against SQL Server
- @set TDBCODBC_TYPE=sqlserver
-# the following is identical for all 3 tests
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
- @set TDBC_LIBRARY=$(LIBDIR:\=/)
- @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
- -load "package ifneeded tdbc::odbc $(DOTVERSION) \
- {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
- package ifneeded tdbc $(TDBC_DOTVERSION) \
- {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
-!endif
-
-test-sqlite: setup $(PROJECT)
- @echo testing tdbcodbc against SQLite
- @set TDBCODBC_TYPE=sqlite
-# the following is identical for all 3 tests
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
- @set TDBC_LIBRARY=$(LIBDIR:\=/)
- @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
- -load "package ifneeded tdbc::odbc $(DOTVERSION) \
- {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
- package ifneeded tdbc $(TDBC_DOTVERSION) \
- {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
-!endif
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for TBDC ODBC interface
+#
+# Basic build, test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir test
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = tdbcodbc
+# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
+# without -DUNICODE. Keep that behaviour for now.
+USE_WIDECHAR_API = 0
+
+!include "rules-ext.vc"
+
+# nmakehelp -V <file> <tag> will search the file for tag, skips until a
+# number and returns all character until a character not in [0-9.ab]
+# is read.
+!if [echo REM = This file is generated from Makefile.vc > versions.vc]
+!endif
+!if [echo TCL_VERSION_REQ = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
+!endif
+!include "versions.vc"
+
+PRJ_OBJS = \
+ $(TMP_DIR)\tdbcodbc.obj \
+ $(TMP_DIR)\odbcStubInit.obj
+
+
+# Uncomment the following line if you want to build and install stubs
+# PRJ_STUBOBJS = $(TMP_DIR)\odbcStubInit.obj
+
+PRJ_HEADERS = \
+ $(GENERICDIR)\fakesql.h \
+ $(GENERICDIR)\odbcStubs.h
+
+# Locate TDBC headers and libraries.
+# In principle, we don't need the TDBC source directory, and an installed
+# TDBC should suffice. But that needs additional machinery not implemented
+# yet.
+!if [echo TDBC_DIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
+!error Could not locate TDBC source directory.
+!endif
+!include nmakehlp.out
+
+# Get the TDBC version from its configure.ac
+!if [echo TDBC_DOTVERSION = \> versions.vc] \
+ && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
+!error Could not retrieve TDBC version.
+!endif
+!include versions.vc
+
+TDBC_VERSION = $(TDBC_DOTVERSION:.=)
+TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
+TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
+TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
+TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
+TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
+
+PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
+PRJ_DEFINES = -Dinline=__inline
+
+!if !$(STATIC_BUILD)
+PRJ_LIBS = $(TDBCSTUBLIB)
+!endif
+
+# Disable standard tes target because we have a custom one.
+DISABLE_TARGET_test = 1
+!include "$(_RULESDIR)\targets.vc"
+
+# Install needs some extra default actions.
+install: default-install-docs-n
+
+# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
+# all replacements below so define our own it.
+pkgindex: $(OUT_DIR)\pkgIndex.tcl
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+ @nmakehlp -s << $** > $@
+@PACKAGE_NAME@ $(PROJECT)
+@PACKAGE_VERSION@ $(DOTVERSION)
+@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+test: test-jet test-sqlserver test-sqlite
+
+test: setup $(PROJECT)
+
+test-jet: setup $(PROJECT)
+ @echo testing tdbcodbc against Jet
+ @set TDBCODBC_TYPE=jet
+# the following is identical for all 3 tests
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+ @set TDBC_LIBRARY=$(LIBDIR:\=/)
+ @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
+ -load "package ifneeded tdbc::odbc $(DOTVERSION) \
+ {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
+ package ifneeded tdbc $(TDBC_DOTVERSION) \
+ {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
+!endif
+
+test-sqlserver: setup $(PROJECT)
+ @echo testing tdbcodbc against SQL Server
+ @set TDBCODBC_TYPE=sqlserver
+# the following is identical for all 3 tests
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+ @set TDBC_LIBRARY=$(LIBDIR:\=/)
+ @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
+ -load "package ifneeded tdbc::odbc $(DOTVERSION) \
+ {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
+ package ifneeded tdbc $(TDBC_DOTVERSION) \
+ {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
+!endif
+
+test-sqlite: setup $(PROJECT)
+ @echo testing tdbcodbc against SQLite
+ @set TDBCODBC_TYPE=sqlite
+# the following is identical for all 3 tests
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
+ @set TDBC_LIBRARY=$(LIBDIR:\=/)
+ @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
+ -load "package ifneeded tdbc::odbc $(DOTVERSION) \
+ {source {$(LIBDIR:\=/)/tdbcodbc.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
+ package ifneeded tdbc $(TDBC_DOTVERSION) \
+ {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
+!endif
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/win/nmakehlp.c b/tcl8.6/pkgs/tdbcodbc1.1.0/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/win/nmakehlp.c
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/win/rules-ext.vc b/tcl8.6/pkgs/tdbcodbc1.1.0/win/rules-ext.vc
index ab86876..58c70fa 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/win/rules-ext.vc
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/win/rules-ext.vc
@@ -1,118 +1,118 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!ifdef TCLDIR
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/win/rules.vc b/tcl8.6/pkgs/tdbcodbc1.1.0/win/rules.vc
index bbb412d..7fc51c1 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/win/rules.vc
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/win/rules.vc
@@ -1,1723 +1,1723 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 0
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!message *** Using $(NMAKEHLPC)
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+# Old linkers (Visual C++ 6 in particular) will link for fast loading
+# on Win98. Since we do not support Win98 any more, we specify nowin98
+# as recommended for NT and later. However, this is only required by
+# IX86 on older compilers and only needed if we are not doing a static build.
+
+!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
+# Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!endif
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcodbc1.1.0/win/targets.vc b/tcl8.6/pkgs/tdbcodbc1.1.0/win/targets.vc
new file mode 100644
index 0000000..7f1d388
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcodbc1.1.0/win/targets.vc
@@ -0,0 +1,98 @@
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/ChangeLog b/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/ChangeLog
deleted file mode 100644
index 9504def..0000000
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/ChangeLog
+++ /dev/null
@@ -1,1003 +0,0 @@
-2016-03-11 Sean Woods <yoda@etoyoc.com>
- *tcl.m4 Fixed the search for Tcl and Wish shells under MinGW. Static builds and threaded builds
- get an "s" or "t" added to the name.
-
-2015-08-28 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Rfe [00189c4afc]: Allow semi-static UCRT build on
- Windows with VC 14.0
-
-2013-10-08 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [172223e008]: Wrong filename in
- --disable-shared compile on MinGW
-
-2013-10-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: stub library is no longer linked with msvcrt??.dll.
-
-2013-10-01 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Workaround for MinGW bug #2065: "gcc --shared" links
- with libgcc_s_dw2-1.dll when using 64-bit division in C
-
-2013-07-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [3324676]: AC_PROG_INSTALL incompat,
- Bug [3606445]: Unneeded -DHAVE_NO_SEH=1 when not building on Windows
-
-2013-07-02 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
- (thanks to Brian Griffin)
-
-2013-06-20 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Use X11/Xlib.h for checking where X11 can be found
- in stead of X11/XIntrinsic.h. Suggested by Pietro Cerutti.
-
-2013-06-04 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Eliminate NO_VIZ macro as current
- zlib uses HAVE_HIDDEN in stead. One more last-moment
- fix for FreeBSD by Pietro Cerutti
-
-2013-05-19 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Fix for FreeBSD, and remove support for old
- FreeBSD versions. Patch by Pietro Cerutti
-
-2013-03-12 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Patch by Andrew Shadura, providing better support for
- * three architectures they have in Debian.
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Added "-DNDEBUG" to CFLAGS_DEFAULT
- when building with --disable-symbols.
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: [Bug 3555058]: Checkin [30736d63f0] broke
- CFLAGS_DEFAULT, LDFLAGS_DEFAULT
-
-2012-08-07 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
-
-2012-08-07 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS
-
-2012-07-25 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: My previous commit (2012-04-03) broke the ActiveTcl
- build for AMD64, because of the quotes in "C:/<path>/AMD64/cl.exe".
- It turns out that the AC_TRY_COMPILE macro cannot handle that.
-
-2012-07-22 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Tidy: consistency, spelling, phrasing, whitespace.
- No functional change.
-
-2012-04-03 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 3511806] Compiler checks too early
- This change allows to build the cygwin and mingw32 ports of
- Tcl/Tk extensions to build out-of-the-box using a native or
- cross-compiler, e.g. on Cygwin, Linux or Darwin.
-
-2011-04-02 Jan Nijtmans <nijtmans@users.sf.net>
-
- * install-sh: Fix issue with library stripping in install-sh
- (backported from kevin_walzer's patch from Tcl 8.6 trunk)
-
-2011-04-05 Andreas Kupries <andreask@activestate.com>
-
- * tcl.m4: Applied patch by Jeff Lawson. Nicer error message when
- tclConfig.sh was not found.
-
-2010-12-15 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * install-sh: Upgrade to newer install-sh and use it.
- * tcl.m4:
-
-2010-12-14 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Better building on OpenBSD.
-
-2010-12-14 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: when using gcc, don't try to determine Win64 SDK
-
-2010-12-12 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Determine correctly a cross-compiler-windres
-
-2010-11-23 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: add some cross-compile support, borrowed from Tcl 8.6
-
-2010-09-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct HP-UX LDFLAGS (only used when building big shell)
-
-2010-09-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add extra if check for .manifest file generation
- Add notice about package name and version being built.
-
-2010-09-09 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [FREQ #3058486] TEA_LOAD_CONFIG doesn't set all BUILD_ vars
- Slightly related: defining BUILD_$1 on all platforms - not only win -
- allows the -fvisibility feature to be used in extensions as well, at
- least if you compile against tcl >= 8.5.
-
-2010-08-26 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: ensure safe quoting for autoheader usage
-
-2010-08-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add TEA_ADD_CLEANFILES macro to make adding cleanfiles
- easier, and add *.exp to CLEANFILES Windows default.
- (TEA_MAKE_LIB): Enhanced to check for MSVC that requires manifests
- and auto-embed it into proj DLL via MAKE_SHARED_LIB. Also define
- VC_MANIFEST_EMBED_DLL and VC_MANIFEST_EMBED_EXE that do the same
- magic in case it is needed for extended TEA projects.
-
-2010-08-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.9 ***
- If upgrading from TEA_VERSION 3.8, copy over tcl.m4, change
- TEA_INIT to use 3.9 and reconfigure (ac-2.59+).
- BUILD_${PACKAGE_NAME} will be auto-defined on Windows for
- correct setting of TCL_STORAGE_CLASS.
- TEA_LOAD_CONFIG users should remove the SHLIB_LD_LIBS setting done
- in configure.in (LIBS will be automagically populated by
- TEA_LOAD_CONFIG).
- TEA_EXPORT_CONFIG has been added for ${pkg}Config.sh creators
- SHLIB_LD_FLAGS was deprecated a while ago, remove it if it is
- still in your Makefile.in.
-
- * tcl.m4: add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
- Auto-define BUILD_$PACKAGE_NAME so users don't need to. This
- needs to correspond with $pkg.h define magic for TCL_STORAGE_CLASS.
- Auto-define CLEANFILES. Users can expand it.
- (SHLIB_LD_LIBS): define to '${LIBS}' default and change it only if
- necessary. Platforms not using this may simply not work or have
- very funky linkers.
- (TEA_LOAD_CONFIG): When loading config for another extension,
- auto-add stub libraries found with TEA_ADD_LIBS. Eases
- configure.in for modules like itk and img::*.
- (TEA_EXPORT_CONFIG): Add standardized function for exporting a
- ${pkg}Config.sh. See use by img::* and itcl.
-
-2010-08-12 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.8 ***
- If upgrading from TEA_VERSION 3.7, copy over tcl.m4, change
- TEA_INIT to use 3.8 and reconfigure (ac-2.59+).
- No other changes should be necessary.
-
- * tcl.m4: remove more vestigial bits from removed platforms.
- Add back SCO_SV-3.2*.
- Remove use of DL_LIBS and DL_OBJS and related baggage - these are
- only needed by the core to support 'load'.
- Allow for macosx in TEA_ADD_SOURCES.
- Correct check for found_xincludes=no in TEA_PATH_UNIX_X.
-
-2010-08-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove the following old platform configurations:
- UNIX_SV*|UnixWare-5*, SunOS-4.*, SINIX*5.4*, SCO_SV-3.2*<readded>,
- OSF1-1.*, NEXTSTEP-*, NetBSD-1.*|FreeBSD-[[1-2]].*, MP-RAS-*,
- IRIX-5.*, HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*, dgux*,
- BSD/OS-2.1*|BSD/OS-3*
- (AIX): drop AIX-pre4 support and use of ldAix, use -bexpall/-brtl
-
-2010-07-05 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Patch #1055668] removal of exported internals from
- tclInt.h (EXTERN macro)
-
-2010-04-14 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4 - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4
- - Fix determination of CYGPATH for CYGWIN
- With those fixes, itcl and tdbc compile fine with CYGWIN
-
-2010-04-06 Jan Nijtmans <nijtmans@users.sf.net>
-
- * install-sh [Bug 2982540] configure and install* script files
- should always have LF
-
-2010-02-19 Stuart Cassoff <stwo@users.sourceforge.net>
-
- * tcl.m4: Correct compiler/linker flags for threaded builds on
- OpenBSD.
-
-2010-01-19 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: Detect CYGWIN variant: win32 or unix
-
-2010-01-03 Donal K. Fellows <dkf@users.sf.net>
-
- * unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the
- configuration for modern FreeBSD suggested by the FreeBSD porter.
-
-2009-10-22 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS
-
-2009-04-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on
- AIX with threads.
-
-2009-04-10 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): check for 64-bit TkAqua.
-
-2009-03-26 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS
- together with SHLIB_LD definition to unbreak building on HPUX.
-
-2009-03-20 Andreas Kupries <andreask@activestate.com>
-
- * tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak
- building on HPUX.
-
-2009-03-16 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC}
- (found in tkConfig.sh) when trying to guess where tk.h might be
- [Patch 1960628].
-
-2009-03-11 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at
- configure-time [Patch 1960628]. Also fix some comment typos,
- and an uninitialized variable bug-waiting-to-happen.
-
-2008-12-21 Jan Nijtmans <nijtmans@users.sf.net>
-
- * tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX
- (this bug report was for Tcl, but holds for TEA as well.)
-
-2008-12-20 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: sync with tdbc tcl.m4 changes
- (SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS
-
-2008-12-02 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.7 ***
-
- * tcl.m4: in private header check, check for <plat>Port.h instead
- of Int.h to ensure all private headers are available.
-
-2008-11-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of
- Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS.
-
-2008-11-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error
- when tclConfig.sh cannot be found. [Bug #1997760]
- (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for
- finding the headers installed in the public areas, e.g. a result of
- make install-private-headers. [Bug #1631922]
-
-2008-08-12 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): link shlib with current and compatiblity version
- flags; look for libX11.dylib when searching for X11 libraries.
-
-2008-06-12 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
-
-2008-03-27 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
-
-2008-02-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with
- more modern VC versions. Currently just made the linker flags more
- flexible; more work may be needed.
-
-2007-10-26 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add support for 64-bit X11.
-
-2007-10-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Tagged tea-3-branch to start TEA 4 development on HEAD ***
-
-2007-09-17 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable'
- to build shared libraries on current NetBSDs [Bug 1749251].
-
-2007-09-15 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: replace all direct references to compiler by ${CC} to
- enable CC overriding at configure & make time.
- (SunOS-5.1x): replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
- 'cc' compiler driver.
-
-2007-08-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: check Ttk dir for Tk private headers (8.5).
- Add some comments to other bits.
-
-2007-06-25 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added.
-
-2007-06-13 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: fix --with-tkinclude alignment. [Bug 1506111]
-
-2007-06-06 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds.
-
-2007-05-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * tcl.m4: Added quoting so that paths with spaces cause fewer
- problems.
-
-2007-03-07 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check.
-
-2007-02-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct private header check to search in generic subdir
-
-2007-02-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA_VERSION 3.6 ***
-
- * tcl.m4: correct -d to -f
- (TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058]
-
-2007-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check
- that the dirs actually have private headers. [Bug 1631922]
-
-2007-02-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: add caching to -pipe check.
-
-2007-01-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
- move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to
- avoid errors about multiple -isysroot flags from some older gcc builds.
-
-2006-01-19 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
- (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
- present in CFLAGS to avoid discrepancies between what headers configure
- sees during preprocessing tests and compiling tests.
-
-2006-12-19 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag
- succeeds before enabling 64bit build.
-
-2006-12-16 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Linux): fix previous change to use makefile variable
- LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker
- flags in sampleextension Makefile are picked up.
-
-2006-11-26 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558]
-
-2006-08-18 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
- universal builds including x86_64 and for use of -mmacosx-version-min
- instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit
- arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor
- TkX11 can be built for 64-bit at present.
-
-2006-03-28 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: []-quote AC_DEFUN functions.
- (TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh.
- (TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs.
-
-2006-03-07 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD,
- as per the other *BSD variants [Bug 1334613].
-
-2006-01-25 Jeff Hobbs <jeffh@ActiveState.com>
-
- *** Bump to TEA version 3.5 ***
-
- * tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous
- with core tcl.m4 meaning.
-
-2006-01-24 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of
- LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile
- are picked up. [Bug 1403343]
-
-2006-01-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for
- *Config.sh on Windows. [Bug 1407544]
-
-2006-01-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS
- like in the Tk configure, as neither TkAqua nor TkX11 can be built for
- 64bit at present (no 64bit GUI libraries).
-
-2006-01-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: restore system=windows on Windows.
- Remove error if 'ar' isn't found (it may not be on Windows).
- Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default.
- Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at
- configure time.
-
-2006-01-10 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL
- where possible, consistent message quoting, sync relevant
- tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences
- (notably sunc removal of support for for ancient BSD's, IRIX 4,
- RISCos and Ultrix by kennykb), Darwin improvements to
- TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks
- installed in arbitrary location, change TEA_PROG_* search order
- (look in *_BIN_DIR parents before *_PREFIX).
-
-2006-01-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add dkf's system config refactor
-
-2006-01-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove extraneous ' that causes bash 3.1 to choke
-
-2005-12-19 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c
- in ${libdir}, where they are installed by default [Patch #1377407].
-
-2005-12-05 Don Porter <dgp@users.sf.net>
-
- * tcl.m4 (TEA_PUBLIC_*_HEADERS): Better support for finding
- header files for uninstalled Tcl and Tk.
-
-2005-12-02 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correctly bump TEA_VERSION var to 3.4
-
-2005-12-01 Daniel Steffen <das@users.sourceforge.net>
-
- * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
-
-2005-11-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: *** Bump to TEA version 3.4 ***
- Add Windows x64 build support.
- Remove TEA_PATH_NOSPACE and handle the problem with ""s where
- necessary - the macro relied on TCLSH_PROG which didn't work for
- cross-compiles.
-
-2005-11-27 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to
- support passing -isysroot in env(CFLAGS) to configure (flag can't
- be present twice, so can't be in both CFLAGS and LDFLAGS during
- configure), don't use -prebind when deploying on 10.4.
- (TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching.
-
-2005-10-30 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that
- should have been for `uname -s` = "Darwin" instead; added some
- missing quoting.
- (TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that
- install location of tclConfig.sh/tkConfig.sh allows to determine
- the tclsh/wish install dir via ../bin. Indeed tcl/tk can be
- configured with arbitrary --libdir and --bindir (independent of
- prefix) and such a configuration is in fact standard with Darwin
- framework builds. At least now also check ${TCL_PREFIX}/bin
- resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk
- have been configured with arbitrary --bindir, this will still not
- find them, for a general solution *Config.sh would need to contain
- the values of bindir/libdir/includedir passed to configure).
-
-2005-10-07 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds.
-
-2005-10-04 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro
- (TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func
-
-2005-09-13 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: *** Update to TEA version 3.3 ***
- define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG.
- Make --enable-threads the default (users can --disable-threads).
- Improve AIX ${CC}_r fix to better check existing ${CC} value.
- Do the appropriate evals to not require the *TOP_DIR_NATIVE vars
- be set for extensions that use private headers.
- Make aqua check for Xlib compat headers the same as win32.
-
-2005-07-26 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
- TEA_PROG_WISH, TEA_BUILD_WISH): Remove
- TEA_BUILD_TCLSH and TEA_BUILD_WISH because
- of complaints that it broke the build when
- only an installed version of Tcl was available
- at extension build time. The TEA_PROG_TCLSH and
- TEA_PROG_WISH macros will no longer search the
- path at all. The build tclsh or installed
- tclsh shell will now be found by TEA_PROG_TCLSH.
-
-2005-07-24 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH,
- TEA_PROG_WISH, TEA_BUILD_WISH):
- Split confused search for tclsh on PATH and
- build and install locations into two macros.
- TEA_PROG_TCLSH and TEA_PROG_WISH search the
- system PATH for an installed tclsh or wish.
- The TEA_BUILD_TCLSH and TEA_BUILD_WISH
- macros determine the name of tclsh or
- wish in the Tcl or Tk build directory even
- if tclsh or wish has not yet been built.
- [Tcl bug 1160114]
- [Tcl patch 1244153]
-
-2005-06-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to
- TK_INCLUDES when building against TkAqua.
-
- * tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE
-
- * tcl.m4: changes to better support framework builds of Tcl and Tk out
- of the box: search framework install locations for *Config.sh, and if in
- presence of a framework build, use the framework's Headers and
- PrivateHeaders directories for public and private includes. [FR 947735]
-
-2005-06-18 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
- ensure we can always relocate binaries with install_name_tool.
-
-2005-06-04 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib
- compat headers are available in tkheaders location, otherwise add xlib
- sourcedir to TK_XINCLUDES.
-
-2005-04-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow
- use with autoheader.
- (Darwin): added configure checks for recently added linker flags
- -single_module and -search_paths_first to allow building with older
- tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD.
- (TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check.
- (TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4).
-
-2005-03-24 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide
- int type only on Windows when __int64 is detected as valid.
-
-2005-03-24 Don Porter <dgp@users.sf.net>
-
- * README.txt: Update reference to "SC_* macros" to "TEA_* macros".
- * tcl.m4: Incorporated recent improvements in SC_PATH_TCLCONFIG
- and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG.
- Corrected search path in TEA_PATH_CONFIG and added
- AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load
- the configuration of another package can know where they loaded
- it from.
-
-2005-03-18 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have
- variant LD_SEARCH_FLAGS for gcc and cc builds.
-
- * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check.
-
-2005-03-17 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Correct gcc build and HP-UX-11.
-
-2005-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -.
- (TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build.
- (TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed).
-
-2005-02-01 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: redo of 2005-01-27 changes to correctly handle paths
- with spaces. Win/CE and Win/64 builds now require a prebuilt
- tclsh to handle conversion to short pathnames. This is done in
- the new TEA_PATH_NOSPACE macro. For Win/CE|64, make CC just the
- compiler and move the necessary includes to CFLAGS.
- (TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support.
- (TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to
- be set in the env and prevent resetting.
- (TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib
- args to -lfoo, for use with mingw.
- *** POTENTIAL INCOMPATABILITY ***
- (TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box.
- Bumped TEA to 3.2.
-
-2005-01-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: remove cygpath calls to support msys.
- Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003".
- Make STLIB_LD use $LINKBIN -lib.
-
-2005-01-25 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (Darwin): fixed bug with static build linking to dynamic
- library in /usr/lib etc instead of linking to static library earlier
- in search path. [Tcl Bug 956908]
- Removed obsolete references to Rhapsody.
-
-2004-12-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS
- options, using better default -O levels. [Bug 1092952, 1091967]
-
-2004-12-29 Joe English <jenglish@users.sourceforge.net>
-
- * tcl.m4: Do not use ${DBGX} suffix when building
- shared libraries [patch #1081595, TIP #34]
-
-2004-09-07 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds
-
-2004-08-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to
- work around subdir configures since autoconf only propagates the
- prefix (not exec_prefix).
-
-2004-07-23 Daniel Steffen <das@users.sourceforge.net>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with
- Tcl 8.5 HEAD config, removed core specific & obsolete settings.
-
-2004-07-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if
- we are compiling on Aqua. Add TEA_WINDOWINGSYSTEM var that
- reflects 'tk windowingsystem' value.
-
-2004-07-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when
- building against a threaded core.
- (CFLAGS_WARNING): Remove -Wconversion for gcc builds
- (TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build
- configuration, replacing EXTRA_CFLAGS with CFLAGS. [Bug #874058]
- Update to latest Tcl 8.5 head config settings.
- Call this TEA version 3.1.
-
-2004-04-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with
- AC_TRY_COMPILE for the long vs. long long check. (kenny)
-
-2004-04-26 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to
- define TCL_WIDE_INT_IS_LONG if 'using long'.
-
-2004-03-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB
-
-2004-02-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct TCL_INCLUDES for private headers on Windows - it
- doesn't need the eval.
-
-2004-02-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the
- DIR_NATIVE vars defined when using private headers on unix.
- Allow $... to TEA_ADD_SOURCES for constructs like
- TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to
- place more in the Makefile.in.
- tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
- CHECK on limits.h
-
-2003-12-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * Makefile.in: added TEA_ADD_LIBS, TEA_ADD_INCLUDES and
- * configure: TEA_ADD_CFLAGS to configurable parameters with
- * configure.in: PKG_* equivs in the Makefile. This allows the
- * tclconfig/tcl.m4: user to worry less about actual magic VAR names.
- Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires
- exact file names.
-
-2003-12-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff)
-
-2003-12-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * configure:
- * configure.in:
- * Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the
- first part of VPATH can get chopped off.
- Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes.
- * tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub
- generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as
- the way the user specifies library files.
-
-2003-12-03 Jeff Hobbs <jeffh@ActiveState.com>
-
- * configure: Update of TEA spec to (hopefully) simplify
- * configure.in: some aspects of TEA by making use of more
- * Makefile.in: AC 2.5x features. Use PACKAGE_NAME (instead
- * generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of
- * tclconfig/tcl.m4: VERSION) arguments to AC_INIT as the TEA
- package name and version.
- Provide a version argument to TEA_INIT - starting with 3.0.
- Drop all use of interior shell substs that older makefiles didn't
- like. Use PKG_* naming convention instead.
- Move specification of source files and public headers into
- configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS. These will
- be munged during ./configure into the right obj file names (no
- $(SOURCES:.c=.obj) needed).
- There is almost nothing that should be touched in Makefile.in now
- for the developer. May want to add a TEA_ADD_TCL_SOURCES for the
- RUNTIME_SOURCES that remains.
- Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does.
- Only specify the user requested LDFLAGS/CFLAGS in the Makefile,
- don't mention the _OPTIMIZE/_DEBUG variants.
-
-2003-10-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the
- TEA_SETUP_COMPILER macro. They are split so the check for CC
- occurs before any use of CC. Also add AC_PROG_CPP to the compiler
- checks.
-
-2003-10-06 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Updated for autoconf 2.5x prereq.
- Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks
- in tcl.h, which also handles TCL_LL_MODIFIER* properly.
-
-2003-04-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct default setting of ARCH for WinCE builds.
- Correct \ escaping for CE sed macros.
-
-2003-04-10 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: replace $(syscal) construct with older `syscall` for
- systems where sh != bash.
-
-2003-04-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib
- options for Windows/CE compilation support. Requires the
- Microsoft eMbedded SDK and Keuchel's celib emulation layer.
-
-2003-02-18 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on
- the link line when checking for the pthread_attr_setstacksize
- symbol. (dejong)
-
- * tcl.m4 (TEA_SETUP_COMPILER): added default calls to
- TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS,
- TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD.
-
-2003-02-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: correct HP-UX ia64 --enable-64bit build flags
-
-2003-01-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: check $prefix/lib as well as $exec_prefix/lib when
- looking for tcl|tkConfig.sh, as this check is done before we would
- set exec_prefix when the user does not define it.
-
-2003-01-21 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support
- for mingw, the previous implementation would
- use VC++ when compiling with mingw gcc. Don't
- pass -fPIC since gcc always compiles pic code
- under win32. Change some hard coded cases
- of gcc to ${CC}.
-
-2002-10-15 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to
- TEA_MAKE_LIB because setting too early confuses other AC_* macros.
- Correct the HP-11 SHLIB_LD_LIBS setting.
-
- * tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and
- make it pick up the env CFLAGS at configure time.
-
-2002-10-09 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG.
- Improved AIX 64-bit build support, allow it on AIX-4 as well.
- Enable 64-bit HP-11 compilation with gcc.
- Enable 64-bit IRIX64-6 cc build support.
- Correct FreeBSD thread library linkage.
- Add OSF1 static build support.
- Improve SunOS-5 shared build SHLIB_LD macro.
-
-2002-07-20 Zoran Vasiljevic <zoran@archiware.com>
-
- * tcl.m4: Added MINGW32 to list of systems checked for Windows build.
- Also, fixes some indentation issues with "--with-XXX" options.
-
-2002-04-23 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to
- use new threaded allocatory by default on Unix for Tcl 8.4.
- (TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+.
-
-2002-04-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that
- we can use autoconf 2.5x as well as 2.13. This prevents us from
- being able to warn against the use of cygwin gcc at configure
- time, but allows autoconf 2.5x, which is what is shipped with most
- newer systems.
-
-2002-04-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: Enabled COFF as well as CV style debug info with
- --enable-symbols to allow Dr. Watson users to see function info.
- More info on debugging levels can be obtained at:
- http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
-
-2002-04-03 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: change all SC_* macros to TEA_*. The SC_ was for
- Scriptics, which is no more. TEA represents a better, independent
- prefix that won't need changing.
- Added preliminary mingw gcc support. [Patch #538772]
- Added TEA_PREFIX macro that handles defaulting the prefix and
- exec_prefix vars to those used by Tcl if none were specified.
- Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC
- check and several other basic AC_PROG checks needed for making
- executables. This greatly simplifies user's configure.in files.
- Collapsed AIX-5 defines into AIX-* with extra checks for doing the
- ELF stuff on AIX-5-ia64.
- Updated TEA_ENABLE_THREADS to take an optional arg to allow
- switching it on by default (for Thread) and add sanity checking to
- warn the user if configuring threads incompatibly.
-
-2002-03-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT.
- Removed --enable-64bit support for AIX-4 because it wasn't correct.
- Added -MT or -MD Windows linker switches to properly support
- symbols-enabled builds.
-
-2002-03-28 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first
- instead of calling it as that inlines it each time in shell code.
- Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti.
- Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds.
- A few changes to support itcl (and perhaps others):
- Added support for making your own stub libraries to SC_MAKE_LIB.
- New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg
- and find that ${pkg}Config.sh file. itk uses this for itcl.
-
-2002-03-27 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk
- build dir setup.
- Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS.
- Added XLIBSW onto LIBS when it is defined.
- Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS
- instead to not rely as much on tclConfig.sh cached info.
- Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH.
- These move towards making TEA much more independent of *Config.sh.
-
-2002-03-19 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and
- SHLIB_SUFFIX defines for Win.
- (SC_PATH_X): made this only do the check on unix platforms.
-
-2002-03-12 Jeff Hobbs <jeffh@ActiveState.com>
-
- * README.txt: updated to reflect fewer files
-
-2002-03-06 Jeff Hobbs <jeffh@ActiveState.com>
-
- * config.guess (removed):
- * config.sub (removed): removed unnecessary files
-
- * installFile.tcl (removed):
- * mkinstalldirs (removed): these aren't really necessary for
- making TEA work
-
- * tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't
- check /usr(/local)/include for includes on Windows when not using
- gcc
-
-2002-03-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tcl.m4: added warnings on Windows, removed RELPATH define and
- added TCL_LIBS to MAKE_LIB macro.
-
- This import represents 2.0.0, or a new start at attempting to
- make TEA much easier for C extension developers.
-
- **** moved from tclpro project to core tcl project, ****
- **** renamed to 'tclconfig' ****
-
-2001-03-15 Karl Lehenbauer <karl@procplace.com>
-
- * installFile.tcl: Added updating of the modification time of
- the target file whether we overwrote it or decided that it
- hadn't changed. This was necessary for us to be able to
- determine whether or not a module install touched the file.
-
-2001-03-08 Karl Lehenbauer <karl@procplace.com>
-
- * installFile.tcl: Added support for converting new-style (1.1+)
- Cygnus drive paths to Tcl-style.
-
-2001-01-15 <brent.welch@interwoven.com>
-
- * tcl.m4: Added FreeBSD clause.
-
-2001-01-03 <brent.welch@interwoven.com>
-
- * tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking
- for exec-prefix.
-
-2000-12-01 <brent.welch@interwoven.com>
-
- * tcl.m4: Concatenated most of the Ajuba acsite.m4 file
- so we don't need to modify the autoconf installation.
- * config.guess:
- * config.sub:
- * installFile.tcl:
- Added files from the itcl config subdirectory,
- which should go away.
-
-2000-7-29 <welch@ajubasolutions.com>
-
- * Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within
- TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent
- change from $(srcdir) to $(srcdir)/..
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/tcl.m4
deleted file mode 100644
index e8234a2..0000000
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tclconfig/tcl.m4
+++ /dev/null
@@ -1,4335 +0,0 @@
-# tcl.m4 --
-#
-# This file provides a set of autoconf macros to help TEA-enable
-# a Tcl extension.
-#
-# Copyright (c) 1999-2000 Ajuba Solutions.
-# Copyright (c) 2002-2005 ActiveState Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-
-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.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
-#
-
-#------------------------------------------------------------------------
-# TEA_PATH_TCLCONFIG --
-#
-# Locate the tclConfig.sh file and perform a sanity check on
-# the Tcl compile flags
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tcl=...
-#
-# Defines the following vars:
-# TCL_BIN_DIR Full path to the directory containing
-# the tclConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TCLCONFIG], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
- #
- # Ok, lets find the tcl configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tcl
- #
-
- if test x"${no_tcl}" = x ; then
- # we reset no_tcl in case something fails here
- no_tcl=true
- AC_ARG_WITH(tcl,
- AC_HELP_STRING([--with-tcl],
- [directory containing tcl configuration (tclConfig.sh)]),
- with_tclconfig="${withval}")
- AC_MSG_CHECKING([for Tcl configuration])
- AC_CACHE_VAL(ac_cv_c_tclconfig,[
-
- # First check to see if --with-tcl was specified.
- if test x"${with_tclconfig}" != x ; then
- case "${with_tclconfig}" in
- */tclConfig.sh )
- if test -f "${with_tclconfig}"; then
- AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
- with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tclconfig}/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
- fi
- fi
-
- # then check for a private Tcl installation
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in \
- ../tcl \
- `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tcl \
- `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tcl \
- `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tcl.framework/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/pkg/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
- ])
-
- if test x"${ac_cv_c_tclconfig}" = x ; then
- TCL_BIN_DIR="# no Tcl configs found"
- AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
- else
- no_tcl=
- TCL_BIN_DIR="${ac_cv_c_tclconfig}"
- AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_TKCONFIG --
-#
-# Locate the tkConfig.sh file
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tk=...
-#
-# Defines the following vars:
-# TK_BIN_DIR Full path to the directory containing
-# the tkConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TKCONFIG], [
- #
- # Ok, lets find the tk configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tk
- #
-
- if test x"${no_tk}" = x ; then
- # we reset no_tk in case something fails here
- no_tk=true
- AC_ARG_WITH(tk,
- AC_HELP_STRING([--with-tk],
- [directory containing tk configuration (tkConfig.sh)]),
- with_tkconfig="${withval}")
- AC_MSG_CHECKING([for Tk configuration])
- AC_CACHE_VAL(ac_cv_c_tkconfig,[
-
- # First check to see if --with-tkconfig was specified.
- if test x"${with_tkconfig}" != x ; then
- case "${with_tkconfig}" in
- */tkConfig.sh )
- if test -f "${with_tkconfig}"; then
- AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
- with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tkconfig}/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
- fi
- fi
-
- # then check for a private Tk library
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ../tk \
- `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tk \
- `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tk \
- `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tk.framework/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few other private locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_tkconfig}" = x ; then
- TK_BIN_DIR="# no Tk configs found"
- AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
- else
- no_tk=
- TK_BIN_DIR="${ac_cv_c_tkconfig}"
- AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TCLCONFIG --
-#
-# Load the tclConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TCL_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_BIN_DIR
-# TCL_SRC_DIR
-# TCL_LIB_FILE
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TCLCONFIG], [
- AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
-
- if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TCL_BIN_DIR}/tclConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
- eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
-
- # If the TCL_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TCL_LIB_SPEC will be set to the value
- # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
- # instead of TCL_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
- TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
- TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tcl.framework installed in an arbitrary location.
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
- for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
- "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
- TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
- TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
- TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
- eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
- eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
- eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
-
- AC_SUBST(TCL_VERSION)
- AC_SUBST(TCL_PATCH_LEVEL)
- AC_SUBST(TCL_BIN_DIR)
- AC_SUBST(TCL_SRC_DIR)
-
- AC_SUBST(TCL_LIB_FILE)
- AC_SUBST(TCL_LIB_FLAG)
- AC_SUBST(TCL_LIB_SPEC)
-
- AC_SUBST(TCL_STUB_LIB_FILE)
- AC_SUBST(TCL_STUB_LIB_FLAG)
- AC_SUBST(TCL_STUB_LIB_SPEC)
-
- AC_MSG_CHECKING([platform])
- hold_cc=$CC; CC="$TCL_CC"
- AC_TRY_COMPILE(,[
- #ifdef _WIN32
- #error win32
- #endif
- ], [
- TEA_PLATFORM="unix"
- CYGPATH=echo
- ], [
- TEA_PLATFORM="windows"
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
- )
- CC=$hold_cc
- AC_MSG_RESULT($TEA_PLATFORM)
-
- # The BUILD_$pkg is to define the correct extern storage class
- # handling when making this package
- AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
- [Building extension source?])
- # 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:
- AC_SUBST(CLEANFILES)
- AC_SUBST(TCL_LIBS)
- AC_SUBST(TCL_DEFS)
- AC_SUBST(TCL_EXTRA_CFLAGS)
- AC_SUBST(TCL_LD_FLAGS)
- AC_SUBST(TCL_SHLIB_LD_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TKCONFIG --
-#
-# Load the tkConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TK_BIN_DIR
-#
-# Results:
-#
-# Sets the following vars that should be in tkConfig.sh:
-# TK_BIN_DIR
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TKCONFIG], [
- AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
-
- if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TK_BIN_DIR}/tkConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
- eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
-
- # If the TK_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TK_LIB_SPEC will be set to the value
- # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
- # instead of TK_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
- TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
- TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tk.framework installed in an arbitrary location.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
- for i in "`cd "${TK_BIN_DIR}"; pwd`" \
- "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
- TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
- TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
- TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
- eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
- eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
- eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
-
- # TEA specific: Ensure windowingsystem is defined
- if test "${TEA_PLATFORM}" = "unix" ; then
- case ${TK_DEFS} in
- *MAC_OSX_TK*)
- AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
- TEA_WINDOWINGSYSTEM="aqua"
- ;;
- *)
- TEA_WINDOWINGSYSTEM="x11"
- ;;
- esac
- elif test "${TEA_PLATFORM}" = "windows" ; then
- TEA_WINDOWINGSYSTEM="win32"
- fi
-
- AC_SUBST(TK_VERSION)
- AC_SUBST(TK_BIN_DIR)
- AC_SUBST(TK_SRC_DIR)
-
- AC_SUBST(TK_LIB_FILE)
- AC_SUBST(TK_LIB_FLAG)
- AC_SUBST(TK_LIB_SPEC)
-
- AC_SUBST(TK_STUB_LIB_FILE)
- AC_SUBST(TK_STUB_LIB_FLAG)
- AC_SUBST(TK_STUB_LIB_SPEC)
-
- # TEA specific:
- AC_SUBST(TK_LIBS)
- AC_SUBST(TK_XINCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_TCLSH
-# Determine the fully qualified path name of the tclsh executable
-# in the Tcl build directory or the tclsh installed in a bin
-# directory. This macro will correctly determine the name
-# of the tclsh executable even if tclsh has not yet been
-# built in the build directory. The tclsh found is always
-# associated with a tclConfig.sh file. This tclsh should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCLSH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_TCLSH], [
- AC_MSG_CHECKING([for tclsh])
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- # tclConfig.sh is in Tcl build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- AC_MSG_RESULT([${TCLSH_PROG}])
- AC_SUBST(TCLSH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_WISH
-# Determine the fully qualified path name of the wish executable
-# in the Tk build directory or the wish installed in a bin
-# directory. This macro will correctly determine the name
-# of the wish executable even if wish has not yet been
-# built in the build directory. The wish found is always
-# associated with a tkConfig.sh file. This wish should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# WISH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_WISH], [
- AC_MSG_CHECKING([for wish])
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- # tkConfig.sh is in Tk build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- else
- # tkConfig.sh is in install location
- if test "${TEA_PLATFORM}" = "windows"; then
- WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
- else
- WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
- fi
- list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
- `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
- for i in $list ; do
- if test -f "$i/${WISH_PROG}" ; then
- REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
- break
- fi
- done
- WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
- fi
- AC_MSG_RESULT([${WISH_PROG}])
- AC_SUBST(WISH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SHARED --
-#
-# Allows the building of shared libraries
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-shared=yes|no
-# --enable-stubs=yes|no
-#
-# Defines the following vars:
-# STATIC_BUILD Used for building import/export libraries
-# on Windows.
-#
-# Sets the following vars:
-# SHARED_BUILD Value of 1 or 0
-# 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)]),
- [shared_ok=$enableval], [shared_ok=yes])
-
- if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
- shared_ok=$enableval
- else
- 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
-
- # 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, [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)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_THREADS --
-#
-# Specify if thread support should be enabled. If "yes" is specified
-# as an arg (optional), threads are enabled by default, "no" means
-# threads are disabled. "yes" is the default.
-#
-# TCL_THREADS is checked so that if you are compiling an extension
-# against a threaded core, your extension must be compiled threaded
-# as well.
-#
-# Note that it is legal to have a thread enabled extension run in a
-# threaded or non-threaded Tcl core, but a non-threaded extension may
-# only run in a non-threaded Tcl core.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-threads
-#
-# Sets the following vars:
-# THREADS_LIBS Thread library(s)
-#
-# Defines the following vars:
-# TCL_THREADS
-# _REENTRANT
-# _THREAD_SAFE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_THREADS], [
- AC_ARG_ENABLE(threads,
- AC_HELP_STRING([--enable-threads],
- [build with threads (default: on)]),
- [tcl_ok=$enableval], [tcl_ok=yes])
-
- if test "${enable_threads+set}" = set; then
- enableval="$enable_threads"
- tcl_ok=$enableval
- else
- tcl_ok=yes
- fi
-
- if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
- TCL_THREADS=1
-
- if test "${TEA_PLATFORM}" != "windows" ; then
- # We are always OK on Windows, so check what this platform wants:
-
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- AC_DEFINE(USE_THREAD_ALLOC, 1,
- [Do we want to use the threaded memory allocator?])
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- if test "`uname -s`" = "SunOS" ; then
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
- fi
- AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
- AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- # Check a little harder for __pthread_mutex_init in the same
- # library, as some systems hide it there until pthread.h is
- # defined. We could alternatively do an AC_TRY_COMPILE with
- # pthread.h, but that will work with libpthread really doesn't
- # exist, like AIX 4.2. [Bug: 4359]
- AC_CHECK_LIB(pthread, __pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- fi
-
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthread"
- else
- AC_CHECK_LIB(pthreads, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthreads"
- else
- AC_CHECK_LIB(c, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- AC_CHECK_LIB(c_r, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -pthread"
- else
- TCL_THREADS=0
- AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
- fi
- fi
- fi
- fi
- fi
- else
- TCL_THREADS=0
- fi
- # Do checking message here to not mess up interleaved configure output
- AC_MSG_CHECKING([for building with threads])
- if test "${TCL_THREADS}" = 1; then
- AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
- AC_MSG_RESULT([yes (default)])
- else
- AC_MSG_RESULT([no])
- fi
- # TCL_THREADS sanity checking. See if our request for building with
- # threads is the same as the way Tcl was built. If not, warn the user.
- case ${TCL_DEFS} in
- *THREADS=1*)
- if test "${TCL_THREADS}" = "0"; then
- AC_MSG_WARN([
- Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
- that IS thread-enabled. It is recommended to use --enable-threads.])
- fi
- ;;
- *)
- if test "${TCL_THREADS}" = "1"; then
- AC_MSG_WARN([
- --enable-threads requested, but building against a Tcl that is NOT
- thread-enabled. This is an OK configuration that will also run in
- a thread-enabled core.])
- fi
- ;;
- esac
- AC_SUBST(TCL_THREADS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SYMBOLS --
-#
-# Specify if debugging symbols should be used.
-# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
-#
-# Arguments:
-# none
-#
-# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
-# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
-# Requires the following vars to be set in the Makefile:
-# CFLAGS_DEFAULT
-# LDFLAGS_DEFAULT
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-symbols
-#
-# Defines the following vars:
-# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
-# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
-# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
-# Sets to $(LDFLAGS_OPTIMIZE) if false
-# DBGX Formerly used as debug library extension;
-# always blank now.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_SYMBOLS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_CONFIG_CFLAGS])
- AC_MSG_CHECKING([for build with symbols])
- AC_ARG_ENABLE(symbols,
- AC_HELP_STRING([--enable-symbols],
- [build with debugging symbols (default: off)]),
- [tcl_ok=$enableval], [tcl_ok=no])
- DBGX=""
- if test "$tcl_ok" = "no"; then
- CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
- LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
- AC_MSG_RESULT([no])
- else
- CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
- LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
- if test "$tcl_ok" = "yes"; then
- AC_MSG_RESULT([yes (standard debugging)])
- fi
- fi
- # TEA specific:
- if test "${TEA_PLATFORM}" != "windows" ; then
- LDFLAGS_DEFAULT="${LDFLAGS}"
- fi
- AC_SUBST(CFLAGS_DEFAULT)
- AC_SUBST(LDFLAGS_DEFAULT)
- AC_SUBST(TCL_DBGX)
-
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
- fi
-
- if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
- if test "$tcl_ok" = "all"; then
- AC_MSG_RESULT([enabled symbols mem debugging])
- else
- AC_MSG_RESULT([enabled $tcl_ok debugging])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_LANGINFO --
-#
-# Allows use of modern nl_langinfo check for better l10n.
-# This is only relevant for Unix.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-langinfo=yes|no (default is yes)
-#
-# Defines the following vars:
-# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_LANGINFO], [
- AC_ARG_ENABLE(langinfo,
- AC_HELP_STRING([--enable-langinfo],
- [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
- [langinfo_ok=$enableval], [langinfo_ok=yes])
-
- HAVE_LANGINFO=0
- if test "$langinfo_ok" = "yes"; then
- AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
- fi
- AC_MSG_CHECKING([whether to use nl_langinfo])
- if test "$langinfo_ok" = "yes"; then
- AC_CACHE_VAL(tcl_cv_langinfo_h, [
- AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
- [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
- AC_MSG_RESULT([$tcl_cv_langinfo_h])
- if test $tcl_cv_langinfo_h = yes; then
- AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
- fi
- else
- AC_MSG_RESULT([$langinfo_ok])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_SYSTEM
-#
-# Determine what the system is (some things cannot be easily checked
-# on a feature-driven basis, alas). This can usually be done via the
-# "uname" command.
-#
-# Arguments:
-# none
-#
-# Results:
-# Defines the following var:
-#
-# system - System/platform/version identification code.
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_SYSTEM], [
- AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
- # TEA specific:
- if test "${TEA_PLATFORM}" = "windows" ; then
- tcl_cv_sys_version=windows
- else
- tcl_cv_sys_version=`uname -s`-`uname -r`
- if test "$?" -ne 0 ; then
- AC_MSG_WARN([can't find uname command])
- tcl_cv_sys_version=unknown
- else
- if test "`uname -s`" = "AIX" ; then
- tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
- fi
- fi
- fi
- ])
- system=$tcl_cv_sys_version
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_CFLAGS
-#
-# Try to determine the proper flags to pass to the compiler
-# for building shared libraries and other such nonsense.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substitutes the following vars:
-#
-# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
-# LDFLAGS - Flags to pass to the compiler when linking object
-# files into an executable application binary such
-# as tclsh.
-# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile. Could
-# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
-# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile.
-# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
-# of a shared library (may request position-independent
-# code, among other things).
-# SHLIB_LD - Base command to use for combining object files
-# into a shared library.
-# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
-# creating shared libraries. This symbol typically
-# goes at the end of the "ld" commands that build
-# shared libraries. The value of the symbol defaults to
-# "${LIBS}" if all of the dependent libraries should
-# be specified when creating a shared library. If
-# dependent libraries should not be specified (as on
-# SunOS 4.x, where they cause the link to fail, or in
-# general if Tcl and Tk aren't themselves shared
-# libraries), then this symbol has an empty string
-# as its value.
-# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
-# extensions. An empty string means we don't know how
-# to use shared libraries on this platform.
-# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
-# in a static or shared library name, using the $PACKAGE_VERSION variable
-# to put the version in the right place. This is used
-# by platforms that need non-standard library names.
-# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
-# to have a version after the .so, and ${PACKAGE_VERSION}.a
-# on AIX, since a shared library needs to have
-# a .a extension whereas shared objects for loadable
-# extensions have a .so extension. Defaults to
-# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
-# CFLAGS_DEBUG -
-# Flags used when running the compiler in debug mode
-# CFLAGS_OPTIMIZE -
-# Flags used when running the compiler in optimize mode
-# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_CFLAGS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
-
- # Step 0.a: Enable 64 bit support?
-
- AC_MSG_CHECKING([if 64bit support is requested])
- AC_ARG_ENABLE(64bit,
- AC_HELP_STRING([--enable-64bit],
- [enable 64bit support (default: off)]),
- [do64bit=$enableval], [do64bit=no])
- AC_MSG_RESULT([$do64bit])
-
- # Step 0.b: Enable Solaris 64 bit VIS support?
-
- AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
- AC_ARG_ENABLE(64bit-vis,
- AC_HELP_STRING([--enable-64bit-vis],
- [enable 64bit Sparc VIS support (default: off)]),
- [do64bitVIS=$enableval], [do64bitVIS=no])
- AC_MSG_RESULT([$do64bitVIS])
- # Force 64bit on with VIS
- AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
-
- # Step 0.c: Check if visibility support is available. Do this here so
- # that platform specific alternatives can be used below if this fails.
-
- AC_CACHE_CHECK([if compiler supports visibility "hidden"],
- tcl_cv_cc_visibility_hidden, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- AC_TRY_LINK([
- extern __attribute__((__visibility__("hidden"))) void f(void);
- void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
- tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- AC_DEFINE(MODULE_SCOPE,
- [extern __attribute__((__visibility__("hidden")))],
- [Compiler support for module scope symbols])
- AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
- ])
-
- # Step 0.d: Disable -rpath support?
-
- AC_MSG_CHECKING([if rpath support is requested])
- AC_ARG_ENABLE(rpath,
- AC_HELP_STRING([--disable-rpath],
- [disable rpath support (default: on)]),
- [doRpath=$enableval], [doRpath=yes])
- AC_MSG_RESULT([$doRpath])
-
- # TEA specific: Cross-compiling options for Windows/CE builds?
-
- AS_IF([test "${TEA_PLATFORM}" = windows], [
- AC_MSG_CHECKING([if Windows/CE build is requested])
- AC_ARG_ENABLE(wince,
- AC_HELP_STRING([--enable-wince],
- [enable Win/CE support (where applicable)]),
- [doWince=$enableval], [doWince=no])
- AC_MSG_RESULT([$doWince])
- ])
-
- # Set the variable "system" to hold the name and version number
- # for the system.
-
- TEA_CONFIG_SYSTEM
-
- # Require ranlib early so we can override it in special cases below.
-
- AC_REQUIRE([AC_PROG_RANLIB])
-
- # 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
- AS_IF([test "$GCC" = yes], [
- CFLAGS_OPTIMIZE=-O2
- CFLAGS_WARNING="-Wall"
- ], [
- CFLAGS_OPTIMIZE=-O
- CFLAGS_WARNING=""
- ])
- AC_CHECK_TOOL(AR, ar)
- STLIB_LD='${AR} cr'
- LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
- AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
- 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
- AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
- AC_MSG_WARN([Ensure latest Platform SDK is installed])
- do64bit="no"
- else
- AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
- do64bit_ok="yes"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- if test "$do64bit" != "no" ; then
- AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
- fi
- if test "$GCC" = "yes" ; then
- AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
- fi
- TEA_PATH_CELIB
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F, '{ \
- if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
- if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
- if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
- if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
- if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
- -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
- doWince="no"
- else
- # We could PATH_NOSPACE these, but that's not important,
- # as long as we quote them when used.
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$GCC" != "yes" ; then
- if test "${SHARED_BUILD}" = "0" ; then
- runtime=-MT
- else
- runtime=-MD
- fi
- case "x`echo \${VisualStudioVersion}`" in
- x1[[4-9]]*)
- lflags="${lflags} -nodefaultlib:libucrt.lib"
- TEA_ADD_LIBS([ucrt.lib])
- ;;
- *)
- ;;
- 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
- TEA_ADD_LIBS([bufferoverflowU.lib])
- elif test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="\"${CEBINROOT}/cl.exe\""
- else
- CC="\"${CEBINROOT}/cl${ARCH}.exe\""
- fi
- CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
- defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
- if test "${SHARED_BUILD}" = "1" ; then
- # Static CE builds require static celib as well
- defs="${defs} _DLL"
- fi
- for i in $defs ; do
- AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
- done
- AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
- AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
- CFLAGS_DEBUG="-nologo -Zi -Od"
- CFLAGS_OPTIMIZE="-nologo -Ox"
- lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
- lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
- LINKBIN="\"${CEBINROOT}/link.exe\""
- AC_SUBST(CELIB_DIR)
- 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
- AC_CHECK_TOOL(RC, windres)
- CFLAGS_DEBUG="-g"
- CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- SHLIB_LD='${CC} -shared'
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
- LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
-
- AC_CACHE_CHECK(for cross-compile version of gcc,
- ac_cv_cross,
- AC_TRY_COMPILE([
- #ifdef _WIN32
- #error cross-compiler
- #endif
- ], [],
- ac_cv_cross=yes,
- ac_cv_cross=no)
- )
- 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-*)
- AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
- # AIX requires the _r compiler when gcc isn't being used
- case "${CC}" in
- *_r|*_r\ *)
- # ok ...
- ;;
- *)
- # Make sure only first arg gets _r
- CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
- ;;
- esac
- AC_MSG_RESULT([Using $CC for compiling with threads])
- ])
- LIBS="$LIBS -lc"
- SHLIB_CFLAGS=""
- SHLIB_SUFFIX=".so"
-
- LD_LIBRARY_PATH_VAR="LIBPATH"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -q64"
- LDFLAGS_ARCH="-q64"
- RANLIB="${RANLIB} -X64"
- AR="${AR} -X64"
- SHLIB_LD_FLAGS="-b64"
- ])
- ])
-
- AS_IF([test "`uname -m`" = ia64], [
- # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- AS_IF([test "$GCC" = yes], [
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- ], [
- CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
- ])
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ], [
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared -Wl,-bexpall'
- ], [
- SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
- LDFLAGS="$LDFLAGS -brtl"
- ])
- SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
- CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- 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.
- #-----------------------------------------------------------
- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
- ;;
- 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} ${CFLAGS} ${LDFLAGS} -shared'
- AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
- ;;
- HP-UX-*.11.*)
- # Use updated header definitions where possible
- AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
- # TEA specific: Needed by Tcl, but not most extensions
- #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
- #LIBS="$LIBS -lxnet" # Use the XOPEN network library
-
- AS_IF([test "`uname -m`" = ia64], [
- SHLIB_SUFFIX=".so"
- # Use newer C++ library for C++ extensions
- #if test "$GCC" != "yes" ; then
- # CPPFLAGS="-AA"
- #fi
- ], [
- SHLIB_SUFFIX=".sl"
- ])
- AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
- AS_IF([test "$tcl_ok" = yes], [
- LDFLAGS="$LDFLAGS -Wl,-E"
- CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
- LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
- LD_LIBRARY_PATH_VAR="SHLIB_PATH"
- ])
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- CFLAGS="$CFLAGS -z"
- # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
- #CFLAGS="$CFLAGS +DAportable"
- SHLIB_CFLAGS="+z"
- SHLIB_LD="ld -b"
- ])
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = "yes"], [
- AS_IF([test "$GCC" = yes], [
- case `${CC} -dumpmachine` in
- hppa64*)
- # 64-bit gcc in use. Fix flags for GNU ld.
- do64bit_ok=yes
- SHLIB_LD='${CC} -shared'
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ;;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ;;
- esac
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS +DD64"
- LDFLAGS_ARCH="+DD64"
- ])
- ]) ;;
- IRIX-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [
- CFLAGS="$CFLAGS -mabi=n32"
- LDFLAGS="$LDFLAGS -mabi=n32"
- ], [
- case $system in
- IRIX-6.3)
- # Use to build 6.2 compatible binaries on 6.3.
- CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
- ;;
- *)
- CFLAGS="$CFLAGS -n32"
- ;;
- esac
- LDFLAGS="$LDFLAGS -n32"
- ])
- ;;
- IRIX64-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
-
- # Check to enable 64-bit flags for compiler/linker
-
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported by gcc])
- ], [
- do64bit_ok=yes
- SHLIB_LD="ld -64 -shared -rdata_shared"
- CFLAGS="$CFLAGS -64"
- LDFLAGS_ARCH="-64"
- ])
- ])
- ;;
- Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
- AS_IF([test $do64bit = yes], [
- AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -m64"
- AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_m64 = yes], [
- CFLAGS="$CFLAGS -m64"
- do64bit_ok=yes
- ])
- ])
-
- # The combo of gcc + glibc has a bug related to inlining of
- # functions like strtod(). The -fno-builtin flag should address
- # this problem but it does not work. The -fno-inline flag is kind
- # of overkill but it works. Disable inlining only when one of the
- # files in compat/*.c is being linked in.
-
- AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
- ;;
- Lynx*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
- CFLAGS_OPTIMIZE=-02
- SHLIB_LD='${CC} -shared'
- LD_FLAGS="-Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- ;;
- OpenBSD-*)
- arch=`arch -s`
- case "$arch" in
- alpha|sparc64)
- SHLIB_CFLAGS="-fPIC"
- ;;
- *)
- SHLIB_CFLAGS="-fpic"
- ;;
- esac
- SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
- LDFLAGS="-Wl,-export-dynamic"
- CFLAGS_OPTIMIZE="-O2"
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # On OpenBSD: Compile with -pthread
- # Don't link with -lpthread
- LIBS=`echo $LIBS | sed s/-lpthread//`
- CFLAGS="$CFLAGS -pthread"
- ])
- # 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} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- LDFLAGS="$LDFLAGS -export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the CFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ;;
- 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=""
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the LDFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
- 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}'`"
- AS_IF([test $do64bit = yes], [
- case `arch` in
- ppc)
- AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
- tcl_cv_cc_arch_ppc64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
- tcl_cv_cc_arch_ppc64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- do64bit_ok=yes
- ]);;
- i386)
- AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
- tcl_cv_cc_arch_x86_64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch x86_64"
- AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
- tcl_cv_cc_arch_x86_64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
- CFLAGS="$CFLAGS -arch x86_64"
- do64bit_ok=yes
- ]);;
- *)
- AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
- esac
- ], [
- # Check for combined 32-bit and 64-bit fat build
- AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
- && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
- fat_32_64=yes])
- ])
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
- AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_single_module = yes], [
- SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
- ])
- # TEA specific: link shlib with current and 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:
- AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
- "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
- LDFLAGS="$LDFLAGS -prebind"])
- LDFLAGS="$LDFLAGS -headerpad_max_install_names"
- AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
- tcl_cv_ld_search_paths_first, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
- tcl_cv_ld_search_paths_first=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- ])
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [__private_extern__],
- [Compiler support for module scope symbols])
- tcl_cv_cc_visibility_hidden=yes
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
- # TEA specific: for combined 32 & 64 bit fat builds of Tk
- # extensions, verify that 64-bit build is possible.
- AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
- AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
- LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
- AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
- tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
- AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
- LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
- AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
- tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- # remove 64-bit arch flags from CFLAGS et al. if configuration
- # does not support 64-bit.
- AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
- AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
- done])
- ])
- ;;
- OS/390-*)
- CFLAGS_OPTIMIZE="" # Optimizer is buggy
- AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
- [Should OS/390 do the right thing with sockets?])
- ;;
- OSF1-V*)
- # Digital OSF/1
- SHLIB_CFLAGS=""
- AS_IF([test "$SHARED_BUILD" = 1], [
- SHLIB_LD='ld -shared -expect_unresolved "*"'
- ], [
- SHLIB_LD='ld -non_shared -expect_unresolved "*"'
- ])
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
- CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
- # see pthread_intro(3) for pthread support on osf1, k.furukawa
- AS_IF([test "${TCL_THREADS}" = 1], [
- CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
- CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
- LIBS=`echo $LIBS | sed s/-lpthreads//`
- AS_IF([test "$GCC" = yes], [
- LIBS="$LIBS -lpthread -lmach -lexc"
- ], [
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ])
- ;;
- QNX-6*)
- # QNX RTP
- # This may work for all QNX, but it was only reported for v6.
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- SCO_SV-3.2*)
- AS_IF([test "$GCC" = yes], [
- SHLIB_CFLAGS="-fPIC -melf"
- LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
- ], [
- SHLIB_CFLAGS="-Kpic -belf"
- LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
- ])
- SHLIB_LD="ld -G"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- 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.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- SunOS-5*)
- # Note: If _REENTRANT isn't defined, then Solaris
- # won't define thread-safe library routines.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- arch=`isainfo`
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- AS_IF([test "$GCC" = yes], [
- AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
- AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64 -mcpu=v9"
- LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
- SHLIB_CFLAGS="-fPIC"
- ])
- ], [
- do64bit_ok=yes
- AS_IF([test "$do64bitVIS" = yes], [
- CFLAGS="$CFLAGS -xarch=v9a"
- LDFLAGS_ARCH="-xarch=v9a"
- ], [
- CFLAGS="$CFLAGS -xarch=v9"
- LDFLAGS_ARCH="-xarch=v9"
- ])
- # Solaris 64 uses this as well
- #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
- ])
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- AS_IF([test "$GCC" = yes], [
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
- esac
- ], [
- do64bit_ok=yes
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- CFLAGS="$CFLAGS -xarch=amd64"
- LDFLAGS="$LDFLAGS -xarch=amd64";;
- esac
- ])
- ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
- ])
-
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "$do64bit_ok" = yes], [
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- # We need to specify -static-libgcc or we need to
- # add the path to the sparv9 libgcc.
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
- # for finding sparcv9 libgcc, get the regular libgcc
- # path, remove so name and append 'sparcv9'
- #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
- #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
- ])])
- ])
- ], [
- case $system in
- SunOS-5.[[1-9]][[0-9]]*)
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
- *)
- SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
- esac
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ])
- ;;
- UNIX_SV* | UnixWare-5*)
- SHLIB_CFLAGS="-KPIC"
- SHLIB_LD='${CC} -G'
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
- # that don't grok the -Bexport option. Test that it does.
- AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_Bexport = yes], [
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- esac
-
- AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
- AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
- ])
-
-dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
-dnl # until the end of configure, as configure's compile and link tests use
-dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
-dnl # preprocessing tests use only CPPFLAGS.
- AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
-
- # 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.
-
- AS_IF([test "$GCC" = yes], [
- case $system in
- AIX-*) ;;
- BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
- IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
- Darwin-*) ;;
- SCO_SV-3.2*) ;;
- windows) ;;
- *) SHLIB_CFLAGS="-fPIC" ;;
- esac])
-
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [extern],
- [No Compiler support for module scope symbols])
- ])
-
- AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
- AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
-
- if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
- AC_CACHE_CHECK(for SEH support in compiler,
- tcl_cv_seh,
- AC_TRY_RUN([
-#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;
- }
- ],
- tcl_cv_seh=yes,
- tcl_cv_seh=no,
- tcl_cv_seh=no)
- )
- if test "$tcl_cv_seh" = "no" ; then
- AC_DEFINE(HAVE_NO_SEH, 1,
- [Defined when mingw does not support SEH])
- 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.
- #
- AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
- tcl_cv_eh_disposition,
- AC_TRY_COMPILE([
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# undef WIN32_LEAN_AND_MEAN
- ],[
- EXCEPTION_DISPOSITION x;
- ],
- tcl_cv_eh_disposition=yes,
- tcl_cv_eh_disposition=no)
- )
- if test "$tcl_cv_eh_disposition" = "no" ; then
- AC_DEFINE(EXCEPTION_DISPOSITION, int,
- [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
- 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.
-
- AC_CACHE_CHECK(for winnt.h that ignores VOID define,
- tcl_cv_winnt_ignore_void,
- AC_TRY_COMPILE([
-#define VOID void
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
- ], [
- CHAR c;
- SHORT s;
- LONG l;
- ],
- tcl_cv_winnt_ignore_void=yes,
- tcl_cv_winnt_ignore_void=no)
- )
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
- AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
- [Defined when cygwin/mingw ignores VOID define in winnt.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.
-
- AC_CACHE_CHECK(for cast to union support,
- tcl_cv_cast_to_union,
- AC_TRY_COMPILE([],
- [
- union foo { int i; double d; };
- union foo f = (union foo) (int) 0;
- ],
- tcl_cv_cast_to_union=yes,
- tcl_cv_cast_to_union=no)
- )
- if test "$tcl_cv_cast_to_union" = "yes"; then
- AC_DEFINE(HAVE_CAST_TO_UNION, 1,
- [Defined when compiler supports casting to union type.])
- fi
-
- AC_SUBST(CFLAGS_DEBUG)
- AC_SUBST(CFLAGS_OPTIMIZE)
- AC_SUBST(CFLAGS_WARNING)
-
- AC_SUBST(STLIB_LD)
- AC_SUBST(SHLIB_LD)
-
- AC_SUBST(SHLIB_LD_LIBS)
- AC_SUBST(SHLIB_CFLAGS)
-
- AC_SUBST(LD_LIBRARY_PATH_VAR)
-
- # These must be called after we do the basic CFLAGS checks and
- # verify any possible 64-bit or similar switches are necessary
- TEA_TCL_EARLY_FLAGS
- TEA_TCL_64BIT_FLAGS
-])
-
-#--------------------------------------------------------------------
-# TEA_SERIAL_PORT
-#
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives,
-# and some build environments have stdin not pointing at a
-# pseudo-terminal (usually /dev/null instead.)
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines only one of the following vars:
-# HAVE_SYS_MODEM_H
-# USE_TERMIOS
-# USE_TERMIO
-# USE_SGTTY
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_SERIAL_PORT], [
- AC_CHECK_HEADERS(sys/modem.h)
- AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
- AC_TRY_RUN([
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termios.h>
-#include <errno.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
- fi])
- case $tcl_cv_api_serial in
- termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
- termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
- sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
-# TEA_PATH_X
-#
-# Locate the X11 header files and the X11 library archive. Try
-# the ac_path_x macro first, but if it doesn't find the X stuff
-# (e.g. because there's no xmkmf program) then check through
-# a list of possible directories. Under some conditions the
-# autoconf macro will return an include directory that contains
-# no include files, so double-check its result just to be safe.
-#
-# This should be called after TEA_CONFIG_CFLAGS as setting the
-# LIBS line can confuse some configure macro magic.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets the following vars:
-# XINCLUDES
-# XLIBSW
-# PKG_LIBS (appends to)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_X], [
- if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
- TEA_PATH_UNIX_X
- fi
-])
-
-AC_DEFUN([TEA_PATH_UNIX_X], [
- AC_PATH_X
- not_really_there=""
- if test "$no_x" = ""; then
- if test "$x_includes" = ""; then
- AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
- else
- if test ! -r $x_includes/X11/Xlib.h; then
- not_really_there="yes"
- fi
- fi
- fi
- if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
- AC_MSG_CHECKING([for X11 header files])
- found_xincludes="no"
- AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
- if test "$found_xincludes" = "no"; then
- dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
- for i in $dirs ; do
- if test -r $i/X11/Xlib.h; then
- AC_MSG_RESULT([$i])
- XINCLUDES=" -I$i"
- found_xincludes="yes"
- break
- fi
- done
- fi
- else
- if test "$x_includes" != ""; then
- XINCLUDES="-I$x_includes"
- found_xincludes="yes"
- fi
- fi
- if test "$found_xincludes" = "no"; then
- AC_MSG_RESULT([couldn't find any!])
- fi
-
- if test "$no_x" = yes; then
- AC_MSG_CHECKING([for X11 libraries])
- XLIBSW=nope
- dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
- for i in $dirs ; do
- if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
- AC_MSG_RESULT([$i])
- XLIBSW="-L$i -lX11"
- x_libraries="$i"
- break
- fi
- done
- else
- if test "$x_libraries" = ""; then
- XLIBSW=-lX11
- else
- XLIBSW="-L$x_libraries -lX11"
- fi
- fi
- if test "$XLIBSW" = nope ; then
- AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
- fi
- if test "$XLIBSW" = nope ; then
- AC_MSG_RESULT([could not find any! Using -lX11.])
- XLIBSW=-lX11
- fi
- # TEA specific:
- if test x"${XLIBSW}" != x ; then
- PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BLOCKING_STYLE
-#
-# The statements below check for systems where POSIX-style
-# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
-# On these systems (mostly older ones), use the old BSD-style
-# FIONBIO approach instead.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# HAVE_SYS_IOCTL_H
-# HAVE_SYS_FILIO_H
-# USE_FIONBIO
-# O_NONBLOCK
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BLOCKING_STYLE], [
- AC_CHECK_HEADERS(sys/ioctl.h)
- AC_CHECK_HEADERS(sys/filio.h)
- TEA_CONFIG_SYSTEM
- AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
- case $system in
- OSF*)
- AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
- AC_MSG_RESULT([FIONBIO])
- ;;
- *)
- AC_MSG_RESULT([O_NONBLOCK])
- ;;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_TIME_HANDLER
-#
-# Checks how the system deals with time.h, what time structures
-# are used on the system, and what fields the structures have.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# USE_DELTA_FOR_TZ
-# HAVE_TM_GMTOFF
-# HAVE_TM_TZADJ
-# HAVE_TIMEZONE_VAR
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TIME_HANDLER], [
- AC_CHECK_HEADERS(sys/time.h)
- AC_HEADER_TIME
- AC_STRUCT_TIMEZONE
-
- AC_CHECK_FUNCS(gmtime_r localtime_r)
-
- AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
- tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
- if test $tcl_cv_member_tm_tzadj = yes ; then
- AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
- fi
-
- AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
- tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
- if test $tcl_cv_member_tm_gmtoff = yes ; then
- AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
- fi
-
- #
- # Its important to include time.h in this check, as some systems
- # (like convex) have timezone functions, etc.
- #
- AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern long timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
- if test $tcl_cv_timezone_long = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- else
- #
- # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
- #
- AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern time_t timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
- if test $tcl_cv_timezone_time = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BUGGY_STRTOD
-#
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" (provided by Tcl) that corrects the error.
-# Also, on Compaq's Tru64 Unix 5.0,
-# strtod(" ") returns 0.0 instead of a failure to convert.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Might defines some of the following vars:
-# strtod (=fixstrtod)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BUGGY_STRTOD], [
- AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
- if test "$tcl_strtod" = 1; then
- AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
- AC_TRY_RUN([
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
- tcl_cv_strtod_buggy=buggy)])
- if test "$tcl_cv_strtod_buggy" = buggy; then
- AC_LIBOBJ([fixstrtod])
- USE_COMPAT=1
- AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_EARLY_FLAGS
-#
-# Check for what flags are needed to be passed so the correct OS
-# features are available.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# _ISOC99_SOURCE
-# _LARGEFILE64_SOURCE
-# _LARGEFILE_SOURCE64
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_EARLY_FLAG],[
- AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
- AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
- AC_TRY_COMPILE([[#define ]$1[ 1
-]$2], $3,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
- if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
- AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
- tcl_flags="$tcl_flags $1"
- fi
-])
-
-AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
- AC_MSG_CHECKING([for required early compiler flags])
- tcl_flags=""
- TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
- [char *p = (char *)strtoll; char *q = (char *)strtoull;])
- TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
- [struct stat64 buf; int i = stat64("/", &buf);])
- TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
- [char *p = (char *)open64;])
- if test "x${tcl_flags}" = "x" ; then
- AC_MSG_RESULT([none])
- else
- AC_MSG_RESULT([${tcl_flags}])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_64BIT_FLAGS
-#
-# Check for what is defined in the way of 64-bit features.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# TCL_WIDE_INT_IS_LONG
-# TCL_WIDE_INT_TYPE
-# HAVE_STRUCT_DIRENT64
-# HAVE_STRUCT_STAT64
-# HAVE_TYPE_OFF64_T
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
- AC_MSG_CHECKING([for 64-bit integer type])
- AC_CACHE_VAL(tcl_cv_type_64bit,[
- tcl_cv_type_64bit=none
- # See if the compiler knows natively about __int64
- AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
- tcl_type_64bit=__int64, tcl_type_64bit="long long")
- # See if we should use long anyway Note that we substitute in the
- # type that is our current guess for a 64-bit type inside this check
- # program, so it should be modified only carefully...
- AC_TRY_COMPILE(,[switch (0) {
- case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
- }],tcl_cv_type_64bit=${tcl_type_64bit})])
- if test "${tcl_cv_type_64bit}" = none ; then
- AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
- AC_MSG_RESULT([using long])
- elif test "${tcl_cv_type_64bit}" = "__int64" \
- -a "${TEA_PLATFORM}" = "windows" ; then
- # TEA specific: We actually want to use the default tcl.h checks in
- # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
- AC_MSG_RESULT([using Tcl header defaults])
- else
- AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
- [What type should be used to define wide integers?])
- AC_MSG_RESULT([${tcl_cv_type_64bit}])
-
- # Now check for auxiliary declarations
- AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <dirent.h>],[struct dirent64 p;],
- tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
- if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
- fi
-
- AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
- AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
-],
- tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
- fi
-
- AC_CHECK_FUNCS(open64 lseek64)
- AC_MSG_CHECKING([for off64_t])
- AC_CACHE_VAL(tcl_cv_type_off64_t,[
- AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
-],
- tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
- dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
- dnl functions lseek64 and open64 are defined.
- if test "x${tcl_cv_type_off64_t}" = "xyes" && \
- test "x${ac_cv_func_lseek64}" = "xyes" && \
- test "x${ac_cv_func_open64}" = "xyes" ; then
- AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- fi
-])
-
-##
-## Here ends the standard Tcl configuration bits and starts the
-## TEA specific functions
-##
-
-#------------------------------------------------------------------------
-# TEA_INIT --
-#
-# Init various Tcl Extension Architecture (TEA) variables.
-# This should be the first called TEA_* macro.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substs the following vars:
-# CYGPATH
-# EXEEXT
-# Defines only:
-# TEA_VERSION
-# TEA_INITED
-# TEA_PLATFORM (windows or unix)
-#
-# "cygpath" is used on windows to generate native path names for include
-# files. These variables should only be used with the compiler and linker
-# since they generate native path names.
-#
-# EXEEXT
-# Select the executable extension based on the host type. This
-# is a lightweight replacement for AC_EXEEXT that doesn't require
-# a compiler.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_INIT], [
- # TEA extensions pass this us the version of TEA they think they
- # are compatible with.
- TEA_VERSION="3.10"
-
- AC_MSG_CHECKING([for correct TEA configuration])
- if test x"${PACKAGE_NAME}" = x ; then
- AC_MSG_ERROR([
-The PACKAGE_NAME variable must be defined by your TEA configure.ac])
- fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
-
- # 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_*)
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
- 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
-
- AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
-
- AC_SUBST(EXEEXT)
- AC_SUBST(CYGPATH)
-
- # This package name must be replaced statically for AC_SUBST to work
- AC_SUBST(PKG_LIB_FILE)
- # Substitute STUB_LIB_FILE in case package creates a stub library too.
- AC_SUBST(PKG_STUB_LIB_FILE)
-
- # We AC_SUBST these here to ensure they are subst'ed,
- # in case the user doesn't call TEA_ADD_...
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
- AC_SUBST(PKG_TCL_SOURCES)
- AC_SUBST(PKG_HEADERS)
- AC_SUBST(PKG_INCLUDES)
- AC_SUBST(PKG_LIBS)
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_SOURCES
-# PKG_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_SOURCES], [
- vars="$@"
- for i in $vars; do
- case $i in
- [\$]*)
- # allow $-var names
- PKG_SOURCES="$PKG_SOURCES $i"
- PKG_OBJECTS="$PKG_OBJECTS $i"
- ;;
- *)
- # check for existence - allows for generic/win/unix VPATH
- # To add more dirs here (like 'src'), you have to update VPATH
- # in Makefile.in as well
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find source file '$i'])
- fi
- PKG_SOURCES="$PKG_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_OBJECTS="$PKG_OBJECTS $j"
- ;;
- esac
- done
- AC_SUBST(PKG_SOURCES)
- AC_SUBST(PKG_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_STUB_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_STUB_SOURCES
-# PKG_STUB_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_STUB_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence - allows for generic/win/unix VPATH
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find stub source file '$i'])
- fi
- PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
- done
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_TCL_SOURCES --
-#
-# Specify one or more Tcl source files. These should be platform
-# independent runtime files.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_TCL_SOURCES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_TCL_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
- fi
- PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
- done
- AC_SUBST(PKG_TCL_SOURCES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_HEADERS --
-#
-# Specify one or more source headers. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_HEADERS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_HEADERS], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
- fi
- PKG_HEADERS="$PKG_HEADERS $i"
- done
- AC_SUBST(PKG_HEADERS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_INCLUDES --
-#
-# Specify one or more include dirs. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_INCLUDES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_INCLUDES], [
- vars="$@"
- for i in $vars; do
- PKG_INCLUDES="$PKG_INCLUDES $i"
- done
- AC_SUBST(PKG_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_LIBS --
-#
-# Specify one or more libraries. Users should check for
-# the right platform before adding to their list. For Windows,
-# libraries provided in "foo.lib" format will be converted to
-# "-lfoo" when using GCC (mingw).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_LIBS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_LIBS], [
- vars="$@"
- for i in $vars; do
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
- # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
- i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
- fi
- PKG_LIBS="$PKG_LIBS $i"
- done
- AC_SUBST(PKG_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CFLAGS --
-#
-# Specify one or more CFLAGS. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_CFLAGS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CFLAGS], [
- PKG_CFLAGS="$PKG_CFLAGS $@"
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CLEANFILES --
-#
-# Specify one or more CLEANFILES.
-#
-# Arguments:
-# one or more file names to clean target
-#
-# Results:
-#
-# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CLEANFILES], [
- CLEANFILES="$CLEANFILES $@"
-])
-
-#------------------------------------------------------------------------
-# TEA_PREFIX --
-#
-# Handle the --prefix=... option by defaulting to what Tcl gave
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# If --prefix or --exec-prefix was not specified, $prefix and
-# $exec_prefix will be set to the values given to Tcl when it was
-# configured.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_PREFIX], [
- if test "${prefix}" = "NONE"; then
- prefix_default=yes
- if test x"${TCL_PREFIX}" != x; then
- AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
- prefix=${TCL_PREFIX}
- else
- AC_MSG_NOTICE([--prefix defaulting to /usr/local])
- prefix=/usr/local
- fi
- fi
- if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
- -o x"${exec_prefix_default}" = x"yes" ; then
- if test x"${TCL_EXEC_PREFIX}" != x; then
- AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
- exec_prefix=${TCL_EXEC_PREFIX}
- else
- AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
- exec_prefix=$prefix
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER_CC --
-#
-# Do compiler checks the way we want. This is just a replacement
-# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER_CC], [
- # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
- # in this macro, they need to go into TEA_SETUP_COMPILER instead.
-
- AC_PROG_CC
- AC_PROG_CPP
-
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
- #--------------------------------------------------------------------
- # Checks to see if the make program sets the $MAKE variable.
- #--------------------------------------------------------------------
-
- AC_PROG_MAKE_SET
-
- #--------------------------------------------------------------------
- # Find ranlib
- #--------------------------------------------------------------------
-
- AC_CHECK_TOOL(RANLIB, ranlib)
-
- #--------------------------------------------------------------------
- # Determines the correct binary file extension (.o, .obj, .exe etc.)
- #--------------------------------------------------------------------
-
- AC_OBJEXT
- AC_EXEEXT
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER --
-#
-# Do compiler checks that use the compiler. This must go after
-# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER], [
- # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
- AC_REQUIRE([TEA_SETUP_COMPILER_CC])
-
- #------------------------------------------------------------------------
- # If we're using GCC, see if the compiler understands -pipe. If so, use it.
- # It makes compiling go faster. (This is only a performance feature.)
- #------------------------------------------------------------------------
-
- if test -z "$no_pipe" -a -n "$GCC"; then
- AC_CACHE_CHECK([if the compiler understands -pipe],
- tcl_cv_cc_pipe, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
- AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
- CFLAGS=$hold_cflags])
- if test $tcl_cv_cc_pipe = yes; then
- CFLAGS="$CFLAGS -pipe"
- fi
- fi
-
- #--------------------------------------------------------------------
- # Common compiler flag setup
- #--------------------------------------------------------------------
-
- AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_MAKE_LIB --
-#
-# Generate a line that can be used to build a shared/unshared library
-# in a platform independent manner.
-#
-# Arguments:
-# none
-#
-# Requires:
-#
-# Results:
-#
-# Defines the following vars:
-# CFLAGS - Done late here to note disturb other AC macros
-# MAKE_LIB - Command to execute to build the Tcl library;
-# differs depending on whether or not Tcl is being
-# compiled as a shared library.
-# MAKE_SHARED_LIB Makefile rule for building a shared library
-# MAKE_STATIC_LIB Makefile rule for building a static library
-# MAKE_STUB_LIB Makefile rule for building a stub library
-# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
-# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_MAKE_LIB], [
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
- MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
- MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
- AC_EGREP_CPP([manifest needed], [
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
- ], [
- # 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}"
- TEA_ADD_CLEANFILES([*.manifest])
- ])
- 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
-
- AC_SUBST(MAKE_LIB)
- AC_SUBST(MAKE_SHARED_LIB)
- AC_SUBST(MAKE_STATIC_LIB)
- AC_SUBST(MAKE_STUB_LIB)
- AC_SUBST(RANLIB_STUB)
- AC_SUBST(VC_MANIFEST_EMBED_DLL)
- AC_SUBST(VC_MANIFEST_EMBED_EXE)
-])
-
-#------------------------------------------------------------------------
-# TEA_LIB_SPEC --
-#
-# Compute the name of an existing object library located in libdir
-# from the given base name and produce the appropriate linker flags.
-#
-# Arguments:
-# basename The base name of the library without version
-# numbers, extensions, or "lib" prefixes.
-# extra_dir Extra directory in which to search for the
-# library. This location is used first, then
-# $prefix/$exec-prefix, then some defaults.
-#
-# Requires:
-# TEA_INIT and TEA_PREFIX must be called first.
-#
-# Results:
-#
-# Defines the following vars:
-# ${basename}_LIB_NAME The computed library name.
-# ${basename}_LIB_SPEC The computed linker flags.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LIB_SPEC], [
- AC_MSG_CHECKING([for $1 library])
-
- # Look in exec-prefix for the library (defined by TEA_PREFIX).
-
- tea_lib_name_dir="${exec_prefix}/lib"
-
- # Or in a user-specified location.
-
- if test x"$2" != x ; then
- tea_extra_lib_dir=$2
- else
- tea_extra_lib_dir=NONE
- fi
-
- for i in \
- `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
- if test -f "$i" ; then
- tea_lib_name_dir=`dirname $i`
- $1_LIB_NAME=`basename $i`
- $1_LIB_PATH_NAME=$i
- break
- fi
- done
-
- if test "${TEA_PLATFORM}" = "windows"; then
- $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
- else
- # Strip off the leading "lib" and trailing ".a" or ".so"
-
- tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
- $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
- fi
-
- if test "x${$1_LIB_NAME}" = x ; then
- AC_MSG_ERROR([not found])
- else
- AC_MSG_RESULT([${$1_LIB_SPEC}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TCL_HEADERS --
-#
-# Locate the private Tcl include files
-#
-# Arguments:
-#
-# Requires:
-# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_TOP_DIR_NATIVE
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
- # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
- AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
- AC_MSG_CHECKING([for Tcl private include files])
-
- TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
- TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
-
- # Check to see if tcl<Plat>Port.h isn't already with the public headers
- # Don't look for tclInt.h because that resides with tcl.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tclh}/tclWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
- result="private headers found with public headers"
- else
- TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
- else
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TCL_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -d "${TCL_BIN_DIR}/Headers" -a \
- -d "${TCL_BIN_DIR}/PrivateHeaders"; then
- TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
- else
- TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TCL_INCLUDES}"
- else
- if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
- fi
- result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TCL_TOP_DIR_NATIVE)
-
- AC_SUBST(TCL_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TCL_HEADERS --
-#
-# Locate the installed public Tcl header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tclinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
- AC_MSG_CHECKING([for Tcl public headers])
-
- AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tclh, [
- # Use the value from --with-tclinclude, if it was given
-
- if test x"${with_tclinclude}" != x ; then
- if test -f "${with_tclinclude}/tcl.h" ; then
- ac_cv_c_tclh=${with_tclinclude}
- else
- AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers directory
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tcl is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TCL_INCLUDE_SPEC}" != x ; then
- d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tcl.h" ; then
- ac_cv_c_tclh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tclh}" = x ; then
- AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tclh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
-
- TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TCL_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TK_HEADERS --
-#
-# Locate the private Tk include files
-#
-# Arguments:
-#
-# Requires:
-# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
- # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
- AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
- AC_MSG_CHECKING([for Tk private include files])
-
- TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
- TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
-
- # Check to see if tk<Plat>Port.h isn't already with the public headers
- # Don't look for tkInt.h because that resides with tk.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tkh}/tkWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
- result="private headers found with public headers"
- else
- TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
- TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
- else
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TK_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
- # Detect and add ttk subdir
- if test -d "${TK_SRC_DIR}/generic/ttk"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
- fi
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -d "${TK_BIN_DIR}/Headers" -a \
- -d "${TK_BIN_DIR}/PrivateHeaders"; then
- TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
- else
- TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TK_INCLUDES}"
- else
- if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
- fi
- result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TK_TOP_DIR_NATIVE)
- AC_SUBST(TK_XLIB_DIR_NATIVE)
-
- AC_SUBST(TK_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TK_HEADERS --
-#
-# Locate the installed public Tk header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tkinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
- AC_MSG_CHECKING([for Tk public headers])
-
- AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tkh, [
- # Use the value from --with-tkinclude, if it was given
-
- if test x"${with_tkinclude}" != x ; then
- if test -f "${with_tkinclude}/tk.h" ; then
- ac_cv_c_tkh=${with_tkinclude}
- else
- AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers directory.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tk is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tk's --prefix location,
- # relative to directory of tkConfig.sh, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TK_PREFIX}/include 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TK_INCLUDE_SPEC}" != x ; then
- d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tk.h" ; then
- ac_cv_c_tkh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tkh}" = x ; then
- AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tkh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
-
- TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TK_INCLUDES)
-
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- # On Windows and Aqua, we need the X compat headers
- AC_MSG_CHECKING([for X11 header files])
- if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
- INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
- TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
- AC_SUBST(TK_XINCLUDES)
- fi
- AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_CONFIG --
-#
-# Locate the ${1}Config.sh file and perform a sanity check on
-# the ${1} compile flags. These are used by packages like
-# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-$1=...
-#
-# Defines the following vars:
-# $1_BIN_DIR Full path to the directory containing
-# the $1Config.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CONFIG], [
- #
- # Ok, lets find the $1 configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-$1
- #
-
- if test x"${no_$1}" = x ; then
- # we reset no_$1 in case something fails here
- no_$1=true
- AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
- AC_MSG_CHECKING([for $1 configuration])
- AC_CACHE_VAL(ac_cv_c_$1config,[
-
- # First check to see if --with-$1 was specified.
- if test x"${with_$1config}" != x ; then
- case ${with_$1config} in
- */$1Config.sh )
- if test -f ${with_$1config}; then
- AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
- with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
- fi;;
- esac
- if test -f "${with_$1config}/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
- else
- AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
- fi
- fi
-
- # then check for a private $1 installation
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in \
- ../$1 \
- `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../$1 \
- `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../../$1 \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ${srcdir}/../$1 \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- if test -f "$i/unix/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i/unix; pwd)`
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_$1config}" = x ; then
- $1_BIN_DIR="# no $1 configs found"
- AC_MSG_WARN([Cannot find $1 configuration definitions])
- exit 0
- else
- no_$1=
- $1_BIN_DIR=${ac_cv_c_$1config}
- AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG --
-#
-# Load the $1Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# $1_SRC_DIR
-# $1_LIB_FILE
-# $1_LIB_SPEC
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_CONFIG], [
- AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
-
- if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
- AC_MSG_RESULT([loading])
- . "${$1_BIN_DIR}/$1Config.sh"
- else
- AC_MSG_RESULT([file not found])
- fi
-
- #
- # If the $1_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable $1_LIB_SPEC will be set to the value
- # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
- # instead of $1_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- #
-
- if test -f "${$1_BIN_DIR}/Makefile" ; then
- AC_MSG_WARN([Found Makefile - using build library specs for $1])
- $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
- $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
- $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
- $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
- $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
- fi
-
- AC_SUBST($1_VERSION)
- AC_SUBST($1_BIN_DIR)
- AC_SUBST($1_SRC_DIR)
-
- AC_SUBST($1_LIB_FILE)
- AC_SUBST($1_LIB_SPEC)
-
- AC_SUBST($1_STUB_LIB_FILE)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_PATH)
-
- # Allow the caller to prevent this auto-check by specifying any 2nd arg
- AS_IF([test "x$2" = x], [
- # Check both upper and lower-case variants
- # If a dev wanted non-stubs libs, this function could take an option
- # to not use _STUB in the paths below
- AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
- [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
- [TEA_LOAD_CONFIG_LIB($1_STUB)])
- ])
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG_LIB --
-#
-# Helper function to load correct library from another extension's
-# ${PACKAGE}Config.sh.
-#
-# Results:
-# Adds to LIBS the appropriate extension library
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
- AC_MSG_CHECKING([For $1 library for LIBS])
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${$1_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
- TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
- AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
- else
- TEA_ADD_LIBS([${$1_LIB_SPEC}])
- AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
- fi
- else
- AC_MSG_RESULT([file not found])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_EXPORT_CONFIG --
-#
-# Define the data to insert into the ${PACKAGE}Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1
-#
-# Results:
-# Substitutes the following vars:
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_EXPORT_CONFIG], [
- #--------------------------------------------------------------------
- # These are for $1Config.sh
- #--------------------------------------------------------------------
-
- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
- eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
- if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
- eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
- else
- eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- fi
- $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
- $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
- $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
- $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
- $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
- $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
-
- AC_SUBST($1_BUILD_LIB_SPEC)
- AC_SUBST($1_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_PATH)
- AC_SUBST($1_STUB_LIB_PATH)
-
- AC_SUBST(MAJOR_VERSION)
- AC_SUBST(MINOR_VERSION)
- AC_SUBST(PATCHLEVEL)
-])
-
-
-#------------------------------------------------------------------------
-# TEA_PATH_CELIB --
-#
-# Locate Keuchel's celib emulation layer for targeting Win/CE
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-celib=...
-#
-# Defines the following vars:
-# CELIB_DIR Full path to the directory containing
-# the include and platform lib files
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CELIB], [
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-celib
-
- if test x"${no_celib}" = x ; then
- # we reset no_celib in case something fails here
- no_celib=true
- AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
- AC_MSG_CHECKING([for Windows/CE celib directory])
- AC_CACHE_VAL(ac_cv_c_celibconfig,[
- # First check to see if --with-celibconfig was specified.
- if test x"${with_celibconfig}" != x ; then
- if test -d "${with_celibconfig}/inc" ; then
- ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
- else
- AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
- fi
- fi
-
- # then check for a celib library
- if test x"${ac_cv_c_celibconfig}" = x ; then
- for i in \
- ../celib-palm-3.0 \
- ../celib \
- ../../celib-palm-3.0 \
- ../../celib \
- `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
- ${srcdir}/../celib-palm-3.0 \
- ${srcdir}/../celib \
- `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
- ; do
- if test -d "$i/inc" ; then
- ac_cv_c_celibconfig=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
- if test x"${ac_cv_c_celibconfig}" = x ; then
- AC_MSG_ERROR([Cannot find celib support library directory])
- else
- no_celib=
- CELIB_DIR=${ac_cv_c_celibconfig}
- CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
- AC_MSG_RESULT([found $CELIB_DIR])
- fi
- fi
-])
-
-###
-# Tip 430 - ZipFS Modifications
-###
-#------------------------------------------------------------------------
-# SC_ZIPFS_SUPPORT
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-# TCL_ZIPFS_FLAG
-# ZIP_PROG
-#------------------------------------------------------------------------
-
-#------------------------------------------------------------------------
-# SC_PROG_ZIP
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# ZIP_PROG
-# ZIP_PROG_OPTIONS
-# ZIP_PROG_VFSSEARCH
-# ZIP_INSTALL_OBJS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ZIPFS_SUPPORT], [
- AC_MSG_CHECKING([for zipfs support])
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- INSTALL_MSGS=""
- # If our native tclsh processes the "install" command line option
- # we can use it to mint zip files
- AS_IF([$TCLSH_PROG install],[
- ZIP_PROG=${TCLSH_PROG}
- ZIP_PROG_OPTIONS="install mkzip"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
- ])
- if test "x$ZIP_PROG" = "x" ; then
- AC_CACHE_VAL(ac_cv_path_zip, [
- search_path=`echo ${PATH} | sed -e 's/:/ /g'`
- for dir in $search_path ; do
- for j in `ls -r $dir/zip 2> /dev/null` \
- `ls -r $dir/zip 2> /dev/null` ; do
- if test x"$ac_cv_path_zip" = x ; then
- if test -f "$j" ; then
- ac_cv_path_zip=$j
- break
- fi
- fi
- done
- done
- ])
- if test -f "$ac_cv_path_zip" ; then
- ZIP_PROG="$ac_cv_path_zip "
- AC_MSG_RESULT([$ZIP_PROG])
- ZIP_PROG_OPTIONS="-rq"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Found INFO Zip in environment])
- # Use standard arguments for zip
- fi
- fi
- if test "x$ZIP_PROG" = "x" ; then
- # It is not an error if an installed version of Zip can't be located.
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- else
- # ZIPFS Support
- eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
- if test ${TCL_ZIP_FILE} = "" ; then
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- INSTALL_LIBRARIES=install-libraries
- INSTALL_MSGS=install-msgs
- else
- if test ${SHARED_BUILD} = 1 ; then
- TCL_ZIPFS_SUPPORT=1
- INSTALL_LIBRARIES=install-libraries-zipfs-shared
- else
- TCL_ZIPFS_SUPPORT=2
- INSTALL_LIBRARIES=install-libraries-zipfs-static
- fi
- TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
- fi
- fi
-
- AC_SUBST(TCL_ZIP_FILE)
- AC_SUBST(TCL_ZIPFS_SUPPORT)
- AC_SUBST(TCL_ZIPFS_FLAG)
- AC_SUBST(ZIP_PROG)
- AC_SUBST(ZIP_PROG_OPTIONS)
- AC_SUBST(ZIP_PROG_VFSSEARCH)
- AC_SUBST(INSTALL_LIBRARIES)
- AC_SUBST(INSTALL_MSGS)
-])
-
-# Local Variables:
-# mode: autoconf
-# End:
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules-ext.vc b/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules-ext.vc
deleted file mode 100644
index ab86876..0000000
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules-ext.vc
+++ /dev/null
@@ -1,118 +0,0 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
-!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules.vc b/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules.vc
deleted file mode 100644
index bbb412d..0000000
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/rules.vc
+++ /dev/null
@@ -1,1723 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/targets.vc b/tcl8.6/pkgs/tdbcpostgres1.0.6/win/targets.vc
deleted file mode 100644
index 312022d..0000000
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/targets.vc
+++ /dev/null
@@ -1,98 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/ChangeLog b/tcl8.6/pkgs/tdbcpostgres1.1.0/ChangeLog
index 591f1da..591f1da 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/ChangeLog
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/ChangeLog
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/Makefile.in b/tcl8.6/pkgs/tdbcpostgres1.1.0/Makefile.in
index 61f2110..ae10535 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/Makefile.in
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/Makefile.in
@@ -11,8 +11,13 @@
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: Makefile.in,v 1.64 2007/10/23 22:08:06 hobbs Exp $
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
#========================================================================
# Nothing of the variables below this line should need to be changed.
@@ -31,6 +36,9 @@
PKG_SOURCES = @PKG_SOURCES@
PKG_OBJECTS = @PKG_OBJECTS@
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
#========================================================================
# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
@@ -50,6 +58,7 @@ PKG_HEADERS = @PKG_HEADERS@
#========================================================================
PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE)
BINARIES = $(lib_BINARIES)
@@ -63,7 +72,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
-datarootdir = @datarootdir@
+datarootdir = @datarootdir@
datadir = @datadir@
mandir = @mandir@
@@ -74,15 +83,15 @@ pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
-top_builddir = .
+top_builddir = @abs_top_builddir@
-INSTALL_OPTIONS =
-INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
-INSTALL_DATA_DIR = ${INSTALL} -d -m 755
-INSTALL_PROGRAM = ${INSTALL} -m 555
-INSTALL_DATA = ${INSTALL} -m 444
-INSTALL_SCRIPT = ${INSTALL_PROGRAM}
-INSTALL_LIBRARY = ${INSTALL_DATA}
+INSTALL_OPTIONS =
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@@ -125,25 +134,25 @@ TDBC_LIB_FILE = @TDBC_LIB_FILE@
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
-TCLLIBPATH = $(top_builddir)
-TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
- TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@`
+TCLLIBPATH = $(top_builddir) $(TDBC_BIN_DIR)
+TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(TCLLIBPATH)" \
- TDBCPOSTGRES_LIBRARY=`@CYGPATH@ $(srcdir)/library`
+ TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` \
+ TDBCPOSTGRES_LIBRARY=`@CYGPATH@ $(srcdir)/library` \
+ TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
-#WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
+#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
-# INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
+#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
PKG_CFLAGS = @PKG_CFLAGS@
@@ -165,8 +174,12 @@ AR = @AR@
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-VALGRIND = valgrind
-VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high --leak-check=yes --show-reachable=yes -v
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
+.SUFFIXES: .c .$(OBJEXT)
#========================================================================
# Start of user-definable TARGETS section
@@ -174,7 +187,7 @@ VALGRINDARGS = --tool=memcheck --num-callers=16 --leak-resolution=high --leak-c
#========================================================================
# TEA TARGETS. Please note that the "libraries:" target refers to platform
-# independent files, and the "binaries:" target inclues executable programs and
+# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries. Modify these targets so that they install
# the various pieces of your package. The make and install rules
# for the BINARIES that you specified above have already been done.
@@ -234,15 +247,27 @@ install-doc: doc
test: binaries libraries
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
-load "package ifneeded tdbc::postgres $(PACKAGE_VERSION) \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcpostgres.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcpostgres.tcl`]\;[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
- $(TCLSH_ENV) $(PKG_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
+
+gdb-test: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) \
+ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
+ $(TESTFLAGS) -singleproc 1 \
+ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
+ [list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
+
+valgrind: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
+ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+valgrindshell: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
depend:
@@ -261,6 +286,11 @@ $(PKG_LIB_FILE): $(PKG_OBJECTS)
${MAKE_LIB}
$(RANLIB) $(PKG_LIB_FILE)
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+ -rm -f $(PKG_STUB_LIB_FILE)
+ ${MAKE_STUB_LIB}
+ $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
@@ -291,26 +321,34 @@ COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
-DIST_INSTALL_DATA = ${INSTALL} -m 644
-DIST_INSTALL_SCRIPT = ${INSTALL} -m 755
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
$(INSTALL_DATA_DIR) $(DIST_DIR)
- $(DIST_INSTALL_DATA) $(srcdir)/license.terms \
- $(srcdir)/ChangeLog $(srcdir)/README $(srcdir)/TODO \
- $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
- $(srcdir)/Makefile.in $(srcdir)/pkgIndex.tcl.in \
- $(DIST_DIR)/
+
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
$(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
- $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/ChangeLog \
- $(srcdir)/tclconfig/README.txt $(srcdir)/tclconfig/tcl.m4 \
- $(srcdir)/tclconfig/install-sh \
- $(DIST_DIR)/tclconfig/
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(srcdir)/TODO \
+ $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/doc
$(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc_postgres.n $(DIST_DIR)/doc/
@@ -390,14 +428,6 @@ install-lib-binaries: binaries
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
- stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
- if test "x$$stub" = "xstub"; then \
- echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
- else \
- echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
- $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
- fi; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
@@ -438,8 +468,6 @@ install-bin-binaries: binaries
fi; \
done
-.SUFFIXES: .c .$(OBJEXT)
-
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
@@ -457,6 +485,7 @@ uninstall-binaries:
done
.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb gdb-test valgrind valgrindshell
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/README b/tcl8.6/pkgs/tdbcpostgres1.1.0/README
index 0cb97bd..3f660ed 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/README
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/README
@@ -1,6 +1,6 @@
README: tdbcpostgres
- This is the 1.0.6 source distribution of the driver for Tcl
+ This is the 1.1.0 source distribution of the driver for Tcl
Database Connectivity (TDBC) to access Postgres databases. TDBC and
its drivers are available from a Fossil version control repository
at http://tdbc.tcl.tk/
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/TODO b/tcl8.6/pkgs/tdbcpostgres1.1.0/TODO
index 51023dd..51023dd 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/TODO
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/TODO
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/aclocal.m4 b/tcl8.6/pkgs/tdbcpostgres1.1.0/aclocal.m4
index 83d361c..83d361c 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/aclocal.m4
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/aclocal.m4
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/configure b/tcl8.6/pkgs/tdbcpostgres1.1.0/configure
index 4627c88..03b3942 100755
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/configure
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tdbcpostgres 1.0.6.
+# Generated by GNU Autoconf 2.69 for tdbcpostgres 1.1.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='tdbcpostgres'
PACKAGE_TARNAME='tdbcpostgres'
-PACKAGE_VERSION='1.0.6'
-PACKAGE_STRING='tdbcpostgres 1.0.6'
+PACKAGE_VERSION='1.1.0'
+PACKAGE_STRING='tdbcpostgres 1.1.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -648,17 +648,10 @@ 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
TDBC_LIB_FILE
TDBC_VERSION
@@ -694,6 +687,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1308,7 +1307,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 tdbcpostgres 1.0.6 to adapt to many kinds of systems.
+\`configure' configures tdbcpostgres 1.1.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1369,7 +1368,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of tdbcpostgres 1.0.6:";;
+ short | recursive ) echo "Configuration of tdbcpostgres 1.1.0:";;
esac
cat <<\_ACEOF
@@ -1472,7 +1471,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-tdbcpostgres configure 1.0.6
+tdbcpostgres configure 1.1.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1634,206 +1633,6 @@ $as_echo "$ac_res" >&6; }
} # 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
-
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
@@ -2070,11 +1869,124 @@ rm -f conftest.val
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
+
+# 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
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 tdbcpostgres $as_me 1.0.6, which was
+It was created by tdbcpostgres $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2430,26 +2342,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2458,7 +2360,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2550,6 +2452,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2659,6 +2610,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2685,13 +2639,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -3792,6 +3750,7 @@ $as_echo "$as_me: WARNING: --with-tdbc argument should refer to directory contai
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
; do
@@ -4692,20 +4651,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -5377,470 +5322,11 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long, long.
+#-----------------------------------------------------------------------
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
$as_echo_n "checking for inline... " >&6; }
@@ -5958,10 +5444,9 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-$as_echo "#define DONT_TD_VOID 1" >>confdefs.h
-
#-----------------------------------------------------------------------
+# __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,
@@ -6115,6 +5600,7 @@ fi
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -6126,8 +5612,20 @@ fi
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -6219,6 +5717,11 @@ $as_echo "${ac_cv_c_tclh}" >&6; }
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -7924,7 +7427,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8558,9 +8061,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -9253,17 +8756,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. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-
-$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
-
-
-#--------------------------------------------------------------------
# Locate the ws2_32 library; we need it for ntohs and friends
#--------------------------------------------------------------------
@@ -9516,11 +9008,12 @@ $as_echo_n "checking for tclsh... " >&6; }
$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.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
@@ -10069,7 +9562,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 tdbcpostgres $as_me 1.0.6, which was
+This file was extended by tdbcpostgres $as_me 1.1.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -10122,7 +9615,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="\\
-tdbcpostgres config.status 1.0.6
+tdbcpostgres config.status 1.1.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/configure.ac b/tcl8.6/pkgs/tdbcpostgres1.1.0/configure.ac
index 67430fa..46881cb 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/configure.ac
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/configure.ac
@@ -4,14 +4,22 @@ dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
+# Sample configure.ac for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
#-----------------------------------------------------------------------
-AC_INIT([tdbcpostgres], [1.0.6])
+AC_INIT([tdbcpostgres], [1.1.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -19,7 +27,7 @@ AC_INIT([tdbcpostgres], [1.0.6])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
@@ -85,15 +93,20 @@ TEA_PREFIX
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# Setup inlining if available. Check sizeof long long, long.
+#-----------------------------------------------------------------------
+
AC_C_INLINE
AC_CHECK_TYPE([long long],[
AC_DEFINE([HAVE_LONG_LONG],[1])
AC_CHECK_SIZEOF([long long])
],[],[])
AC_CHECK_SIZEOF([long])
-AC_DEFINE([DONT_TD_VOID],[1])
#-----------------------------------------------------------------------
+# __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,
@@ -122,6 +135,7 @@ TEA_ADD_STUB_SOURCES()
TEA_ADD_TCL_SOURCES([library/tdbcpostgres.tcl])
#--------------------------------------------------------------------
+# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
@@ -133,8 +147,20 @@ TEA_ADD_TCL_SOURCES([library/tdbcpostgres.tcl])
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
@@ -143,6 +169,11 @@ TEA_ADD_TCL_SOURCES([library/tdbcpostgres.tcl])
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
@@ -180,15 +211,6 @@ AC_TYPE_INTPTR_T
AC_TYPE_UINTPTR_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. Add Tk too if necessary.
-#--------------------------------------------------------------------
-
-AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
-
-#--------------------------------------------------------------------
# Locate the ws2_32 library; we need it for ntohs and friends
#--------------------------------------------------------------------
@@ -213,11 +235,12 @@ TEA_MAKE_LIB
#--------------------------------------------------------------------
TEA_PROG_TCLSH
+#TEA_PROG_WISH
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
-# which require substituting th AC variables in. Include these here.
+# which require substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/doc/tdbc_postgres.n b/tcl8.6/pkgs/tdbcpostgres1.1.0/doc/tdbc_postgres.n
index 4ffa7c7..4ffa7c7 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/doc/tdbc_postgres.n
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/doc/tdbc_postgres.n
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/fakepq.h b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/fakepq.h
index b3c20dc..b3c20dc 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/fakepq.h
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/fakepq.h
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/int2ptr_ptr2int.h b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/int2ptr_ptr2int.h
index 4b0a15d..4b0a15d 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/generic/int2ptr_ptr2int.h
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/int2ptr_ptr2int.h
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubDefs.txt b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubDefs.txt
index f7bb85e..f7bb85e 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubDefs.txt
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubDefs.txt
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubInit.c b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubInit.c
index bccd408..bccd408 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubInit.c
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubInit.c
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubs.h b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubs.h
index c084989..c084989 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/pqStubs.h
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/pqStubs.h
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/tdbcpostgres.c b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/tdbcpostgres.c
index e5c5eb6..e5c5eb6 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/generic/tdbcpostgres.c
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/generic/tdbcpostgres.c
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/library/tdbcpostgres.tcl b/tcl8.6/pkgs/tdbcpostgres1.1.0/library/tdbcpostgres.tcl
index 6294a48..6294a48 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/library/tdbcpostgres.tcl
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/library/tdbcpostgres.tcl
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/license.terms b/tcl8.6/pkgs/tdbcpostgres1.1.0/license.terms
index f143364..f143364 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/license.terms
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/license.terms
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbcpostgres1.1.0/pkgIndex.tcl.in
index 7798a70..0999069 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/pkgIndex.tcl.in
@@ -1,4 +1,4 @@
-# Package index file for tdbc::postgres
+# Index file to load the TDBC Postgres package.
if {[catch {package require Tcl @TCL_VERSION_REQ@}]} {
return
diff --git a/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/README.txt b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension. For more information on TEA see:
+
+ http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+ http://tcl.sourceforge.net/
+
+This package is a freely available open source package. You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt This file
+
+install-sh Program used for copying binaries and script files
+ to their install locations.
+
+tcl.m4 Collection of Tcl autoconf macros. Included by a package's
+ aclocal.m4 to define TEA_* macros.
diff --git a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/install-sh b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/tdbc1.0.6/tclconfig/install-sh
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/tcl.m4
new file mode 100644
index 0000000..2ec82a2
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tclconfig/tcl.m4
@@ -0,0 +1,4184 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+# 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
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig="${withval}")
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 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/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/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
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig="${withval}")
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+ else
+ no_tk=
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_PATCH_LEVEL)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ AC_MSG_CHECKING([platform])
+ hold_cc=$CC; CC="$TCL_CC"
+ AC_TRY_COMPILE(,[
+ #ifdef _WIN32
+ #error win32
+ #endif
+ ], [
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+ ], [
+ TEA_PLATFORM="windows"
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
+ )
+ CC=$hold_cc
+ AC_MSG_RESULT($TEA_PLATFORM)
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+ AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+ [Building extension source?])
+ # 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:
+ AC_SUBST(CLEANFILES)
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FLAG)
+ AC_SUBST(TK_LIB_SPEC)
+
+ AC_SUBST(TK_STUB_LIB_FILE)
+ AC_SUBST(TK_STUB_LIB_FLAG)
+ AC_SUBST(TK_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+# --enable-stubs=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+# 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)]),
+ [shared_ok=$enableval], [shared_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ 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
+
+ # 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, [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)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol defaults to
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $PACKAGE_VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${PACKAGE_VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # 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
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+ ], [
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+ ])
+ AC_CHECK_TOOL(AR, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
+ 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
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[[4-9]]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+ TEA_ADD_LIBS([ucrt.lib])
+ ;;
+ *)
+ ;;
+ 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
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ 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
+ AC_CHECK_TOOL(RC, windres)
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ AC_CACHE_CHECK(for cross-compile version of gcc,
+ ac_cv_cross,
+ AC_TRY_COMPILE([
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+ ], [],
+ ac_cv_cross=yes,
+ ac_cv_cross=no)
+ )
+ 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-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+ ], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+ ])
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ 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.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ 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} ${CFLAGS} ${LDFLAGS} -shared'
+ AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ ])
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ CFLAGS_OPTIMIZE="-O2"
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+ ])
+ # 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} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ;;
+ DragonFly-*|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=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+ 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}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and 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:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ tcl_cv_cc_visibility_hidden=yes
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+ tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+ tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done])
+ ])
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ ], [
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+ ])
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ 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.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # 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.
+
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
+ IRIX*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [extern],
+ [No Compiler support for module scope symbols])
+ ])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+ AC_TRY_RUN([
+#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;
+ }
+ ],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+ )
+ if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH, 1,
+ [Defined when mingw does not support SEH])
+ 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.
+ #
+ AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+ tcl_cv_eh_disposition,
+ AC_TRY_COMPILE([
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+ ],[
+ EXCEPTION_DISPOSITION x;
+ ],
+ tcl_cv_eh_disposition=yes,
+ tcl_cv_eh_disposition=no)
+ )
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+ AC_DEFINE(EXCEPTION_DISPOSITION, int,
+ [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+ 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.
+
+ AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+ tcl_cv_winnt_ignore_void,
+ AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+ ], [
+ CHAR c;
+ SHORT s;
+ LONG l;
+ ],
+ tcl_cv_winnt_ignore_void=yes,
+ tcl_cv_winnt_ignore_void=no)
+ )
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+ [Defined when cygwin/mingw ignores VOID define in winnt.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.
+
+ AC_CACHE_CHECK(for cast to union support,
+ tcl_cv_cast_to_union,
+ AC_TRY_COMPILE([],
+ [
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+ ],
+ tcl_cv_cast_to_union=yes,
+ tcl_cv_cast_to_union=no)
+ )
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+ AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+ [Defined when compiler supports casting to union type.])
+ fi
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# Locate the X11 header files and the X11 library archive. Try
+# the ac_path_x macro first, but if it doesn't find the X stuff
+# (e.g. because there's no xmkmf program) then check through
+# a list of possible directories. Under some conditions the
+# autoconf macro will return an include directory that contains
+# no include files, so double-check its result just to be safe.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Xlib.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Xlib.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test "$found_xincludes" = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" (provided by Tcl) that corrects the error.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ TEA_VERSION="3.13"
+
+ AC_MSG_CHECKING([TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.ac])
+ fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+
+ # 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_*|*MINGW64_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ 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
+
+ AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
+ i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+# Specify one or more CLEANFILES.
+#
+# Arguments:
+# one or more file names to clean target
+#
+# Results:
+#
+# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+ CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ AC_PROG_CC
+ AC_PROG_CPP
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_CHECK_TOOL(RANLIB, ranlib)
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ AC_CACHE_CHECK([if the compiler understands -pipe],
+ tcl_cv_cc_pipe, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+ ], [
+ # 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}"
+ TEA_ADD_CLEANFILES([*.manifest])
+ ])
+ 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
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+ AC_SUBST(VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(VC_MANIFEST_EMBED_EXE)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tcl<Plat>Port.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tk<Plat>Port.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ fi
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+ $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ AS_IF([test "x$2" = x], [
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+ [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+ [TEA_LOAD_CONFIG_LIB($1_STUB)])
+ ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+# Helper function to load correct library from another extension's
+# ${PACKAGE}Config.sh.
+#
+# Results:
+# Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+ AC_MSG_CHECKING([For $1 library for LIBS])
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${$1_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+ TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+ AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+ else
+ TEA_ADD_LIBS([${$1_LIB_SPEC}])
+ AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+ fi
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+# Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1
+#
+# Results:
+# Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+ #--------------------------------------------------------------------
+ # These are for $1Config.sh
+ #--------------------------------------------------------------------
+
+ # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+ eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+ if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+ else
+ eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ fi
+ $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
+ $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
+ $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
+ $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
+
+ AC_SUBST($1_BUILD_LIB_SPEC)
+ AC_SUBST($1_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_PATH)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ AC_SUBST(MAJOR_VERSION)
+ AC_SUBST(MINOR_VERSION)
+ AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
+###
+# Tip 430 - ZipFS Modifications
+###
+#------------------------------------------------------------------------
+# SC_ZIPFS_SUPPORT
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+# TCL_ZIPFS_FLAG
+# ZIP_PROG
+#------------------------------------------------------------------------
+
+#------------------------------------------------------------------------
+# SC_PROG_ZIP
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# ZIP_PROG
+# ZIP_PROG_OPTIONS
+# ZIP_PROG_VFSSEARCH
+# ZIP_INSTALL_OBJS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ZIPFS_SUPPORT], [
+ AC_MSG_CHECKING([for zipfs support])
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ INSTALL_MSGS=""
+ # If our native tclsh processes the "install" command line option
+ # we can use it to mint zip files
+ AS_IF([$TCLSH_PROG install],[
+ ZIP_PROG=${TCLSH_PROG}
+ ZIP_PROG_OPTIONS="install mkzip"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
+ ])
+ if test "x$ZIP_PROG" = "x" ; then
+ AC_CACHE_VAL(ac_cv_path_zip, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip "
+ AC_MSG_RESULT([$ZIP_PROG])
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Found INFO Zip in environment])
+ # Use standard arguments for zip
+ fi
+ fi
+ if test "x$ZIP_PROG" = "x" ; then
+ # It is not an error if an installed version of Zip can't be located.
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ else
+ # ZIPFS Support
+ eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
+ if test ${TCL_ZIP_FILE} = "" ; then
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ INSTALL_LIBRARIES=install-libraries
+ INSTALL_MSGS=install-msgs
+ else
+ if test ${SHARED_BUILD} = 1 ; then
+ TCL_ZIPFS_SUPPORT=1
+ INSTALL_LIBRARIES=install-libraries-zipfs-shared
+ else
+ TCL_ZIPFS_SUPPORT=2
+ INSTALL_LIBRARIES=install-libraries-zipfs-static
+ fi
+ TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
+ fi
+ fi
+
+ AC_SUBST(TCL_ZIP_FILE)
+ AC_SUBST(TCL_ZIPFS_SUPPORT)
+ AC_SUBST(TCL_ZIPFS_FLAG)
+ AC_SUBST(ZIP_PROG)
+ AC_SUBST(ZIP_PROG_OPTIONS)
+ AC_SUBST(ZIP_PROG_VFSSEARCH)
+ AC_SUBST(INSTALL_LIBRARIES)
+ AC_SUBST(INSTALL_MSGS)
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/all.tcl b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/all.tcl
index c0bbaa7..c0bbaa7 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/all.tcl
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/all.tcl
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/future/tdbcpostgre.test.tcl b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/future/tdbcpostgre.test.tcl
index b0c5775..b0c5775 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/future/tdbcpostgre.test.tcl
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/future/tdbcpostgre.test.tcl
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/tdbcpostgres.test b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/tdbcpostgres.test
index 3090776..3090776 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/tests/tdbcpostgres.test
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/tests/tdbcpostgres.test
diff --git a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/makefile.vc b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/makefile.vc
index 05ec4e7..3b20f0b 100644
--- a/tcl8.6/pkgs/tdbcpostgres1.0.6/win/makefile.vc
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/makefile.vc
@@ -1,111 +1,111 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for TBDC Postgres interface
-#
-# Basic build, test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = tdbcpostgres
-# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
-# without -DUNICODE. Keep that behaviour.
-USE_WIDECHAR_API = 0
-
-!include "rules-ext.vc"
-
-# nmakehelp -V <file> <tag> will search the file for tag, skips until a
-# number and returns all character until a character not in [0-9.ab]
-# is read.
-!if [echo REM = This file is generated from Makefile.vc > versions.vc]
-!endif
-!if [echo TCL_VERSION_REQ = \>> versions.vc] \
- && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
-!endif
-!include "versions.vc"
-
-PRJ_OBJS = \
- $(TMP_DIR)\tdbcpostgres.obj \
- $(TMP_DIR)\pqStubInit.obj
-
-# Uncomment the following line if you want to build and install stubs
-# PRJ_STUBOBJS = $(TMP_DIR)\pqStubInit.obj
-
-PRJ_HEADERS = \
- $(GENERICDIR)\fakepq.h \
- $(GENERICDIR)\pqStubs.h
-
-# Locate TDBC headers and libraries.
-# In principle, we don't need the TDBC source directory, and an installed
-# TDBC should suffice. But that needs additional machinery not implemented
-# yet.
-!if [echo TDBC_DIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
-!error Could not locate TDBC source directory.
-!endif
-!include nmakehlp.out
-
-# Get the TDBC version from its configure.ac
-!if [echo TDBC_DOTVERSION = \> versions.vc] \
- && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
-!error Could not retrieve TDBC version.
-!endif
-!include versions.vc
-
-TDBC_VERSION = $(TDBC_DOTVERSION:.=)
-TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
-TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
-TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
-TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
-TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
-
-PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
-
-!if !$(STATIC_BUILD)
-PRJ_LIBS = $(TDBCSTUBLIB)
-!endif
-
-# Disable standard test target because we have a custom one
-DISABLE_TARGET_test = 1
-!include "$(_RULESDIR)\targets.vc"
-
-# Additional default actions for install
-install: default-install-docs-n
-
-# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
-# all replacements below so define our own target.
-pkgindex: $(OUT_DIR)\pkgIndex.tcl
-$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
- @nmakehlp -s << $** > $@
-@PACKAGE_NAME@ $(PROJECT)
-@PACKAGE_VERSION@ $(DOTVERSION)
-@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-test: setup $(PROJECT)
- @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @set TDBC_LIBRARY=$(LIBDIR:\=/)
- @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
-!if $(TCLINSTALL)
- @set PATH=$(_TCLDIR)\bin;$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
-!else
- @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
- $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
- -load "package ifneeded tdbc::postgres $(DOTVERSION) \
- {source {$(LIBDIR:\=/)/tdbcpostgres.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
- package ifneeded tdbc $(TDBC_DOTVERSION) \
- {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
-!endif
-
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for TBDC Postgres interface
+#
+# Basic build, test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = tdbcpostgres
+# Tcl 8.6 etc. compile with /DUNICODE. TDBC pre-nmake reform compiled
+# without -DUNICODE. Keep that behaviour.
+USE_WIDECHAR_API = 0
+
+!include "rules-ext.vc"
+
+# nmakehelp -V <file> <tag> will search the file for tag, skips until a
+# number and returns all character until a character not in [0-9.ab]
+# is read.
+!if [echo REM = This file is generated from Makefile.vc > versions.vc]
+!endif
+!if [echo TCL_VERSION_REQ = \>> versions.vc] \
+ && [nmakehlp -V ..\configure.ac TCL_VERSION_REQ >> versions.vc]
+!endif
+!include "versions.vc"
+
+PRJ_OBJS = \
+ $(TMP_DIR)\tdbcpostgres.obj \
+ $(TMP_DIR)\pqStubInit.obj
+
+# Uncomment the following line if you want to build and install stubs
+# PRJ_STUBOBJS = $(TMP_DIR)\pqStubInit.obj
+
+PRJ_HEADERS = \
+ $(GENERICDIR)\fakepq.h \
+ $(GENERICDIR)\pqStubs.h
+
+# Locate TDBC headers and libraries.
+# In principle, we don't need the TDBC source directory, and an installed
+# TDBC should suffice. But that needs additional machinery not implemented
+# yet.
+!if [echo TDBC_DIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tdbcInt.h >> nmakehlp.out]
+!error Could not locate TDBC source directory.
+!endif
+!include nmakehlp.out
+
+# Get the TDBC version from its configure.ac
+!if [echo TDBC_DOTVERSION = \> versions.vc] \
+ && [nmakehlp -V "$(TDBC_DIR)\configure.ac" tdbc >> versions.vc]
+!error Could not retrieve TDBC version.
+!endif
+!include versions.vc
+
+TDBC_VERSION = $(TDBC_DOTVERSION:.=)
+TDBC_GENERIC_DIR = $(TDBC_DIR)\generic
+TDBCSTUBLIBNAME = tdbcstub$(TDBC_VERSION).lib
+TDBCSTUBLIB = $(TDBC_DIR)\win\$(BUILDDIRTOP)\$(TDBCSTUBLIBNAME)
+TDBC_LIB_FILE = tdbc$(TDBC_VERSION).dll
+TDBC_BIN_DIR = $(TDBC_DIR)/win/$(BUILDDIRTOP)
+
+PRJ_INCLUDES = -I"$(TDBC_GENERIC_DIR)"
+
+!if !$(STATIC_BUILD)
+PRJ_LIBS = $(TDBCSTUBLIB)
+!endif
+
+# Disable standard test target because we have a custom one
+DISABLE_TARGET_test = 1
+!include "$(_RULESDIR)\targets.vc"
+
+# Additional default actions for install
+install: default-install-docs-n
+
+# The TIP 477 generation of pkgIndex.tcl from pkgIndex.tcl.in does not include
+# all replacements below so define our own target.
+pkgindex: $(OUT_DIR)\pkgIndex.tcl
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+ @nmakehlp -s << $** > $@
+@PACKAGE_NAME@ $(PROJECT)
+@PACKAGE_VERSION@ $(DOTVERSION)
+@TCL_VERSION_REQ@ $(TCL_VERSION_REQ)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+test: setup $(PROJECT)
+ @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @set TDBC_LIBRARY=$(LIBDIR:\=/)
+ @$(CPY) $(LIBDIR)\*.tcl $(OUT_DIR)
+!if $(TCLINSTALL)
+ @set PATH=$(_TCLDIR)\bin;$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS)
+!else
+ @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
+ $(DEBUGGER) $(TCLSH) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) \
+ -load "package ifneeded tdbc::postgres $(DOTVERSION) \
+ {source {$(LIBDIR:\=/)/tdbcpostgres.tcl};load {$(PRJLIB:\=/)} $(PROJECT)};\
+ package ifneeded tdbc $(TDBC_DOTVERSION) \
+ {source {$(TDBC_BIN_DIR:\=/)/tdbc.tcl};load {$(TDBC_BIN_DIR:\=/)/$(TDBC_LIB_FILE)} tdbc}"
+!endif
+
diff --git a/tcl8.6/pkgs/tdbcmysql1.0.6/win/nmakehlp.c b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/tdbcmysql1.0.6/win/nmakehlp.c
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/rules-ext.vc b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules-ext.vc
index ab86876..58c70fa 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/rules-ext.vc
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules-ext.vc
@@ -1,118 +1,118 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!ifdef TCLDIR
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/rules.vc b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules.vc
index bbb412d..7fc51c1 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/rules.vc
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/rules.vc
@@ -1,1723 +1,1723 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 0
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!message *** Using $(NMAKEHLPC)
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+# Old linkers (Visual C++ 6 in particular) will link for fast loading
+# on Win98. Since we do not support Win98 any more, we specify nowin98
+# as recommended for NT and later. However, this is only required by
+# IX86 on older compilers and only needed if we are not doing a static build.
+
+!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
+# Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!endif
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcpostgres1.1.0/win/targets.vc b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/targets.vc
new file mode 100644
index 0000000..7f1d388
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcpostgres1.1.0/win/targets.vc
@@ -0,0 +1,98 @@
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/Makefile.in b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/Makefile.in
deleted file mode 100644
index ba69eec..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/Makefile.in
+++ /dev/null
@@ -1,297 +0,0 @@
-# Makefile.in --
-#
-# This file is a Makefile for Sample TEA Extension. If it has the name
-# "Makefile.in" then it is a template for a Makefile; to generate the
-# actual Makefile, run "./configure", which is a configuration script
-# generated by the "autoconf" program (constructs like "@foo@" will get
-# replaced in the actual Makefile.
-#
-# Copyright (c) 1999 Scriptics Corporation.
-# Copyright (c) 2002-2005 ActiveState Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# RCS: @(#) $Id: Makefile.in,v 1.64 2007/10/23 22:08:06 hobbs Exp $
-
-#========================================================================
-# Nothing of the variables below this line should need to be changed.
-# Please check the TARGETS section below to make sure the make targets
-# are correct.
-#========================================================================
-
-#========================================================================
-# The names of the source files is defined in the configure script.
-# The object files are used for linking into the final library.
-# This will be used when a dist target is added to the Makefile.
-# It is not important to specify the directory, as long as it is the
-# $(srcdir) or in the generic, win or unix subdirectory.
-#========================================================================
-
-#========================================================================
-# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
-# this package that need to be installed, if any.
-#========================================================================
-
-PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
-
-#========================================================================
-# "PKG_LIB_FILE" refers to the library (dynamic or static as per
-# configuration options) composed of the named objects.
-#========================================================================
-
-PKG_LIB_FILE = @PKG_LIB_FILE@
-PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
-
-lib_BINARIES = $(PKG_LIB_FILE)
-BINARIES = $(lib_BINARIES)
-
-SHELL = @SHELL@
-
-srcdir = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-libdir = @libdir@
-includedir = @includedir@
-datarootdir = @datarootdir@
-datadir = @datadir@
-mandir = @mandir@
-
-DESTDIR =
-
-PKG_DIR = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
-pkgdatadir = $(datadir)/$(PKG_DIR)
-pkglibdir = $(libdir)/$(PKG_DIR)
-pkgincludedir = $(includedir)/$(PKG_DIR)
-tmdir = $(libdir)/tcl$(TCL_MAJOR_VERSION)/$(TCL_VERSION)
-pkgslash = `echo $(PACKAGE_NAME) | sed s=tdbc=tdbc/=`
-pkgtmdir = $(tmdir)/tdbc
-pkgtmfile = $(tmdir)/$(pkgslash)-$(PACKAGE_VERSION).tm
-
-top_builddir = .
-
-INSTALL_OPTIONS =
-INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
-INSTALL_DATA_DIR = ${INSTALL} -d -m 755
-INSTALL_PROGRAM = ${INSTALL} -m 555
-INSTALL_DATA = ${INSTALL} -m 444
-INSTALL_SCRIPT = ${INSTALL_PROGRAM}
-INSTALL_LIBRARY = ${INSTALL_DATA}
-
-TCL_VERSION = @TCL_VERSION@
-TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@
-
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-#TCL_DEFS = @TCL_DEFS@
-TCL_BIN_DIR = @TCL_BIN_DIR@
-TCL_SRC_DIR = @TCL_SRC_DIR@
-#TK_BIN_DIR = @TK_BIN_DIR@
-#TK_SRC_DIR = @TK_SRC_DIR@
-
-TDBC_VERSION = @TDBC_VERSION@
-TDBC_BIN_DIR = @tdbc_BIN_DIR@
-TDBC_LIB_FILE = @TDBC_LIB_FILE@
-
-# Not used, but retained for reference of what libs Tcl required
-#TCL_LIBS = @TCL_LIBS@
-
-#========================================================================
-# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
-# package without installing. The other environment variables allow us
-# to test against an uninstalled Tcl. Add special env vars that you
-# require for testing here (like TCLX_LIBRARY).
-#========================================================================
-
-EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
-#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
-TCLLIBPATH = $(top_builddir)
-TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
- TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@`
-PKG_ENV = PATH="$(EXTRA_PATH):$(PATH)" \
- TCLLIBPATH="$(TCLLIBPATH)"
-
-TCLSH_PROG = @TCLSH_PROG@
-TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)
-
-#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
-#WISH_PROG = @WISH_PROG@
-#WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)
-
-SHARED_BUILD = @SHARED_BUILD@
-
-INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
-
-# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
-CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
-CLEANFILES = @CLEANFILES@
-
-#========================================================================
-# Start of user-definable TARGETS section
-#========================================================================
-
-#========================================================================
-# TEA TARGETS. Please note that the "libraries:" target refers to platform
-# independent files, and the "binaries:" target inclues executable programs and
-# platform-dependent libraries. Modify these targets so that they install
-# the various pieces of your package. The make and install rules
-# for the BINARIES that you specified above have already been done.
-#========================================================================
-
-all: libraries doc
-
-libraries:
-
-#========================================================================
-# Your doc target should differentiate from doc builds (by the developer)
-# and doc installs (see install-doc), which just install the docs on the
-# end user machine when building from source.
-#========================================================================
-
-doc:
-
-install: all install-binaries install-libraries install-doc
-
-install-binaries: install-lib-binaries
-
-#========================================================================
-# This rule installs platform-independent files, such as header files.
-# The list=...; for p in $$list handles the empty list case x-platform.
-#========================================================================
-
-install-libraries: libraries
-
-#========================================================================
-# Install documentation. Unix manpages should go in the $(mandir)
-# directory.
-#========================================================================
-
-install-doc: doc
- @$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
- @echo "Installing documentation in $(DESTDIR)$(mandir)"
- @list='$(srcdir)/doc/*.n'; for i in $$list; do \
- echo "Installing $$i"; \
- $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
- done
-
-# If the semicolon is omitted after the [list source ...], then
-# at least one version of msys make replaces the slashes in the
-# $(srcdir)/library/tdbcsqlite3.tcl path with backslashes, causing
-# the [package ifneeded] to fail. Leave it in, even though it's
-# spurious.
-test: libraries
- $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) -load \
- "package ifneeded tdbc::sqlite3 $(PACKAGE_VERSION) \
- [list source `@CYGPATH@ $(srcdir)/library/tdbcsqlite3.tcl`];\
- package ifneeded tdbc ${TDBC_VERSION} \
- [list source `@CYGPATH@ $(TDBC_BIN_DIR)/tdbc.tcl`]\;[list load `@CYGPATH@ $(TDBC_BIN_DIR)/$(TDBC_LIB_FILE)` tdbc]"
-
-shell: libraries
- @$(TCLSH) $(SCRIPT)
-
-gdb:
- $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
-
-depend:
-
-#========================================================================
-# Distribution creation
-# You may need to tweak this target to make it work correctly.
-#========================================================================
-
-#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
-COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
-DIST_ROOT = /tmp/dist
-DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
-
-dist-clean:
- rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
-
-dist: dist-clean
- mkdir -p $(DIST_DIR)
- cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
- $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
- $(srcdir)/configure.ac $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
-
- for i in $(srcdir)/*.[ch]; do \
- if [ -f $$i ]; then \
- cp -p $$i $(DIST_DIR)/ ; \
- fi; \
- done;
-
- mkdir $(DIST_DIR)/tclconfig
- cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
- $(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
-
- mkdir $(DIST_DIR)/doc
- cp -p $(srcdir)/doc/tdbc_sqlite3.n $(DIST_DIR)/doc/
-
- mkdir $(DIST_DIR)/library
- cp -p $(srcdir)/library/tdbcsqlite3.tcl $(DIST_DIR)/library/
-
- mkdir $(DIST_DIR)/tests
- cp -p $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcsqlite3.test \
- $(DIST_DIR)/tests/
-
- mkdir $(DIST_DIR)/win
- cp -p $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
- $(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
- $(srcdir)/win/rules.vc $(DIST_DIR)/win/
-
- (cd $(DIST_ROOT); $(COMPRESS);)
-
-#========================================================================
-# End of user-definable section
-#========================================================================
-
-#========================================================================
-# Don't modify the file to clean here. Instead, set the "CLEANFILES"
-# variable in configure.in
-#========================================================================
-
-clean:
- -rm -f *.core *.core
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean: clean
- -rm -f *.tab.c
- -rm -f $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log config.status
-
-#========================================================================
-# Install binary object libraries. On Windows this includes both .dll and
-# .lib files. Because the .lib files are not explicitly listed anywhere,
-# we need to deduce their existence from the .dll file of the same name.
-# Library files go into the lib directory.
-# In addition, this will generate the pkgIndex.tcl
-# file in the install location (assuming it can find a usable tclsh shell)
-#
-# You should not have to modify this target.
-#========================================================================
-
-install-lib-binaries:
- @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkgtmdir)
- $(INSTALL_DATA) $(srcdir)/library/tdbcsqlite3.tcl \
- $(DESTDIR)$(pkgtmfile)
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) \
- && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-uninstall-binaries:
- list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
- p=`basename $$p`; \
- rm -f $(DESTDIR)$(pkglibdir)/$$p; \
- done
-
-.PHONY: all clean distclean doc install libraries test
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure
deleted file mode 100755
index 0b48245..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure
+++ /dev/null
@@ -1,5150 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tdbcsqlite3 1.0.6.
-#
-#
-# 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"
- 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='tdbcsqlite3'
-PACKAGE_TARNAME='tdbcsqlite3'
-PACKAGE_VERSION='1.0.6'
-PACKAGE_STRING='tdbcsqlite3 1.0.6'
-PACKAGE_BUGREPORT=''
-PACKAGE_URL=''
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-TCLSH_PROG
-TCL_MINOR_VERSION
-TCL_MAJOR_VERSION
-STUBS_BUILD
-SHARED_BUILD
-TCL_THREADS
-TCL_INCLUDES
-TDBC_LIB_FILE
-TDBC_VERSION
-tdbc_LIBRARY_PATH
-tdbc_STUB_LIB_PATH
-tdbc_STUB_LIB_SPEC
-tdbc_STUB_LIB_FILE
-tdbc_LIB_SPEC
-tdbc_LIB_FILE
-tdbc_SRC_DIR
-tdbc_BIN_DIR
-tdbc_VERSION
-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_tdbc
-with_tclinclude
-enable_threads
-enable_shared
-enable_stubs
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS'
-
-
-# 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 tdbcsqlite3 1.0.6 to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/tdbcsqlite3]
- --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 tdbcsqlite3 1.0.6:";;
- 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 (default: on)
- --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)
-
-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-tdbc directory containing tdbc configuration (tdbcConfig.sh)
- --with-tclinclude directory containing the public Tcl header files
-
-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>
-
-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
-tdbcsqlite3 configure 1.0.6
-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_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
-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 tdbcsqlite3 $as_me 1.0.6, 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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; }
- 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/contrib/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/pkg/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:
-
-
-
-
-
-
-
-
-#----------------------------------------------------------------------
-# Load the tdbcConfig.sh file
-#----------------------------------------------------------------------
-
-
- #
- # Ok, lets find the tdbc configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tdbc
- #
-
- if test x"${no_tdbc}" = x ; then
- # we reset no_tdbc in case something fails here
- no_tdbc=true
-
-# Check whether --with-tdbc was given.
-if test "${with_tdbc+set}" = set; then :
- withval=$with_tdbc; with_tdbcconfig=${withval}
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdbc configuration" >&5
-$as_echo_n "checking for tdbc configuration... " >&6; }
- if ${ac_cv_c_tdbcconfig+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-
- # First check to see if --with-tdbc was specified.
- if test x"${with_tdbcconfig}" != x ; then
- case ${with_tdbcconfig} in
- */tdbcConfig.sh )
- if test -f ${with_tdbcconfig}; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tdbc argument should refer to directory containing tdbcConfig.sh, not to tdbcConfig.sh itself" >&5
-$as_echo "$as_me: WARNING: --with-tdbc argument should refer to directory containing tdbcConfig.sh, not to tdbcConfig.sh itself" >&2;}
- with_tdbcconfig=`echo ${with_tdbcconfig} | sed 's!/tdbcConfig\.sh$!!'`
- fi;;
- esac
- if test -f "${with_tdbcconfig}/tdbcConfig.sh" ; then
- ac_cv_c_tdbcconfig=`(cd ${with_tdbcconfig}; pwd)`
- else
- as_fn_error $? "${with_tdbcconfig} directory doesn't contain tdbcConfig.sh" "$LINENO" 5
- fi
- fi
-
- # then check for a private tdbc installation
- if test x"${ac_cv_c_tdbcconfig}" = x ; then
- for i in \
- ../tdbc \
- `ls -dr ../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
- `ls -dr ../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
- `ls -dr ../tdbc*[0-9].[0-9] 2>/dev/null` \
- `ls -dr ../tdbc*[0-9].[0-9]* 2>/dev/null` \
- ../../tdbc \
- `ls -dr ../../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
- `ls -dr ../../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
- `ls -dr ../../tdbc*[0-9].[0-9] 2>/dev/null` \
- `ls -dr ../../tdbc*[0-9].[0-9]* 2>/dev/null` \
- ../../../tdbc \
- `ls -dr ../../../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
- `ls -dr ../../../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
- `ls -dr ../../../tdbc*[0-9].[0-9] 2>/dev/null` \
- `ls -dr ../../../tdbc*[0-9].[0-9]* 2>/dev/null` \
- ${srcdir}/../tdbc \
- `ls -dr ${srcdir}/../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
- `ls -dr ${srcdir}/../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
- `ls -dr ${srcdir}/../tdbc*[0-9].[0-9] 2>/dev/null` \
- `ls -dr ${srcdir}/../tdbc*[0-9].[0-9]* 2>/dev/null` \
- ; do
- if test -f "$i/tdbcConfig.sh" ; then
- ac_cv_c_tdbcconfig=`(cd $i; pwd)`
- break
- fi
- if test -f "$i/unix/tdbcConfig.sh" ; then
- ac_cv_c_tdbcconfig=`(cd $i/unix; pwd)`
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tdbcconfig}" = 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` \
- ; do
- if test -f "$i/tdbcConfig.sh" ; then
- ac_cv_c_tdbcconfig=`(cd $i; pwd)`
- break
- fi
- done
- fi
-
-fi
-
-
- if test x"${ac_cv_c_tdbcconfig}" = x ; then
- tdbc_BIN_DIR="# no tdbc configs found"
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find tdbc configuration definitions" >&5
-$as_echo "$as_me: WARNING: Cannot find tdbc configuration definitions" >&2;}
- exit 0
- else
- no_tdbc=
- tdbc_BIN_DIR=${ac_cv_c_tdbcconfig}
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $tdbc_BIN_DIR/tdbcConfig.sh" >&5
-$as_echo "found $tdbc_BIN_DIR/tdbcConfig.sh" >&6; }
- fi
- fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${tdbc_BIN_DIR}/tdbcConfig.sh" >&5
-$as_echo_n "checking for existence of ${tdbc_BIN_DIR}/tdbcConfig.sh... " >&6; }
-
- if test -f "${tdbc_BIN_DIR}/tdbcConfig.sh" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
-$as_echo "loading" >&6; }
- . "${tdbc_BIN_DIR}/tdbcConfig.sh"
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
-$as_echo "file not found" >&6; }
- fi
-
- #
- # If the tdbc_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 tdbc_LIB_SPEC will be set to the value
- # of tdbc_BUILD_LIB_SPEC. An extension should make use of tdbc_LIB_SPEC
- # instead of tdbc_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- #
-
- if test -f "${tdbc_BIN_DIR}/Makefile" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found Makefile - using build library specs for tdbc" >&5
-$as_echo "$as_me: WARNING: Found Makefile - using build library specs for tdbc" >&2;}
- tdbc_LIB_SPEC=${tdbc_BUILD_LIB_SPEC}
- tdbc_STUB_LIB_SPEC=${tdbc_BUILD_STUB_LIB_SPEC}
- tdbc_STUB_LIB_PATH=${tdbc_BUILD_STUB_LIB_PATH}
- tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
- tdbc_LIBRARY_PATH=${tdbc_LIBRARY_PATH}
- fi
-
-
-
-
-
-
-
-
-
-
-
-
- # Allow the caller to prevent this auto-check by specifying any 2nd arg
- if test "x" = x; then :
-
- # Check both upper and lower-case variants
- # If a dev wanted non-stubs libs, this function could take an option
- # to not use _STUB in the paths below
- if test "x${tdbc_STUB_LIB_SPEC}" = x; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking For TDBC_STUB library for LIBS" >&5
-$as_echo_n "checking For TDBC_STUB library for LIBS... " >&6; }
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${TDBC_STUB_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
-
- vars="\"`${CYGPATH} ${TDBC_STUB_LIB_PATH}`\""
- 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
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using TDBC_STUB_LIB_PATH ${TDBC_STUB_LIB_PATH}" >&5
-$as_echo "using TDBC_STUB_LIB_PATH ${TDBC_STUB_LIB_PATH}" >&6; }
- else
-
- vars="${TDBC_STUB_LIB_SPEC}"
- 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
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using TDBC_STUB_LIB_SPEC ${TDBC_STUB_LIB_SPEC}" >&5
-$as_echo "using TDBC_STUB_LIB_SPEC ${TDBC_STUB_LIB_SPEC}" >&6; }
- fi
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
-$as_echo "file not found" >&6; }
- fi
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking For tdbc_STUB library for LIBS" >&5
-$as_echo_n "checking For tdbc_STUB library for LIBS... " >&6; }
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${tdbc_STUB_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
-
- vars="\"`${CYGPATH} ${tdbc_STUB_LIB_PATH}`\""
- 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
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using tdbc_STUB_LIB_PATH ${tdbc_STUB_LIB_PATH}" >&5
-$as_echo "using tdbc_STUB_LIB_PATH ${tdbc_STUB_LIB_PATH}" >&6; }
- else
-
- vars="${tdbc_STUB_LIB_SPEC}"
- 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
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using tdbc_STUB_LIB_SPEC ${tdbc_STUB_LIB_SPEC}" >&5
-$as_echo "using tdbc_STUB_LIB_SPEC ${tdbc_STUB_LIB_SPEC}" >&6; }
- fi
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
-$as_echo "file not found" >&6; }
- fi
-
-fi
-
-fi
-
-# The next bit probably ought to be in TEA_LOAD_CONFIG
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Looking for \"${tdbc_BIN_DIR}/Makefile\"" >&5
-$as_echo "$as_me: WARNING: Looking for \"${tdbc_BIN_DIR}/Makefile\"" >&2;}
-if test -f "${tdbc_BIN_DIR}/Makefile" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found Makefile - using build include spec and lib specs for tdbc" >&5
-$as_echo "$as_me: WARNING: Found Makefile - using build include spec and lib specs for tdbc" >&2;}
- tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
- tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH}
-fi
-
-
-
-
-
-#-----------------------------------------------------------------------
-# 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
-
-
-#-----------------------------------------------------------------------
-# These bits have no value to the tdbcsqlite3 configuration itself, but
-# we include them to avoid warnings about unrecognized options that
-# otherwise show up when conventional configurations happen, like that
-# in the Tcl+pkgs harness: --enable-threads, --disable-shared, etc.
-#-----------------------------------------------------------------------
-
-
- { $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}\"
-
-
-
-
- # 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
-
-
-
- { $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
-
-
-
-
-
-#-----------------------------------------------------------------------
-#-----------------------------------------------------------------------
-
-
-
-
-
-#-----------------------------------------------------------------------
-# 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="library/tdbcsqlite3.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
-
-
-
-#--------------------------------------------------------------------
-# 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.
-#--------------------------------------------------------------------
-
-# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
-# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
-#CLEANFILES="pkgIndex.tcl"
-if test "${TEA_PLATFORM}" = "windows" ; then
-
-$as_echo "#define BUILD_sample 1" >>confdefs.h
-
- CLEANFILES="$CLEANFILES *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
-else
- # Ensure no empty else clauses
- :
-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; }
-
-
-
-#--------------------------------------------------------------------
-# 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
-
-
-
-: "${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 tdbcsqlite3 $as_me 1.0.6, 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="\\
-tdbcsqlite3 config.status 1.0.6
-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 = ""
-
-}
-{
- 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
-
-
-# This is a comment added to force the 'execute' permission to update
-# in the Fossil repository.
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure.ac b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure.ac
deleted file mode 100755
index 20514f5..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/configure.ac
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/bin/bash -norc
-dnl This file is an input file used by the GNU "autoconf" program to
-dnl generate the file "configure", which is run during Tcl installation
-dnl to configure the system for the local environment.
-#
-# RCS: @(#) $Id: configure.in,v 1.48 2008/11/05 00:13:00 hobbs Exp $
-
-AC_INIT([tdbcsqlite3], [1.0.6])
-
-#--------------------------------------------------------------------
-# Call TEA_INIT as the first TEA_ macro to set up initial vars.
-# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
-# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
-#--------------------------------------------------------------------
-
-TEA_INIT([3.10])
-AC_CONFIG_AUX_DIR(tclconfig)
-
-#--------------------------------------------------------------------
-# Load the tclConfig.sh file
-#--------------------------------------------------------------------
-
-TEA_PATH_TCLCONFIG
-TEA_LOAD_TCLCONFIG
-
-#----------------------------------------------------------------------
-# Load the tdbcConfig.sh file
-#----------------------------------------------------------------------
-
-TEA_PATH_CONFIG(tdbc)
-TEA_LOAD_CONFIG(tdbc)
-# The next bit probably ought to be in TEA_LOAD_CONFIG
-AC_MSG_WARN([Looking for "${tdbc_BIN_DIR}/Makefile"])
-if test -f "${tdbc_BIN_DIR}/Makefile" ; then
- AC_MSG_WARN([Found Makefile - using build include spec and lib specs for tdbc])
- tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
- tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH}
-fi
-AC_SUBST(tdbc_LIBRARY_PATH)
-AC_SUBST(TDBC_VERSION)
-AC_SUBST(tdbc_BIN_DIR)
-AC_SUBST(TDBC_LIB_FILE)
-
-#-----------------------------------------------------------------------
-# Handle the --prefix=... option by defaulting to what Tcl gave.
-# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
-#-----------------------------------------------------------------------
-
-TEA_PREFIX
-
-#-----------------------------------------------------------------------
-# These bits have no value to the tdbcsqlite3 configuration itself, but
-# we include them to avoid warnings about unrecognized options that
-# otherwise show up when conventional configurations happen, like that
-# in the Tcl+pkgs harness: --enable-threads, --disable-shared, etc.
-#-----------------------------------------------------------------------
-
-TEA_PUBLIC_TCL_HEADERS
-TEA_ENABLE_THREADS
-TEA_ENABLE_SHARED
-
-#-----------------------------------------------------------------------
-#-----------------------------------------------------------------------
-
-AC_SUBST(TCL_VERSION)
-AC_SUBST(TCL_MAJOR_VERSION)
-AC_SUBST(TCL_MINOR_VERSION)
-
-#-----------------------------------------------------------------------
-# Specify the C source files to compile in TEA_ADD_SOURCES,
-# public headers that need to be installed in TEA_ADD_HEADERS,
-# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
-# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
-# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
-# and PKG_TCL_SOURCES.
-#-----------------------------------------------------------------------
-
-TEA_ADD_TCL_SOURCES([library/tdbcsqlite3.tcl])
-
-#--------------------------------------------------------------------
-# 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.
-#--------------------------------------------------------------------
-
-# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
-# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
-#CLEANFILES="pkgIndex.tcl"
-if test "${TEA_PLATFORM}" = "windows" ; then
- AC_DEFINE(BUILD_sample, 1, [Build windows export dll])
- CLEANFILES="$CLEANFILES *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
-else
- # Ensure no empty else clauses
- :
-fi
-AC_SUBST(CLEANFILES)
-
-#--------------------------------------------------------------------
-# Determine the name of the tclsh and/or wish executables in the
-# Tcl and Tk build directories or the location they were installed
-# into. These paths are used to support running test cases only,
-# the Makefile should not be making use of these paths to generate
-# a pkgIndex.tcl file or anything else at extension build time.
-#--------------------------------------------------------------------
-
-TEA_PROG_TCLSH
-
-#--------------------------------------------------------------------
-# Finally, substitute all of the various values into the Makefile.
-# You may alternatively have a special pkgIndex.tcl.in or other files
-# which require substituting th AC variables in. Include these here.
-#--------------------------------------------------------------------
-
-AC_OUTPUT([Makefile pkgIndex.tcl])
-
-# This is a comment added to force the 'execute' permission to update
-# in the Fossil repository.
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/tcl.m4
deleted file mode 100644
index e8234a2..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tclconfig/tcl.m4
+++ /dev/null
@@ -1,4335 +0,0 @@
-# tcl.m4 --
-#
-# This file provides a set of autoconf macros to help TEA-enable
-# a Tcl extension.
-#
-# Copyright (c) 1999-2000 Ajuba Solutions.
-# Copyright (c) 2002-2005 ActiveState Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-
-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.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
-#
-
-#------------------------------------------------------------------------
-# TEA_PATH_TCLCONFIG --
-#
-# Locate the tclConfig.sh file and perform a sanity check on
-# the Tcl compile flags
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tcl=...
-#
-# Defines the following vars:
-# TCL_BIN_DIR Full path to the directory containing
-# the tclConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TCLCONFIG], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
- #
- # Ok, lets find the tcl configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tcl
- #
-
- if test x"${no_tcl}" = x ; then
- # we reset no_tcl in case something fails here
- no_tcl=true
- AC_ARG_WITH(tcl,
- AC_HELP_STRING([--with-tcl],
- [directory containing tcl configuration (tclConfig.sh)]),
- with_tclconfig="${withval}")
- AC_MSG_CHECKING([for Tcl configuration])
- AC_CACHE_VAL(ac_cv_c_tclconfig,[
-
- # First check to see if --with-tcl was specified.
- if test x"${with_tclconfig}" != x ; then
- case "${with_tclconfig}" in
- */tclConfig.sh )
- if test -f "${with_tclconfig}"; then
- AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
- with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tclconfig}/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
- fi
- fi
-
- # then check for a private Tcl installation
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in \
- ../tcl \
- `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tcl \
- `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tcl \
- `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tcl.framework/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/pkg/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
- ])
-
- if test x"${ac_cv_c_tclconfig}" = x ; then
- TCL_BIN_DIR="# no Tcl configs found"
- AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
- else
- no_tcl=
- TCL_BIN_DIR="${ac_cv_c_tclconfig}"
- AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_TKCONFIG --
-#
-# Locate the tkConfig.sh file
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tk=...
-#
-# Defines the following vars:
-# TK_BIN_DIR Full path to the directory containing
-# the tkConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TKCONFIG], [
- #
- # Ok, lets find the tk configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tk
- #
-
- if test x"${no_tk}" = x ; then
- # we reset no_tk in case something fails here
- no_tk=true
- AC_ARG_WITH(tk,
- AC_HELP_STRING([--with-tk],
- [directory containing tk configuration (tkConfig.sh)]),
- with_tkconfig="${withval}")
- AC_MSG_CHECKING([for Tk configuration])
- AC_CACHE_VAL(ac_cv_c_tkconfig,[
-
- # First check to see if --with-tkconfig was specified.
- if test x"${with_tkconfig}" != x ; then
- case "${with_tkconfig}" in
- */tkConfig.sh )
- if test -f "${with_tkconfig}"; then
- AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
- with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tkconfig}/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
- fi
- fi
-
- # then check for a private Tk library
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ../tk \
- `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tk \
- `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tk \
- `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tk.framework/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few other private locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_tkconfig}" = x ; then
- TK_BIN_DIR="# no Tk configs found"
- AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
- else
- no_tk=
- TK_BIN_DIR="${ac_cv_c_tkconfig}"
- AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TCLCONFIG --
-#
-# Load the tclConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TCL_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_BIN_DIR
-# TCL_SRC_DIR
-# TCL_LIB_FILE
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TCLCONFIG], [
- AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
-
- if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TCL_BIN_DIR}/tclConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
- eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
-
- # If the TCL_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TCL_LIB_SPEC will be set to the value
- # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
- # instead of TCL_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
- TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
- TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tcl.framework installed in an arbitrary location.
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
- for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
- "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
- TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
- TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
- TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
- eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
- eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
- eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
-
- AC_SUBST(TCL_VERSION)
- AC_SUBST(TCL_PATCH_LEVEL)
- AC_SUBST(TCL_BIN_DIR)
- AC_SUBST(TCL_SRC_DIR)
-
- AC_SUBST(TCL_LIB_FILE)
- AC_SUBST(TCL_LIB_FLAG)
- AC_SUBST(TCL_LIB_SPEC)
-
- AC_SUBST(TCL_STUB_LIB_FILE)
- AC_SUBST(TCL_STUB_LIB_FLAG)
- AC_SUBST(TCL_STUB_LIB_SPEC)
-
- AC_MSG_CHECKING([platform])
- hold_cc=$CC; CC="$TCL_CC"
- AC_TRY_COMPILE(,[
- #ifdef _WIN32
- #error win32
- #endif
- ], [
- TEA_PLATFORM="unix"
- CYGPATH=echo
- ], [
- TEA_PLATFORM="windows"
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
- )
- CC=$hold_cc
- AC_MSG_RESULT($TEA_PLATFORM)
-
- # The BUILD_$pkg is to define the correct extern storage class
- # handling when making this package
- AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
- [Building extension source?])
- # 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:
- AC_SUBST(CLEANFILES)
- AC_SUBST(TCL_LIBS)
- AC_SUBST(TCL_DEFS)
- AC_SUBST(TCL_EXTRA_CFLAGS)
- AC_SUBST(TCL_LD_FLAGS)
- AC_SUBST(TCL_SHLIB_LD_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TKCONFIG --
-#
-# Load the tkConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TK_BIN_DIR
-#
-# Results:
-#
-# Sets the following vars that should be in tkConfig.sh:
-# TK_BIN_DIR
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TKCONFIG], [
- AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
-
- if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TK_BIN_DIR}/tkConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
- eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
-
- # If the TK_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TK_LIB_SPEC will be set to the value
- # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
- # instead of TK_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
- TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
- TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tk.framework installed in an arbitrary location.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
- for i in "`cd "${TK_BIN_DIR}"; pwd`" \
- "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
- TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
- TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
- TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
- eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
- eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
- eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
-
- # TEA specific: Ensure windowingsystem is defined
- if test "${TEA_PLATFORM}" = "unix" ; then
- case ${TK_DEFS} in
- *MAC_OSX_TK*)
- AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
- TEA_WINDOWINGSYSTEM="aqua"
- ;;
- *)
- TEA_WINDOWINGSYSTEM="x11"
- ;;
- esac
- elif test "${TEA_PLATFORM}" = "windows" ; then
- TEA_WINDOWINGSYSTEM="win32"
- fi
-
- AC_SUBST(TK_VERSION)
- AC_SUBST(TK_BIN_DIR)
- AC_SUBST(TK_SRC_DIR)
-
- AC_SUBST(TK_LIB_FILE)
- AC_SUBST(TK_LIB_FLAG)
- AC_SUBST(TK_LIB_SPEC)
-
- AC_SUBST(TK_STUB_LIB_FILE)
- AC_SUBST(TK_STUB_LIB_FLAG)
- AC_SUBST(TK_STUB_LIB_SPEC)
-
- # TEA specific:
- AC_SUBST(TK_LIBS)
- AC_SUBST(TK_XINCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_TCLSH
-# Determine the fully qualified path name of the tclsh executable
-# in the Tcl build directory or the tclsh installed in a bin
-# directory. This macro will correctly determine the name
-# of the tclsh executable even if tclsh has not yet been
-# built in the build directory. The tclsh found is always
-# associated with a tclConfig.sh file. This tclsh should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCLSH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_TCLSH], [
- AC_MSG_CHECKING([for tclsh])
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- # tclConfig.sh is in Tcl build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- AC_MSG_RESULT([${TCLSH_PROG}])
- AC_SUBST(TCLSH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_WISH
-# Determine the fully qualified path name of the wish executable
-# in the Tk build directory or the wish installed in a bin
-# directory. This macro will correctly determine the name
-# of the wish executable even if wish has not yet been
-# built in the build directory. The wish found is always
-# associated with a tkConfig.sh file. This wish should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# WISH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_WISH], [
- AC_MSG_CHECKING([for wish])
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- # tkConfig.sh is in Tk build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- else
- # tkConfig.sh is in install location
- if test "${TEA_PLATFORM}" = "windows"; then
- WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
- else
- WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
- fi
- list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
- `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
- for i in $list ; do
- if test -f "$i/${WISH_PROG}" ; then
- REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
- break
- fi
- done
- WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
- fi
- AC_MSG_RESULT([${WISH_PROG}])
- AC_SUBST(WISH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SHARED --
-#
-# Allows the building of shared libraries
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-shared=yes|no
-# --enable-stubs=yes|no
-#
-# Defines the following vars:
-# STATIC_BUILD Used for building import/export libraries
-# on Windows.
-#
-# Sets the following vars:
-# SHARED_BUILD Value of 1 or 0
-# 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)]),
- [shared_ok=$enableval], [shared_ok=yes])
-
- if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
- shared_ok=$enableval
- else
- 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
-
- # 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, [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)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_THREADS --
-#
-# Specify if thread support should be enabled. If "yes" is specified
-# as an arg (optional), threads are enabled by default, "no" means
-# threads are disabled. "yes" is the default.
-#
-# TCL_THREADS is checked so that if you are compiling an extension
-# against a threaded core, your extension must be compiled threaded
-# as well.
-#
-# Note that it is legal to have a thread enabled extension run in a
-# threaded or non-threaded Tcl core, but a non-threaded extension may
-# only run in a non-threaded Tcl core.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-threads
-#
-# Sets the following vars:
-# THREADS_LIBS Thread library(s)
-#
-# Defines the following vars:
-# TCL_THREADS
-# _REENTRANT
-# _THREAD_SAFE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_THREADS], [
- AC_ARG_ENABLE(threads,
- AC_HELP_STRING([--enable-threads],
- [build with threads (default: on)]),
- [tcl_ok=$enableval], [tcl_ok=yes])
-
- if test "${enable_threads+set}" = set; then
- enableval="$enable_threads"
- tcl_ok=$enableval
- else
- tcl_ok=yes
- fi
-
- if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
- TCL_THREADS=1
-
- if test "${TEA_PLATFORM}" != "windows" ; then
- # We are always OK on Windows, so check what this platform wants:
-
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- AC_DEFINE(USE_THREAD_ALLOC, 1,
- [Do we want to use the threaded memory allocator?])
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- if test "`uname -s`" = "SunOS" ; then
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
- fi
- AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
- AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- # Check a little harder for __pthread_mutex_init in the same
- # library, as some systems hide it there until pthread.h is
- # defined. We could alternatively do an AC_TRY_COMPILE with
- # pthread.h, but that will work with libpthread really doesn't
- # exist, like AIX 4.2. [Bug: 4359]
- AC_CHECK_LIB(pthread, __pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- fi
-
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthread"
- else
- AC_CHECK_LIB(pthreads, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthreads"
- else
- AC_CHECK_LIB(c, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- AC_CHECK_LIB(c_r, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -pthread"
- else
- TCL_THREADS=0
- AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
- fi
- fi
- fi
- fi
- fi
- else
- TCL_THREADS=0
- fi
- # Do checking message here to not mess up interleaved configure output
- AC_MSG_CHECKING([for building with threads])
- if test "${TCL_THREADS}" = 1; then
- AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
- AC_MSG_RESULT([yes (default)])
- else
- AC_MSG_RESULT([no])
- fi
- # TCL_THREADS sanity checking. See if our request for building with
- # threads is the same as the way Tcl was built. If not, warn the user.
- case ${TCL_DEFS} in
- *THREADS=1*)
- if test "${TCL_THREADS}" = "0"; then
- AC_MSG_WARN([
- Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
- that IS thread-enabled. It is recommended to use --enable-threads.])
- fi
- ;;
- *)
- if test "${TCL_THREADS}" = "1"; then
- AC_MSG_WARN([
- --enable-threads requested, but building against a Tcl that is NOT
- thread-enabled. This is an OK configuration that will also run in
- a thread-enabled core.])
- fi
- ;;
- esac
- AC_SUBST(TCL_THREADS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SYMBOLS --
-#
-# Specify if debugging symbols should be used.
-# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
-#
-# Arguments:
-# none
-#
-# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
-# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
-# Requires the following vars to be set in the Makefile:
-# CFLAGS_DEFAULT
-# LDFLAGS_DEFAULT
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-symbols
-#
-# Defines the following vars:
-# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
-# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
-# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
-# Sets to $(LDFLAGS_OPTIMIZE) if false
-# DBGX Formerly used as debug library extension;
-# always blank now.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_SYMBOLS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_CONFIG_CFLAGS])
- AC_MSG_CHECKING([for build with symbols])
- AC_ARG_ENABLE(symbols,
- AC_HELP_STRING([--enable-symbols],
- [build with debugging symbols (default: off)]),
- [tcl_ok=$enableval], [tcl_ok=no])
- DBGX=""
- if test "$tcl_ok" = "no"; then
- CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
- LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
- AC_MSG_RESULT([no])
- else
- CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
- LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
- if test "$tcl_ok" = "yes"; then
- AC_MSG_RESULT([yes (standard debugging)])
- fi
- fi
- # TEA specific:
- if test "${TEA_PLATFORM}" != "windows" ; then
- LDFLAGS_DEFAULT="${LDFLAGS}"
- fi
- AC_SUBST(CFLAGS_DEFAULT)
- AC_SUBST(LDFLAGS_DEFAULT)
- AC_SUBST(TCL_DBGX)
-
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
- fi
-
- if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
- if test "$tcl_ok" = "all"; then
- AC_MSG_RESULT([enabled symbols mem debugging])
- else
- AC_MSG_RESULT([enabled $tcl_ok debugging])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_LANGINFO --
-#
-# Allows use of modern nl_langinfo check for better l10n.
-# This is only relevant for Unix.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-langinfo=yes|no (default is yes)
-#
-# Defines the following vars:
-# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_LANGINFO], [
- AC_ARG_ENABLE(langinfo,
- AC_HELP_STRING([--enable-langinfo],
- [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
- [langinfo_ok=$enableval], [langinfo_ok=yes])
-
- HAVE_LANGINFO=0
- if test "$langinfo_ok" = "yes"; then
- AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
- fi
- AC_MSG_CHECKING([whether to use nl_langinfo])
- if test "$langinfo_ok" = "yes"; then
- AC_CACHE_VAL(tcl_cv_langinfo_h, [
- AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
- [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
- AC_MSG_RESULT([$tcl_cv_langinfo_h])
- if test $tcl_cv_langinfo_h = yes; then
- AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
- fi
- else
- AC_MSG_RESULT([$langinfo_ok])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_SYSTEM
-#
-# Determine what the system is (some things cannot be easily checked
-# on a feature-driven basis, alas). This can usually be done via the
-# "uname" command.
-#
-# Arguments:
-# none
-#
-# Results:
-# Defines the following var:
-#
-# system - System/platform/version identification code.
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_SYSTEM], [
- AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
- # TEA specific:
- if test "${TEA_PLATFORM}" = "windows" ; then
- tcl_cv_sys_version=windows
- else
- tcl_cv_sys_version=`uname -s`-`uname -r`
- if test "$?" -ne 0 ; then
- AC_MSG_WARN([can't find uname command])
- tcl_cv_sys_version=unknown
- else
- if test "`uname -s`" = "AIX" ; then
- tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
- fi
- fi
- fi
- ])
- system=$tcl_cv_sys_version
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_CFLAGS
-#
-# Try to determine the proper flags to pass to the compiler
-# for building shared libraries and other such nonsense.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substitutes the following vars:
-#
-# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
-# LDFLAGS - Flags to pass to the compiler when linking object
-# files into an executable application binary such
-# as tclsh.
-# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile. Could
-# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
-# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile.
-# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
-# of a shared library (may request position-independent
-# code, among other things).
-# SHLIB_LD - Base command to use for combining object files
-# into a shared library.
-# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
-# creating shared libraries. This symbol typically
-# goes at the end of the "ld" commands that build
-# shared libraries. The value of the symbol defaults to
-# "${LIBS}" if all of the dependent libraries should
-# be specified when creating a shared library. If
-# dependent libraries should not be specified (as on
-# SunOS 4.x, where they cause the link to fail, or in
-# general if Tcl and Tk aren't themselves shared
-# libraries), then this symbol has an empty string
-# as its value.
-# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
-# extensions. An empty string means we don't know how
-# to use shared libraries on this platform.
-# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
-# in a static or shared library name, using the $PACKAGE_VERSION variable
-# to put the version in the right place. This is used
-# by platforms that need non-standard library names.
-# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
-# to have a version after the .so, and ${PACKAGE_VERSION}.a
-# on AIX, since a shared library needs to have
-# a .a extension whereas shared objects for loadable
-# extensions have a .so extension. Defaults to
-# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
-# CFLAGS_DEBUG -
-# Flags used when running the compiler in debug mode
-# CFLAGS_OPTIMIZE -
-# Flags used when running the compiler in optimize mode
-# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_CFLAGS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
-
- # Step 0.a: Enable 64 bit support?
-
- AC_MSG_CHECKING([if 64bit support is requested])
- AC_ARG_ENABLE(64bit,
- AC_HELP_STRING([--enable-64bit],
- [enable 64bit support (default: off)]),
- [do64bit=$enableval], [do64bit=no])
- AC_MSG_RESULT([$do64bit])
-
- # Step 0.b: Enable Solaris 64 bit VIS support?
-
- AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
- AC_ARG_ENABLE(64bit-vis,
- AC_HELP_STRING([--enable-64bit-vis],
- [enable 64bit Sparc VIS support (default: off)]),
- [do64bitVIS=$enableval], [do64bitVIS=no])
- AC_MSG_RESULT([$do64bitVIS])
- # Force 64bit on with VIS
- AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
-
- # Step 0.c: Check if visibility support is available. Do this here so
- # that platform specific alternatives can be used below if this fails.
-
- AC_CACHE_CHECK([if compiler supports visibility "hidden"],
- tcl_cv_cc_visibility_hidden, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- AC_TRY_LINK([
- extern __attribute__((__visibility__("hidden"))) void f(void);
- void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
- tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- AC_DEFINE(MODULE_SCOPE,
- [extern __attribute__((__visibility__("hidden")))],
- [Compiler support for module scope symbols])
- AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
- ])
-
- # Step 0.d: Disable -rpath support?
-
- AC_MSG_CHECKING([if rpath support is requested])
- AC_ARG_ENABLE(rpath,
- AC_HELP_STRING([--disable-rpath],
- [disable rpath support (default: on)]),
- [doRpath=$enableval], [doRpath=yes])
- AC_MSG_RESULT([$doRpath])
-
- # TEA specific: Cross-compiling options for Windows/CE builds?
-
- AS_IF([test "${TEA_PLATFORM}" = windows], [
- AC_MSG_CHECKING([if Windows/CE build is requested])
- AC_ARG_ENABLE(wince,
- AC_HELP_STRING([--enable-wince],
- [enable Win/CE support (where applicable)]),
- [doWince=$enableval], [doWince=no])
- AC_MSG_RESULT([$doWince])
- ])
-
- # Set the variable "system" to hold the name and version number
- # for the system.
-
- TEA_CONFIG_SYSTEM
-
- # Require ranlib early so we can override it in special cases below.
-
- AC_REQUIRE([AC_PROG_RANLIB])
-
- # 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
- AS_IF([test "$GCC" = yes], [
- CFLAGS_OPTIMIZE=-O2
- CFLAGS_WARNING="-Wall"
- ], [
- CFLAGS_OPTIMIZE=-O
- CFLAGS_WARNING=""
- ])
- AC_CHECK_TOOL(AR, ar)
- STLIB_LD='${AR} cr'
- LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
- AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
- 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
- AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
- AC_MSG_WARN([Ensure latest Platform SDK is installed])
- do64bit="no"
- else
- AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
- do64bit_ok="yes"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- if test "$do64bit" != "no" ; then
- AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
- fi
- if test "$GCC" = "yes" ; then
- AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
- fi
- TEA_PATH_CELIB
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F, '{ \
- if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
- if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
- if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
- if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
- if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
- -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
- doWince="no"
- else
- # We could PATH_NOSPACE these, but that's not important,
- # as long as we quote them when used.
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$GCC" != "yes" ; then
- if test "${SHARED_BUILD}" = "0" ; then
- runtime=-MT
- else
- runtime=-MD
- fi
- case "x`echo \${VisualStudioVersion}`" in
- x1[[4-9]]*)
- lflags="${lflags} -nodefaultlib:libucrt.lib"
- TEA_ADD_LIBS([ucrt.lib])
- ;;
- *)
- ;;
- 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
- TEA_ADD_LIBS([bufferoverflowU.lib])
- elif test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="\"${CEBINROOT}/cl.exe\""
- else
- CC="\"${CEBINROOT}/cl${ARCH}.exe\""
- fi
- CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
- defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
- if test "${SHARED_BUILD}" = "1" ; then
- # Static CE builds require static celib as well
- defs="${defs} _DLL"
- fi
- for i in $defs ; do
- AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
- done
- AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
- AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
- CFLAGS_DEBUG="-nologo -Zi -Od"
- CFLAGS_OPTIMIZE="-nologo -Ox"
- lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
- lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
- LINKBIN="\"${CEBINROOT}/link.exe\""
- AC_SUBST(CELIB_DIR)
- 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
- AC_CHECK_TOOL(RC, windres)
- CFLAGS_DEBUG="-g"
- CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- SHLIB_LD='${CC} -shared'
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
- LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
-
- AC_CACHE_CHECK(for cross-compile version of gcc,
- ac_cv_cross,
- AC_TRY_COMPILE([
- #ifdef _WIN32
- #error cross-compiler
- #endif
- ], [],
- ac_cv_cross=yes,
- ac_cv_cross=no)
- )
- 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-*)
- AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
- # AIX requires the _r compiler when gcc isn't being used
- case "${CC}" in
- *_r|*_r\ *)
- # ok ...
- ;;
- *)
- # Make sure only first arg gets _r
- CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
- ;;
- esac
- AC_MSG_RESULT([Using $CC for compiling with threads])
- ])
- LIBS="$LIBS -lc"
- SHLIB_CFLAGS=""
- SHLIB_SUFFIX=".so"
-
- LD_LIBRARY_PATH_VAR="LIBPATH"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -q64"
- LDFLAGS_ARCH="-q64"
- RANLIB="${RANLIB} -X64"
- AR="${AR} -X64"
- SHLIB_LD_FLAGS="-b64"
- ])
- ])
-
- AS_IF([test "`uname -m`" = ia64], [
- # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- AS_IF([test "$GCC" = yes], [
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- ], [
- CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
- ])
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ], [
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared -Wl,-bexpall'
- ], [
- SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
- LDFLAGS="$LDFLAGS -brtl"
- ])
- SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
- CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- 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.
- #-----------------------------------------------------------
- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
- ;;
- 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} ${CFLAGS} ${LDFLAGS} -shared'
- AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
- ;;
- HP-UX-*.11.*)
- # Use updated header definitions where possible
- AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
- # TEA specific: Needed by Tcl, but not most extensions
- #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
- #LIBS="$LIBS -lxnet" # Use the XOPEN network library
-
- AS_IF([test "`uname -m`" = ia64], [
- SHLIB_SUFFIX=".so"
- # Use newer C++ library for C++ extensions
- #if test "$GCC" != "yes" ; then
- # CPPFLAGS="-AA"
- #fi
- ], [
- SHLIB_SUFFIX=".sl"
- ])
- AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
- AS_IF([test "$tcl_ok" = yes], [
- LDFLAGS="$LDFLAGS -Wl,-E"
- CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
- LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
- LD_LIBRARY_PATH_VAR="SHLIB_PATH"
- ])
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- CFLAGS="$CFLAGS -z"
- # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
- #CFLAGS="$CFLAGS +DAportable"
- SHLIB_CFLAGS="+z"
- SHLIB_LD="ld -b"
- ])
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = "yes"], [
- AS_IF([test "$GCC" = yes], [
- case `${CC} -dumpmachine` in
- hppa64*)
- # 64-bit gcc in use. Fix flags for GNU ld.
- do64bit_ok=yes
- SHLIB_LD='${CC} -shared'
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ;;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ;;
- esac
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS +DD64"
- LDFLAGS_ARCH="+DD64"
- ])
- ]) ;;
- IRIX-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [
- CFLAGS="$CFLAGS -mabi=n32"
- LDFLAGS="$LDFLAGS -mabi=n32"
- ], [
- case $system in
- IRIX-6.3)
- # Use to build 6.2 compatible binaries on 6.3.
- CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
- ;;
- *)
- CFLAGS="$CFLAGS -n32"
- ;;
- esac
- LDFLAGS="$LDFLAGS -n32"
- ])
- ;;
- IRIX64-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
-
- # Check to enable 64-bit flags for compiler/linker
-
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported by gcc])
- ], [
- do64bit_ok=yes
- SHLIB_LD="ld -64 -shared -rdata_shared"
- CFLAGS="$CFLAGS -64"
- LDFLAGS_ARCH="-64"
- ])
- ])
- ;;
- Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
- AS_IF([test $do64bit = yes], [
- AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -m64"
- AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_m64 = yes], [
- CFLAGS="$CFLAGS -m64"
- do64bit_ok=yes
- ])
- ])
-
- # The combo of gcc + glibc has a bug related to inlining of
- # functions like strtod(). The -fno-builtin flag should address
- # this problem but it does not work. The -fno-inline flag is kind
- # of overkill but it works. Disable inlining only when one of the
- # files in compat/*.c is being linked in.
-
- AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
- ;;
- Lynx*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
- CFLAGS_OPTIMIZE=-02
- SHLIB_LD='${CC} -shared'
- LD_FLAGS="-Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- ;;
- OpenBSD-*)
- arch=`arch -s`
- case "$arch" in
- alpha|sparc64)
- SHLIB_CFLAGS="-fPIC"
- ;;
- *)
- SHLIB_CFLAGS="-fpic"
- ;;
- esac
- SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
- LDFLAGS="-Wl,-export-dynamic"
- CFLAGS_OPTIMIZE="-O2"
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # On OpenBSD: Compile with -pthread
- # Don't link with -lpthread
- LIBS=`echo $LIBS | sed s/-lpthread//`
- CFLAGS="$CFLAGS -pthread"
- ])
- # 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} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- LDFLAGS="$LDFLAGS -export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the CFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ;;
- 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=""
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the LDFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
- 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}'`"
- AS_IF([test $do64bit = yes], [
- case `arch` in
- ppc)
- AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
- tcl_cv_cc_arch_ppc64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
- tcl_cv_cc_arch_ppc64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- do64bit_ok=yes
- ]);;
- i386)
- AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
- tcl_cv_cc_arch_x86_64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch x86_64"
- AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
- tcl_cv_cc_arch_x86_64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
- CFLAGS="$CFLAGS -arch x86_64"
- do64bit_ok=yes
- ]);;
- *)
- AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
- esac
- ], [
- # Check for combined 32-bit and 64-bit fat build
- AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
- && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
- fat_32_64=yes])
- ])
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
- AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_single_module = yes], [
- SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
- ])
- # TEA specific: link shlib with current and 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:
- AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
- "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
- LDFLAGS="$LDFLAGS -prebind"])
- LDFLAGS="$LDFLAGS -headerpad_max_install_names"
- AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
- tcl_cv_ld_search_paths_first, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
- tcl_cv_ld_search_paths_first=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- ])
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [__private_extern__],
- [Compiler support for module scope symbols])
- tcl_cv_cc_visibility_hidden=yes
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
- # TEA specific: for combined 32 & 64 bit fat builds of Tk
- # extensions, verify that 64-bit build is possible.
- AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
- AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
- LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
- AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
- tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
- AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
- LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
- AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
- tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- # remove 64-bit arch flags from CFLAGS et al. if configuration
- # does not support 64-bit.
- AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
- AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
- done])
- ])
- ;;
- OS/390-*)
- CFLAGS_OPTIMIZE="" # Optimizer is buggy
- AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
- [Should OS/390 do the right thing with sockets?])
- ;;
- OSF1-V*)
- # Digital OSF/1
- SHLIB_CFLAGS=""
- AS_IF([test "$SHARED_BUILD" = 1], [
- SHLIB_LD='ld -shared -expect_unresolved "*"'
- ], [
- SHLIB_LD='ld -non_shared -expect_unresolved "*"'
- ])
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
- CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
- # see pthread_intro(3) for pthread support on osf1, k.furukawa
- AS_IF([test "${TCL_THREADS}" = 1], [
- CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
- CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
- LIBS=`echo $LIBS | sed s/-lpthreads//`
- AS_IF([test "$GCC" = yes], [
- LIBS="$LIBS -lpthread -lmach -lexc"
- ], [
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ])
- ;;
- QNX-6*)
- # QNX RTP
- # This may work for all QNX, but it was only reported for v6.
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- SCO_SV-3.2*)
- AS_IF([test "$GCC" = yes], [
- SHLIB_CFLAGS="-fPIC -melf"
- LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
- ], [
- SHLIB_CFLAGS="-Kpic -belf"
- LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
- ])
- SHLIB_LD="ld -G"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- 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.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- SunOS-5*)
- # Note: If _REENTRANT isn't defined, then Solaris
- # won't define thread-safe library routines.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- arch=`isainfo`
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- AS_IF([test "$GCC" = yes], [
- AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
- AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64 -mcpu=v9"
- LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
- SHLIB_CFLAGS="-fPIC"
- ])
- ], [
- do64bit_ok=yes
- AS_IF([test "$do64bitVIS" = yes], [
- CFLAGS="$CFLAGS -xarch=v9a"
- LDFLAGS_ARCH="-xarch=v9a"
- ], [
- CFLAGS="$CFLAGS -xarch=v9"
- LDFLAGS_ARCH="-xarch=v9"
- ])
- # Solaris 64 uses this as well
- #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
- ])
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- AS_IF([test "$GCC" = yes], [
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
- esac
- ], [
- do64bit_ok=yes
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- CFLAGS="$CFLAGS -xarch=amd64"
- LDFLAGS="$LDFLAGS -xarch=amd64";;
- esac
- ])
- ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
- ])
-
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "$do64bit_ok" = yes], [
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- # We need to specify -static-libgcc or we need to
- # add the path to the sparv9 libgcc.
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
- # for finding sparcv9 libgcc, get the regular libgcc
- # path, remove so name and append 'sparcv9'
- #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
- #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
- ])])
- ])
- ], [
- case $system in
- SunOS-5.[[1-9]][[0-9]]*)
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
- *)
- SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
- esac
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ])
- ;;
- UNIX_SV* | UnixWare-5*)
- SHLIB_CFLAGS="-KPIC"
- SHLIB_LD='${CC} -G'
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
- # that don't grok the -Bexport option. Test that it does.
- AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_Bexport = yes], [
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- esac
-
- AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
- AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
- ])
-
-dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
-dnl # until the end of configure, as configure's compile and link tests use
-dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
-dnl # preprocessing tests use only CPPFLAGS.
- AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
-
- # 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.
-
- AS_IF([test "$GCC" = yes], [
- case $system in
- AIX-*) ;;
- BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
- IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
- Darwin-*) ;;
- SCO_SV-3.2*) ;;
- windows) ;;
- *) SHLIB_CFLAGS="-fPIC" ;;
- esac])
-
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [extern],
- [No Compiler support for module scope symbols])
- ])
-
- AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
- AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
-
- if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
- AC_CACHE_CHECK(for SEH support in compiler,
- tcl_cv_seh,
- AC_TRY_RUN([
-#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;
- }
- ],
- tcl_cv_seh=yes,
- tcl_cv_seh=no,
- tcl_cv_seh=no)
- )
- if test "$tcl_cv_seh" = "no" ; then
- AC_DEFINE(HAVE_NO_SEH, 1,
- [Defined when mingw does not support SEH])
- 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.
- #
- AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
- tcl_cv_eh_disposition,
- AC_TRY_COMPILE([
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# undef WIN32_LEAN_AND_MEAN
- ],[
- EXCEPTION_DISPOSITION x;
- ],
- tcl_cv_eh_disposition=yes,
- tcl_cv_eh_disposition=no)
- )
- if test "$tcl_cv_eh_disposition" = "no" ; then
- AC_DEFINE(EXCEPTION_DISPOSITION, int,
- [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
- 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.
-
- AC_CACHE_CHECK(for winnt.h that ignores VOID define,
- tcl_cv_winnt_ignore_void,
- AC_TRY_COMPILE([
-#define VOID void
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
- ], [
- CHAR c;
- SHORT s;
- LONG l;
- ],
- tcl_cv_winnt_ignore_void=yes,
- tcl_cv_winnt_ignore_void=no)
- )
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
- AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
- [Defined when cygwin/mingw ignores VOID define in winnt.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.
-
- AC_CACHE_CHECK(for cast to union support,
- tcl_cv_cast_to_union,
- AC_TRY_COMPILE([],
- [
- union foo { int i; double d; };
- union foo f = (union foo) (int) 0;
- ],
- tcl_cv_cast_to_union=yes,
- tcl_cv_cast_to_union=no)
- )
- if test "$tcl_cv_cast_to_union" = "yes"; then
- AC_DEFINE(HAVE_CAST_TO_UNION, 1,
- [Defined when compiler supports casting to union type.])
- fi
-
- AC_SUBST(CFLAGS_DEBUG)
- AC_SUBST(CFLAGS_OPTIMIZE)
- AC_SUBST(CFLAGS_WARNING)
-
- AC_SUBST(STLIB_LD)
- AC_SUBST(SHLIB_LD)
-
- AC_SUBST(SHLIB_LD_LIBS)
- AC_SUBST(SHLIB_CFLAGS)
-
- AC_SUBST(LD_LIBRARY_PATH_VAR)
-
- # These must be called after we do the basic CFLAGS checks and
- # verify any possible 64-bit or similar switches are necessary
- TEA_TCL_EARLY_FLAGS
- TEA_TCL_64BIT_FLAGS
-])
-
-#--------------------------------------------------------------------
-# TEA_SERIAL_PORT
-#
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives,
-# and some build environments have stdin not pointing at a
-# pseudo-terminal (usually /dev/null instead.)
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines only one of the following vars:
-# HAVE_SYS_MODEM_H
-# USE_TERMIOS
-# USE_TERMIO
-# USE_SGTTY
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_SERIAL_PORT], [
- AC_CHECK_HEADERS(sys/modem.h)
- AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
- AC_TRY_RUN([
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termios.h>
-#include <errno.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
- fi])
- case $tcl_cv_api_serial in
- termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
- termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
- sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
-# TEA_PATH_X
-#
-# Locate the X11 header files and the X11 library archive. Try
-# the ac_path_x macro first, but if it doesn't find the X stuff
-# (e.g. because there's no xmkmf program) then check through
-# a list of possible directories. Under some conditions the
-# autoconf macro will return an include directory that contains
-# no include files, so double-check its result just to be safe.
-#
-# This should be called after TEA_CONFIG_CFLAGS as setting the
-# LIBS line can confuse some configure macro magic.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets the following vars:
-# XINCLUDES
-# XLIBSW
-# PKG_LIBS (appends to)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_X], [
- if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
- TEA_PATH_UNIX_X
- fi
-])
-
-AC_DEFUN([TEA_PATH_UNIX_X], [
- AC_PATH_X
- not_really_there=""
- if test "$no_x" = ""; then
- if test "$x_includes" = ""; then
- AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
- else
- if test ! -r $x_includes/X11/Xlib.h; then
- not_really_there="yes"
- fi
- fi
- fi
- if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
- AC_MSG_CHECKING([for X11 header files])
- found_xincludes="no"
- AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
- if test "$found_xincludes" = "no"; then
- dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
- for i in $dirs ; do
- if test -r $i/X11/Xlib.h; then
- AC_MSG_RESULT([$i])
- XINCLUDES=" -I$i"
- found_xincludes="yes"
- break
- fi
- done
- fi
- else
- if test "$x_includes" != ""; then
- XINCLUDES="-I$x_includes"
- found_xincludes="yes"
- fi
- fi
- if test "$found_xincludes" = "no"; then
- AC_MSG_RESULT([couldn't find any!])
- fi
-
- if test "$no_x" = yes; then
- AC_MSG_CHECKING([for X11 libraries])
- XLIBSW=nope
- dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
- for i in $dirs ; do
- if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
- AC_MSG_RESULT([$i])
- XLIBSW="-L$i -lX11"
- x_libraries="$i"
- break
- fi
- done
- else
- if test "$x_libraries" = ""; then
- XLIBSW=-lX11
- else
- XLIBSW="-L$x_libraries -lX11"
- fi
- fi
- if test "$XLIBSW" = nope ; then
- AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
- fi
- if test "$XLIBSW" = nope ; then
- AC_MSG_RESULT([could not find any! Using -lX11.])
- XLIBSW=-lX11
- fi
- # TEA specific:
- if test x"${XLIBSW}" != x ; then
- PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BLOCKING_STYLE
-#
-# The statements below check for systems where POSIX-style
-# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
-# On these systems (mostly older ones), use the old BSD-style
-# FIONBIO approach instead.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# HAVE_SYS_IOCTL_H
-# HAVE_SYS_FILIO_H
-# USE_FIONBIO
-# O_NONBLOCK
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BLOCKING_STYLE], [
- AC_CHECK_HEADERS(sys/ioctl.h)
- AC_CHECK_HEADERS(sys/filio.h)
- TEA_CONFIG_SYSTEM
- AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
- case $system in
- OSF*)
- AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
- AC_MSG_RESULT([FIONBIO])
- ;;
- *)
- AC_MSG_RESULT([O_NONBLOCK])
- ;;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_TIME_HANDLER
-#
-# Checks how the system deals with time.h, what time structures
-# are used on the system, and what fields the structures have.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# USE_DELTA_FOR_TZ
-# HAVE_TM_GMTOFF
-# HAVE_TM_TZADJ
-# HAVE_TIMEZONE_VAR
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TIME_HANDLER], [
- AC_CHECK_HEADERS(sys/time.h)
- AC_HEADER_TIME
- AC_STRUCT_TIMEZONE
-
- AC_CHECK_FUNCS(gmtime_r localtime_r)
-
- AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
- tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
- if test $tcl_cv_member_tm_tzadj = yes ; then
- AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
- fi
-
- AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
- tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
- if test $tcl_cv_member_tm_gmtoff = yes ; then
- AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
- fi
-
- #
- # Its important to include time.h in this check, as some systems
- # (like convex) have timezone functions, etc.
- #
- AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern long timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
- if test $tcl_cv_timezone_long = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- else
- #
- # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
- #
- AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern time_t timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
- if test $tcl_cv_timezone_time = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BUGGY_STRTOD
-#
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" (provided by Tcl) that corrects the error.
-# Also, on Compaq's Tru64 Unix 5.0,
-# strtod(" ") returns 0.0 instead of a failure to convert.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Might defines some of the following vars:
-# strtod (=fixstrtod)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BUGGY_STRTOD], [
- AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
- if test "$tcl_strtod" = 1; then
- AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
- AC_TRY_RUN([
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
- tcl_cv_strtod_buggy=buggy)])
- if test "$tcl_cv_strtod_buggy" = buggy; then
- AC_LIBOBJ([fixstrtod])
- USE_COMPAT=1
- AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_EARLY_FLAGS
-#
-# Check for what flags are needed to be passed so the correct OS
-# features are available.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# _ISOC99_SOURCE
-# _LARGEFILE64_SOURCE
-# _LARGEFILE_SOURCE64
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_EARLY_FLAG],[
- AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
- AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
- AC_TRY_COMPILE([[#define ]$1[ 1
-]$2], $3,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
- if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
- AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
- tcl_flags="$tcl_flags $1"
- fi
-])
-
-AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
- AC_MSG_CHECKING([for required early compiler flags])
- tcl_flags=""
- TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
- [char *p = (char *)strtoll; char *q = (char *)strtoull;])
- TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
- [struct stat64 buf; int i = stat64("/", &buf);])
- TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
- [char *p = (char *)open64;])
- if test "x${tcl_flags}" = "x" ; then
- AC_MSG_RESULT([none])
- else
- AC_MSG_RESULT([${tcl_flags}])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_64BIT_FLAGS
-#
-# Check for what is defined in the way of 64-bit features.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# TCL_WIDE_INT_IS_LONG
-# TCL_WIDE_INT_TYPE
-# HAVE_STRUCT_DIRENT64
-# HAVE_STRUCT_STAT64
-# HAVE_TYPE_OFF64_T
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
- AC_MSG_CHECKING([for 64-bit integer type])
- AC_CACHE_VAL(tcl_cv_type_64bit,[
- tcl_cv_type_64bit=none
- # See if the compiler knows natively about __int64
- AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
- tcl_type_64bit=__int64, tcl_type_64bit="long long")
- # See if we should use long anyway Note that we substitute in the
- # type that is our current guess for a 64-bit type inside this check
- # program, so it should be modified only carefully...
- AC_TRY_COMPILE(,[switch (0) {
- case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
- }],tcl_cv_type_64bit=${tcl_type_64bit})])
- if test "${tcl_cv_type_64bit}" = none ; then
- AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
- AC_MSG_RESULT([using long])
- elif test "${tcl_cv_type_64bit}" = "__int64" \
- -a "${TEA_PLATFORM}" = "windows" ; then
- # TEA specific: We actually want to use the default tcl.h checks in
- # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
- AC_MSG_RESULT([using Tcl header defaults])
- else
- AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
- [What type should be used to define wide integers?])
- AC_MSG_RESULT([${tcl_cv_type_64bit}])
-
- # Now check for auxiliary declarations
- AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <dirent.h>],[struct dirent64 p;],
- tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
- if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
- fi
-
- AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
- AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
-],
- tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
- fi
-
- AC_CHECK_FUNCS(open64 lseek64)
- AC_MSG_CHECKING([for off64_t])
- AC_CACHE_VAL(tcl_cv_type_off64_t,[
- AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
-],
- tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
- dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
- dnl functions lseek64 and open64 are defined.
- if test "x${tcl_cv_type_off64_t}" = "xyes" && \
- test "x${ac_cv_func_lseek64}" = "xyes" && \
- test "x${ac_cv_func_open64}" = "xyes" ; then
- AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- fi
-])
-
-##
-## Here ends the standard Tcl configuration bits and starts the
-## TEA specific functions
-##
-
-#------------------------------------------------------------------------
-# TEA_INIT --
-#
-# Init various Tcl Extension Architecture (TEA) variables.
-# This should be the first called TEA_* macro.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substs the following vars:
-# CYGPATH
-# EXEEXT
-# Defines only:
-# TEA_VERSION
-# TEA_INITED
-# TEA_PLATFORM (windows or unix)
-#
-# "cygpath" is used on windows to generate native path names for include
-# files. These variables should only be used with the compiler and linker
-# since they generate native path names.
-#
-# EXEEXT
-# Select the executable extension based on the host type. This
-# is a lightweight replacement for AC_EXEEXT that doesn't require
-# a compiler.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_INIT], [
- # TEA extensions pass this us the version of TEA they think they
- # are compatible with.
- TEA_VERSION="3.10"
-
- AC_MSG_CHECKING([for correct TEA configuration])
- if test x"${PACKAGE_NAME}" = x ; then
- AC_MSG_ERROR([
-The PACKAGE_NAME variable must be defined by your TEA configure.ac])
- fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
-
- # 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_*)
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
- 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
-
- AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
-
- AC_SUBST(EXEEXT)
- AC_SUBST(CYGPATH)
-
- # This package name must be replaced statically for AC_SUBST to work
- AC_SUBST(PKG_LIB_FILE)
- # Substitute STUB_LIB_FILE in case package creates a stub library too.
- AC_SUBST(PKG_STUB_LIB_FILE)
-
- # We AC_SUBST these here to ensure they are subst'ed,
- # in case the user doesn't call TEA_ADD_...
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
- AC_SUBST(PKG_TCL_SOURCES)
- AC_SUBST(PKG_HEADERS)
- AC_SUBST(PKG_INCLUDES)
- AC_SUBST(PKG_LIBS)
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_SOURCES
-# PKG_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_SOURCES], [
- vars="$@"
- for i in $vars; do
- case $i in
- [\$]*)
- # allow $-var names
- PKG_SOURCES="$PKG_SOURCES $i"
- PKG_OBJECTS="$PKG_OBJECTS $i"
- ;;
- *)
- # check for existence - allows for generic/win/unix VPATH
- # To add more dirs here (like 'src'), you have to update VPATH
- # in Makefile.in as well
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find source file '$i'])
- fi
- PKG_SOURCES="$PKG_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_OBJECTS="$PKG_OBJECTS $j"
- ;;
- esac
- done
- AC_SUBST(PKG_SOURCES)
- AC_SUBST(PKG_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_STUB_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_STUB_SOURCES
-# PKG_STUB_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_STUB_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence - allows for generic/win/unix VPATH
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find stub source file '$i'])
- fi
- PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
- done
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_TCL_SOURCES --
-#
-# Specify one or more Tcl source files. These should be platform
-# independent runtime files.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_TCL_SOURCES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_TCL_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
- fi
- PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
- done
- AC_SUBST(PKG_TCL_SOURCES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_HEADERS --
-#
-# Specify one or more source headers. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_HEADERS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_HEADERS], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
- fi
- PKG_HEADERS="$PKG_HEADERS $i"
- done
- AC_SUBST(PKG_HEADERS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_INCLUDES --
-#
-# Specify one or more include dirs. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_INCLUDES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_INCLUDES], [
- vars="$@"
- for i in $vars; do
- PKG_INCLUDES="$PKG_INCLUDES $i"
- done
- AC_SUBST(PKG_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_LIBS --
-#
-# Specify one or more libraries. Users should check for
-# the right platform before adding to their list. For Windows,
-# libraries provided in "foo.lib" format will be converted to
-# "-lfoo" when using GCC (mingw).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_LIBS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_LIBS], [
- vars="$@"
- for i in $vars; do
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
- # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
- i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
- fi
- PKG_LIBS="$PKG_LIBS $i"
- done
- AC_SUBST(PKG_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CFLAGS --
-#
-# Specify one or more CFLAGS. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_CFLAGS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CFLAGS], [
- PKG_CFLAGS="$PKG_CFLAGS $@"
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CLEANFILES --
-#
-# Specify one or more CLEANFILES.
-#
-# Arguments:
-# one or more file names to clean target
-#
-# Results:
-#
-# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CLEANFILES], [
- CLEANFILES="$CLEANFILES $@"
-])
-
-#------------------------------------------------------------------------
-# TEA_PREFIX --
-#
-# Handle the --prefix=... option by defaulting to what Tcl gave
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# If --prefix or --exec-prefix was not specified, $prefix and
-# $exec_prefix will be set to the values given to Tcl when it was
-# configured.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_PREFIX], [
- if test "${prefix}" = "NONE"; then
- prefix_default=yes
- if test x"${TCL_PREFIX}" != x; then
- AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
- prefix=${TCL_PREFIX}
- else
- AC_MSG_NOTICE([--prefix defaulting to /usr/local])
- prefix=/usr/local
- fi
- fi
- if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
- -o x"${exec_prefix_default}" = x"yes" ; then
- if test x"${TCL_EXEC_PREFIX}" != x; then
- AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
- exec_prefix=${TCL_EXEC_PREFIX}
- else
- AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
- exec_prefix=$prefix
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER_CC --
-#
-# Do compiler checks the way we want. This is just a replacement
-# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER_CC], [
- # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
- # in this macro, they need to go into TEA_SETUP_COMPILER instead.
-
- AC_PROG_CC
- AC_PROG_CPP
-
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
- #--------------------------------------------------------------------
- # Checks to see if the make program sets the $MAKE variable.
- #--------------------------------------------------------------------
-
- AC_PROG_MAKE_SET
-
- #--------------------------------------------------------------------
- # Find ranlib
- #--------------------------------------------------------------------
-
- AC_CHECK_TOOL(RANLIB, ranlib)
-
- #--------------------------------------------------------------------
- # Determines the correct binary file extension (.o, .obj, .exe etc.)
- #--------------------------------------------------------------------
-
- AC_OBJEXT
- AC_EXEEXT
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER --
-#
-# Do compiler checks that use the compiler. This must go after
-# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER], [
- # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
- AC_REQUIRE([TEA_SETUP_COMPILER_CC])
-
- #------------------------------------------------------------------------
- # If we're using GCC, see if the compiler understands -pipe. If so, use it.
- # It makes compiling go faster. (This is only a performance feature.)
- #------------------------------------------------------------------------
-
- if test -z "$no_pipe" -a -n "$GCC"; then
- AC_CACHE_CHECK([if the compiler understands -pipe],
- tcl_cv_cc_pipe, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
- AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
- CFLAGS=$hold_cflags])
- if test $tcl_cv_cc_pipe = yes; then
- CFLAGS="$CFLAGS -pipe"
- fi
- fi
-
- #--------------------------------------------------------------------
- # Common compiler flag setup
- #--------------------------------------------------------------------
-
- AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_MAKE_LIB --
-#
-# Generate a line that can be used to build a shared/unshared library
-# in a platform independent manner.
-#
-# Arguments:
-# none
-#
-# Requires:
-#
-# Results:
-#
-# Defines the following vars:
-# CFLAGS - Done late here to note disturb other AC macros
-# MAKE_LIB - Command to execute to build the Tcl library;
-# differs depending on whether or not Tcl is being
-# compiled as a shared library.
-# MAKE_SHARED_LIB Makefile rule for building a shared library
-# MAKE_STATIC_LIB Makefile rule for building a static library
-# MAKE_STUB_LIB Makefile rule for building a stub library
-# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
-# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_MAKE_LIB], [
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
- MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
- MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
- AC_EGREP_CPP([manifest needed], [
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
- ], [
- # 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}"
- TEA_ADD_CLEANFILES([*.manifest])
- ])
- 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
-
- AC_SUBST(MAKE_LIB)
- AC_SUBST(MAKE_SHARED_LIB)
- AC_SUBST(MAKE_STATIC_LIB)
- AC_SUBST(MAKE_STUB_LIB)
- AC_SUBST(RANLIB_STUB)
- AC_SUBST(VC_MANIFEST_EMBED_DLL)
- AC_SUBST(VC_MANIFEST_EMBED_EXE)
-])
-
-#------------------------------------------------------------------------
-# TEA_LIB_SPEC --
-#
-# Compute the name of an existing object library located in libdir
-# from the given base name and produce the appropriate linker flags.
-#
-# Arguments:
-# basename The base name of the library without version
-# numbers, extensions, or "lib" prefixes.
-# extra_dir Extra directory in which to search for the
-# library. This location is used first, then
-# $prefix/$exec-prefix, then some defaults.
-#
-# Requires:
-# TEA_INIT and TEA_PREFIX must be called first.
-#
-# Results:
-#
-# Defines the following vars:
-# ${basename}_LIB_NAME The computed library name.
-# ${basename}_LIB_SPEC The computed linker flags.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LIB_SPEC], [
- AC_MSG_CHECKING([for $1 library])
-
- # Look in exec-prefix for the library (defined by TEA_PREFIX).
-
- tea_lib_name_dir="${exec_prefix}/lib"
-
- # Or in a user-specified location.
-
- if test x"$2" != x ; then
- tea_extra_lib_dir=$2
- else
- tea_extra_lib_dir=NONE
- fi
-
- for i in \
- `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
- if test -f "$i" ; then
- tea_lib_name_dir=`dirname $i`
- $1_LIB_NAME=`basename $i`
- $1_LIB_PATH_NAME=$i
- break
- fi
- done
-
- if test "${TEA_PLATFORM}" = "windows"; then
- $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
- else
- # Strip off the leading "lib" and trailing ".a" or ".so"
-
- tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
- $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
- fi
-
- if test "x${$1_LIB_NAME}" = x ; then
- AC_MSG_ERROR([not found])
- else
- AC_MSG_RESULT([${$1_LIB_SPEC}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TCL_HEADERS --
-#
-# Locate the private Tcl include files
-#
-# Arguments:
-#
-# Requires:
-# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_TOP_DIR_NATIVE
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
- # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
- AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
- AC_MSG_CHECKING([for Tcl private include files])
-
- TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
- TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
-
- # Check to see if tcl<Plat>Port.h isn't already with the public headers
- # Don't look for tclInt.h because that resides with tcl.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tclh}/tclWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
- result="private headers found with public headers"
- else
- TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
- else
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TCL_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -d "${TCL_BIN_DIR}/Headers" -a \
- -d "${TCL_BIN_DIR}/PrivateHeaders"; then
- TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
- else
- TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TCL_INCLUDES}"
- else
- if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
- fi
- result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TCL_TOP_DIR_NATIVE)
-
- AC_SUBST(TCL_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TCL_HEADERS --
-#
-# Locate the installed public Tcl header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tclinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
- AC_MSG_CHECKING([for Tcl public headers])
-
- AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tclh, [
- # Use the value from --with-tclinclude, if it was given
-
- if test x"${with_tclinclude}" != x ; then
- if test -f "${with_tclinclude}/tcl.h" ; then
- ac_cv_c_tclh=${with_tclinclude}
- else
- AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers directory
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tcl is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TCL_INCLUDE_SPEC}" != x ; then
- d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tcl.h" ; then
- ac_cv_c_tclh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tclh}" = x ; then
- AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tclh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
-
- TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TCL_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TK_HEADERS --
-#
-# Locate the private Tk include files
-#
-# Arguments:
-#
-# Requires:
-# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
- # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
- AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
- AC_MSG_CHECKING([for Tk private include files])
-
- TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
- TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
-
- # Check to see if tk<Plat>Port.h isn't already with the public headers
- # Don't look for tkInt.h because that resides with tk.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tkh}/tkWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
- result="private headers found with public headers"
- else
- TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
- TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
- else
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TK_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
- # Detect and add ttk subdir
- if test -d "${TK_SRC_DIR}/generic/ttk"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
- fi
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -d "${TK_BIN_DIR}/Headers" -a \
- -d "${TK_BIN_DIR}/PrivateHeaders"; then
- TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
- else
- TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TK_INCLUDES}"
- else
- if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
- fi
- result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TK_TOP_DIR_NATIVE)
- AC_SUBST(TK_XLIB_DIR_NATIVE)
-
- AC_SUBST(TK_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TK_HEADERS --
-#
-# Locate the installed public Tk header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tkinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
- AC_MSG_CHECKING([for Tk public headers])
-
- AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tkh, [
- # Use the value from --with-tkinclude, if it was given
-
- if test x"${with_tkinclude}" != x ; then
- if test -f "${with_tkinclude}/tk.h" ; then
- ac_cv_c_tkh=${with_tkinclude}
- else
- AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers directory.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tk is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tk's --prefix location,
- # relative to directory of tkConfig.sh, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TK_PREFIX}/include 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TK_INCLUDE_SPEC}" != x ; then
- d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tk.h" ; then
- ac_cv_c_tkh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tkh}" = x ; then
- AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tkh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
-
- TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TK_INCLUDES)
-
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- # On Windows and Aqua, we need the X compat headers
- AC_MSG_CHECKING([for X11 header files])
- if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
- INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
- TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
- AC_SUBST(TK_XINCLUDES)
- fi
- AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_CONFIG --
-#
-# Locate the ${1}Config.sh file and perform a sanity check on
-# the ${1} compile flags. These are used by packages like
-# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-$1=...
-#
-# Defines the following vars:
-# $1_BIN_DIR Full path to the directory containing
-# the $1Config.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CONFIG], [
- #
- # Ok, lets find the $1 configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-$1
- #
-
- if test x"${no_$1}" = x ; then
- # we reset no_$1 in case something fails here
- no_$1=true
- AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
- AC_MSG_CHECKING([for $1 configuration])
- AC_CACHE_VAL(ac_cv_c_$1config,[
-
- # First check to see if --with-$1 was specified.
- if test x"${with_$1config}" != x ; then
- case ${with_$1config} in
- */$1Config.sh )
- if test -f ${with_$1config}; then
- AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
- with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
- fi;;
- esac
- if test -f "${with_$1config}/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
- else
- AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
- fi
- fi
-
- # then check for a private $1 installation
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in \
- ../$1 \
- `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../$1 \
- `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../../$1 \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ${srcdir}/../$1 \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- if test -f "$i/unix/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i/unix; pwd)`
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_$1config}" = x ; then
- $1_BIN_DIR="# no $1 configs found"
- AC_MSG_WARN([Cannot find $1 configuration definitions])
- exit 0
- else
- no_$1=
- $1_BIN_DIR=${ac_cv_c_$1config}
- AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG --
-#
-# Load the $1Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# $1_SRC_DIR
-# $1_LIB_FILE
-# $1_LIB_SPEC
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_CONFIG], [
- AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
-
- if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
- AC_MSG_RESULT([loading])
- . "${$1_BIN_DIR}/$1Config.sh"
- else
- AC_MSG_RESULT([file not found])
- fi
-
- #
- # If the $1_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable $1_LIB_SPEC will be set to the value
- # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
- # instead of $1_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- #
-
- if test -f "${$1_BIN_DIR}/Makefile" ; then
- AC_MSG_WARN([Found Makefile - using build library specs for $1])
- $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
- $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
- $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
- $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
- $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
- fi
-
- AC_SUBST($1_VERSION)
- AC_SUBST($1_BIN_DIR)
- AC_SUBST($1_SRC_DIR)
-
- AC_SUBST($1_LIB_FILE)
- AC_SUBST($1_LIB_SPEC)
-
- AC_SUBST($1_STUB_LIB_FILE)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_PATH)
-
- # Allow the caller to prevent this auto-check by specifying any 2nd arg
- AS_IF([test "x$2" = x], [
- # Check both upper and lower-case variants
- # If a dev wanted non-stubs libs, this function could take an option
- # to not use _STUB in the paths below
- AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
- [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
- [TEA_LOAD_CONFIG_LIB($1_STUB)])
- ])
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG_LIB --
-#
-# Helper function to load correct library from another extension's
-# ${PACKAGE}Config.sh.
-#
-# Results:
-# Adds to LIBS the appropriate extension library
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
- AC_MSG_CHECKING([For $1 library for LIBS])
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${$1_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
- TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
- AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
- else
- TEA_ADD_LIBS([${$1_LIB_SPEC}])
- AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
- fi
- else
- AC_MSG_RESULT([file not found])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_EXPORT_CONFIG --
-#
-# Define the data to insert into the ${PACKAGE}Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1
-#
-# Results:
-# Substitutes the following vars:
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_EXPORT_CONFIG], [
- #--------------------------------------------------------------------
- # These are for $1Config.sh
- #--------------------------------------------------------------------
-
- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
- eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
- if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
- eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
- else
- eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- fi
- $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
- $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
- $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
- $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
- $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
- $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
-
- AC_SUBST($1_BUILD_LIB_SPEC)
- AC_SUBST($1_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_PATH)
- AC_SUBST($1_STUB_LIB_PATH)
-
- AC_SUBST(MAJOR_VERSION)
- AC_SUBST(MINOR_VERSION)
- AC_SUBST(PATCHLEVEL)
-])
-
-
-#------------------------------------------------------------------------
-# TEA_PATH_CELIB --
-#
-# Locate Keuchel's celib emulation layer for targeting Win/CE
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-celib=...
-#
-# Defines the following vars:
-# CELIB_DIR Full path to the directory containing
-# the include and platform lib files
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CELIB], [
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-celib
-
- if test x"${no_celib}" = x ; then
- # we reset no_celib in case something fails here
- no_celib=true
- AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
- AC_MSG_CHECKING([for Windows/CE celib directory])
- AC_CACHE_VAL(ac_cv_c_celibconfig,[
- # First check to see if --with-celibconfig was specified.
- if test x"${with_celibconfig}" != x ; then
- if test -d "${with_celibconfig}/inc" ; then
- ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
- else
- AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
- fi
- fi
-
- # then check for a celib library
- if test x"${ac_cv_c_celibconfig}" = x ; then
- for i in \
- ../celib-palm-3.0 \
- ../celib \
- ../../celib-palm-3.0 \
- ../../celib \
- `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
- ${srcdir}/../celib-palm-3.0 \
- ${srcdir}/../celib \
- `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
- ; do
- if test -d "$i/inc" ; then
- ac_cv_c_celibconfig=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
- if test x"${ac_cv_c_celibconfig}" = x ; then
- AC_MSG_ERROR([Cannot find celib support library directory])
- else
- no_celib=
- CELIB_DIR=${ac_cv_c_celibconfig}
- CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
- AC_MSG_RESULT([found $CELIB_DIR])
- fi
- fi
-])
-
-###
-# Tip 430 - ZipFS Modifications
-###
-#------------------------------------------------------------------------
-# SC_ZIPFS_SUPPORT
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-# TCL_ZIPFS_FLAG
-# ZIP_PROG
-#------------------------------------------------------------------------
-
-#------------------------------------------------------------------------
-# SC_PROG_ZIP
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# ZIP_PROG
-# ZIP_PROG_OPTIONS
-# ZIP_PROG_VFSSEARCH
-# ZIP_INSTALL_OBJS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ZIPFS_SUPPORT], [
- AC_MSG_CHECKING([for zipfs support])
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- INSTALL_MSGS=""
- # If our native tclsh processes the "install" command line option
- # we can use it to mint zip files
- AS_IF([$TCLSH_PROG install],[
- ZIP_PROG=${TCLSH_PROG}
- ZIP_PROG_OPTIONS="install mkzip"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
- ])
- if test "x$ZIP_PROG" = "x" ; then
- AC_CACHE_VAL(ac_cv_path_zip, [
- search_path=`echo ${PATH} | sed -e 's/:/ /g'`
- for dir in $search_path ; do
- for j in `ls -r $dir/zip 2> /dev/null` \
- `ls -r $dir/zip 2> /dev/null` ; do
- if test x"$ac_cv_path_zip" = x ; then
- if test -f "$j" ; then
- ac_cv_path_zip=$j
- break
- fi
- fi
- done
- done
- ])
- if test -f "$ac_cv_path_zip" ; then
- ZIP_PROG="$ac_cv_path_zip "
- AC_MSG_RESULT([$ZIP_PROG])
- ZIP_PROG_OPTIONS="-rq"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Found INFO Zip in environment])
- # Use standard arguments for zip
- fi
- fi
- if test "x$ZIP_PROG" = "x" ; then
- # It is not an error if an installed version of Zip can't be located.
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- else
- # ZIPFS Support
- eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
- if test ${TCL_ZIP_FILE} = "" ; then
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- INSTALL_LIBRARIES=install-libraries
- INSTALL_MSGS=install-msgs
- else
- if test ${SHARED_BUILD} = 1 ; then
- TCL_ZIPFS_SUPPORT=1
- INSTALL_LIBRARIES=install-libraries-zipfs-shared
- else
- TCL_ZIPFS_SUPPORT=2
- INSTALL_LIBRARIES=install-libraries-zipfs-static
- fi
- TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
- fi
- fi
-
- AC_SUBST(TCL_ZIP_FILE)
- AC_SUBST(TCL_ZIPFS_SUPPORT)
- AC_SUBST(TCL_ZIPFS_FLAG)
- AC_SUBST(ZIP_PROG)
- AC_SUBST(ZIP_PROG_OPTIONS)
- AC_SUBST(ZIP_PROG_VFSSEARCH)
- AC_SUBST(INSTALL_LIBRARIES)
- AC_SUBST(INSTALL_MSGS)
-])
-
-# Local Variables:
-# mode: autoconf
-# End:
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules-ext.vc b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules-ext.vc
deleted file mode 100644
index ab86876..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules-ext.vc
+++ /dev/null
@@ -1,118 +0,0 @@
-# This file should only be included in makefiles for Tcl extensions,
-# NOT in the makefile for Tcl itself.
-
-!ifndef _RULES_EXT_VC
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-!if "$(PROJECT)" == "tcl"
-!error The rules-ext.vc file is not intended for Tcl itself.
-!endif
-
-# We extract version numbers using the nmakehlp program. For now use
-# the local copy of nmakehlp. Once we locate Tcl, we will use that
-# one if it is newer.
-!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
-# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
-
-_RULESDIR = $(TCLDIR:/=\)
-
-!else
-
-# If an installation path is specified, that is also the Tcl directory.
-# Also Tk never builds against an installed Tcl, it needs Tcl sources
-!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
-_RULESDIR=$(INSTALLDIR:/=\)
-!else
-# Locate Tcl sources
-!if [echo _RULESDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-_RULESDIR = ..\..\tcl
-!else
-!include nmakehlp.out
-!endif
-
-!endif # defined(INSTALLDIR)....
-
-!endif # ifndef TCLDIR
-
-# Now look for the targets.vc file under the Tcl root. Note we check this
-# file and not rules.vc because the latter also exists on older systems.
-!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
-_RULESDIR = $(_RULESDIR)\lib\nmake
-!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
-_RULESDIR = $(_RULESDIR)\win
-!else
-# If we have not located Tcl's targets file, most likely we are compiling
-# against an older version of Tcl and so must use our own support files.
-_RULESDIR = .
-!endif
-
-!if "$(_RULESDIR)" != "."
-# Potentially using Tcl's support files. If this extension has its own
-# nmake support files, need to compare the versions and pick newer.
-
-!if exist("rules.vc") # The extension has its own copy
-
-!if [echo TCL_RULES_MAJOR = \> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo TCL_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-
-!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
-!endif
-!if [echo OUR_RULES_MINOR = \>> versions.vc] \
- && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
-!endif
-!include versions.vc
-# We have a newer version of the support files, use them
-!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
-_RULESDIR = .
-!endif
-
-!endif # if exist("rules.vc")
-
-!endif # if $(_RULESDIR) != "."
-
-# Let rules.vc know what copy of nmakehlp.c to use.
-NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
-
-# Get rid of our internal defines before calling rules.vc
-!undef TCL_RULES_MAJOR
-!undef TCL_RULES_MINOR
-!undef OUR_RULES_MAJOR
-!undef OUR_RULES_MINOR
-
-!if exist("$(_RULESDIR)\rules.vc")
-!message *** Using $(_RULESDIR)\rules.vc
-!include "$(_RULESDIR)\rules.vc"
-!else
-!error *** Could not locate rules.vc in $(_RULESDIR)
-!endif
-
-!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules.vc b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules.vc
deleted file mode 100644
index bbb412d..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/rules.vc
+++ /dev/null
@@ -1,1723 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/targets.vc b/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/targets.vc
deleted file mode 100644
index 312022d..0000000
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/targets.vc
+++ /dev/null
@@ -1,98 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/ChangeLog b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/ChangeLog
index 16096e8..16096e8 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/ChangeLog
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/ChangeLog
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/Makefile.in b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/Makefile.in
new file mode 100644
index 0000000..106b1b0
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/Makefile.in
@@ -0,0 +1,478 @@
+# Makefile.in --
+#
+# This file is a Makefile for Sample TEA Extension. If it has the name
+# "Makefile.in" then it is a template for a Makefile; to generate the
+# actual Makefile, run "./configure", which is a configuration script
+# generated by the "autoconf" program (constructs like "@foo@" will get
+# replaced in the actual Makefile.
+#
+# Copyright (c) 1999 Scriptics Corporation.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#========================================================================
+# Add additional lines to handle any additional AC_SUBST cases that
+# have been added in a customized configure script.
+#========================================================================
+
+#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
+
+#========================================================================
+# Nothing of the variables below this line should need to be changed.
+# Please check the TARGETS section below to make sure the make targets
+# are correct.
+#========================================================================
+
+#========================================================================
+# The names of the source files is defined in the configure script.
+# The object files are used for linking into the final library.
+# This will be used when a dist target is added to the Makefile.
+# It is not important to specify the directory, as long as it is the
+# $(srcdir) or in the generic, win or unix subdirectory.
+#========================================================================
+
+PKG_SOURCES = @PKG_SOURCES@
+PKG_OBJECTS = @PKG_OBJECTS@
+
+PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
+PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
+
+#========================================================================
+# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
+# this package that need to be installed, if any.
+#========================================================================
+
+PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
+
+#========================================================================
+# This is a list of public header files to be installed, if any.
+#========================================================================
+
+PKG_HEADERS = @PKG_HEADERS@
+
+#========================================================================
+# "PKG_LIB_FILE" refers to the library (dynamic or static as per
+# configuration options) composed of the named objects.
+#========================================================================
+
+PKG_LIB_FILE = @PKG_LIB_FILE@
+PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
+
+lib_BINARIES = $(PKG_LIB_FILE)
+BINARIES = $(lib_BINARIES)
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+libdir = @libdir@
+includedir = @includedir@
+datarootdir = @datarootdir@
+datadir = @datadir@
+mandir = @mandir@
+
+DESTDIR =
+
+PKG_DIR = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
+pkgdatadir = $(datadir)/$(PKG_DIR)
+pkglibdir = $(libdir)/$(PKG_DIR)
+pkgincludedir = $(includedir)/$(PKG_DIR)
+
+top_builddir = @abs_top_builddir@
+
+INSTALL_OPTIONS =
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
+INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_LIBRARY = @INSTALL_LIBRARY@
+
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+CC = @CC@
+CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
+CFLAGS_WARNING = @CFLAGS_WARNING@
+EXEEXT = @EXEEXT@
+LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
+MAKE_LIB = @MAKE_LIB@
+MAKE_SHARED_LIB = @MAKE_SHARED_LIB@
+MAKE_STATIC_LIB = @MAKE_STATIC_LIB@
+MAKE_STUB_LIB = @MAKE_STUB_LIB@
+OBJEXT = @OBJEXT@
+RANLIB = @RANLIB@
+RANLIB_STUB = @RANLIB_STUB@
+SHLIB_CFLAGS = @SHLIB_CFLAGS@
+SHLIB_LD = @SHLIB_LD@
+SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
+STLIB_LD = @STLIB_LD@
+#TCL_DEFS = @TCL_DEFS@
+TCL_BIN_DIR = @TCL_BIN_DIR@
+TCL_SRC_DIR = @TCL_SRC_DIR@
+#TK_BIN_DIR = @TK_BIN_DIR@
+#TK_SRC_DIR = @TK_SRC_DIR@
+
+# Not used, but retained for reference of what libs Tcl required
+#TCL_LIBS = @TCL_LIBS@
+
+TDBC_VERSION = @TDBC_VERSION@
+TDBC_BIN_DIR = @tdbc_BIN_DIR@
+TDBC_LIB_FILE = @TDBC_LIB_FILE@
+
+#========================================================================
+# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
+# package without installing. The other environment variables allow us
+# to test against an uninstalled Tcl. Add special env vars that you
+# require for testing here (like TCLX_LIBRARY).
+#========================================================================
+
+EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
+#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
+TCLLIBPATH = $(top_builddir) $(TDBC_BIN_DIR)
+TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
+PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+ PATH="$(EXTRA_PATH):$(PATH)" \
+ TDBC_LIBRARY=`@CYGPATH@ @tdbc_LIBRARY_PATH@` \
+ TCLLIBPATH="$(TCLLIBPATH)"
+
+TCLSH_PROG = @TCLSH_PROG@
+TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
+
+#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
+#WISH_PROG = @WISH_PROG@
+#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
+
+SHARED_BUILD = @SHARED_BUILD@
+
+INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@
+#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
+
+PKG_CFLAGS = @PKG_CFLAGS@
+
+# TCL_DEFS is not strictly need here, but if you remove it, then you
+# must make sure that configure.ac checks for the necessary components
+# that your library may use. TCL_DEFS can actually be a problem if
+# you do not compile with a similar machine setup as the Tcl core was
+# compiled with.
+#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
+DEFS = @DEFS@ $(PKG_CFLAGS)
+
+# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
+CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
+CLEANFILES = @CLEANFILES@
+
+CPPFLAGS = @CPPFLAGS@
+LIBS = @PKG_LIBS@ @LIBS@
+AR = @AR@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
+GDB = gdb
+VALGRIND = valgrind
+VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
+ --leak-check=yes --show-reachable=yes -v
+
+TCL_VERSION = @TCL_VERSION@
+TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@
+
+tmdir = $(libdir)/tcl$(TCL_MAJOR_VERSION)/$(TCL_VERSION)
+pkgslash = `echo $(PACKAGE_NAME) | sed s=tdbc=tdbc/=`
+pkgtmdir = $(tmdir)/tdbc
+pkgtmfile = $(tmdir)/$(pkgslash)-$(PACKAGE_VERSION).tm
+
+.SUFFIXES: .c .$(OBJEXT)
+
+#========================================================================
+# Start of user-definable TARGETS section
+#========================================================================
+
+#========================================================================
+# TEA TARGETS. Please note that the "libraries:" target refers to platform
+# independent files, and the "binaries:" target includes executable programs and
+# platform-dependent libraries. Modify these targets so that they install
+# the various pieces of your package. The make and install rules
+# for the BINARIES that you specified above have already been done.
+#========================================================================
+
+all: binaries libraries doc
+
+#========================================================================
+# The binaries target builds executable programs, Windows .dll's, unix
+# shared/static libraries, and any other platform-dependent files.
+# The list of targets to build for "binaries:" is specified at the top
+# of the Makefile, in the "BINARIES" variable.
+#========================================================================
+
+binaries: $(BINARIES)
+
+libraries:
+
+#========================================================================
+# Your doc target should differentiate from doc builds (by the developer)
+# and doc installs (see install-doc), which just install the docs on the
+# end user machine when building from source.
+#========================================================================
+
+doc:
+
+install: all install-tm install-doc
+
+install-binaries: binaries install-lib-binaries install-bin-binaries
+
+#========================================================================
+# This rule installs platform-independent files, such as header files.
+# The list=...; for p in $$list handles the empty list case x-platform.
+#========================================================================
+
+install-libraries: libraries
+ @$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
+ @echo "Installing header files in $(DESTDIR)$(includedir)"
+ @list='$(PKG_HEADERS)'; for i in $$list; do \
+ echo "Installing $(srcdir)/$$i" ; \
+ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
+ done;
+
+#========================================================================
+# Install documentation. Unix manpages should go in the $(mandir)
+# directory.
+#========================================================================
+
+install-doc: doc
+ @$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
+ @echo "Installing documentation in $(DESTDIR)$(mandir)"
+ @list='$(srcdir)/doc/*.n'; for i in $$list; do \
+ echo "Installing $$i"; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
+ done
+
+test: binaries libraries
+ $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
+ -load "package ifneeded tdbc::sqlite3 $(PACKAGE_VERSION) \
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcsqlite3.tcl`]"
+
+shell: binaries libraries
+ @$(TCLSH) $(SCRIPT)
+
+gdb:
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
+
+gdb-test: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(GDB) \
+ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
+ $(TESTFLAGS) -singleproc 1 \
+ -load "package ifneeded tdbc::sqlite3 $(PACKAGE_VERSION) \
+ [list source `@CYGPATH@ $(srcdir)/library/tdbcsqlite3.tcl`]"
+
+valgrind: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
+ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
+
+valgrindshell: binaries libraries
+ $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
+
+depend:
+
+#========================================================================
+# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
+# mentioned above. That will ensure that this target is built when you
+# run "make binaries".
+#
+# The $(PKG_OBJECTS) objects are created and linked into the final
+# library. In most cases these object files will correspond to the
+# source files above.
+#========================================================================
+
+$(PKG_LIB_FILE): $(PKG_OBJECTS)
+ -rm -f $(PKG_LIB_FILE)
+ ${MAKE_LIB}
+ $(RANLIB) $(PKG_LIB_FILE)
+
+$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
+ -rm -f $(PKG_STUB_LIB_FILE)
+ ${MAKE_STUB_LIB}
+ $(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
+
+#========================================================================
+# We need to enumerate the list of .c to .o lines here.
+#
+# In the following lines, $(srcdir) refers to the toplevel directory
+# containing your extension. If your sources are in a subdirectory,
+# you will have to modify the paths to reflect this:
+#
+# sample.$(OBJEXT): $(srcdir)/generic/sample.c
+# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
+#
+# Setting the VPATH variable to a list of paths will cause the makefile
+# to look into these paths when resolving .c to .obj dependencies.
+# As necessary, add $(srcdir):$(srcdir)/compat:....
+#========================================================================
+
+VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
+
+.c.@OBJEXT@:
+ $(COMPILE) -c `@CYGPATH@ $<` -o $@
+
+#========================================================================
+# Distribution creation
+# You may need to tweak this target to make it work correctly.
+#========================================================================
+
+#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
+COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
+DIST_ROOT = /tmp/dist
+DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
+
+dist-clean:
+ rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
+
+dist: dist-clean
+ $(INSTALL_DATA_DIR) $(DIST_DIR)
+
+ # TEA files
+ $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
+ $(DIST_DIR)/tclconfig/
+
+ # Extension files
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/ChangeLog \
+ $(srcdir)/license.terms \
+ $(srcdir)/README \
+ $(srcdir)/pkgIndex.tcl.in \
+ $(DIST_DIR)/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/doc
+ $(DIST_INSTALL_DATA) $(srcdir)/doc/tdbc_sqlite3.n $(DIST_DIR)/doc/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/library
+ $(DIST_INSTALL_DATA) $(srcdir)/library/tdbcsqlite3.tcl $(DIST_DIR)/library/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/tests
+ $(DIST_INSTALL_DATA) $(srcdir)/tests/all.tcl $(srcdir)/tests/tdbcsqlite3.test \
+ $(DIST_DIR)/tests/
+
+ $(INSTALL_DATA_DIR) $(DIST_DIR)/win
+ $(DIST_INSTALL_DATA) $(srcdir)/win/makefile.vc $(srcdir)/win/nmakehlp.c \
+ $(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
+ $(srcdir)/win/rules.vc $(DIST_DIR)/win/
+
+ (cd $(DIST_ROOT); $(COMPRESS);)
+
+#========================================================================
+# End of user-definable section
+#========================================================================
+
+#========================================================================
+# Don't modify the file to clean here. Instead, set the "CLEANFILES"
+# variable in configure.ac
+#========================================================================
+
+clean:
+ -test -z "$(BINARIES)" || rm -f $(BINARIES)
+ -rm -f *.$(OBJEXT) core *.core
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean: clean
+ -rm -f *.tab.c
+ -rm -f $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log config.status
+
+#========================================================================
+# Install binary object libraries. On Windows this includes both .dll and
+# .lib files. Because the .lib files are not explicitly listed anywhere,
+# we need to deduce their existence from the .dll file of the same name.
+# Library files go into the lib directory.
+# In addition, this will generate the pkgIndex.tcl
+# file in the install location (assuming it can find a usable tclsh shell)
+#
+# You should not have to modify this target.
+#========================================================================
+
+install-lib-binaries: binaries
+ @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
+ @list='$(lib_BINARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+ ext=`echo $$p|sed -e "s/.*\.//"`; \
+ if test "x$$ext" = "xdll"; then \
+ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
+ if test -f $$lib; then \
+ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
+ $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
+ fi; \
+ fi; \
+ fi; \
+ done
+ @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ destp=`basename $$p`; \
+ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
+ fi; \
+ done
+ @if test "x$(SHARED_BUILD)" = "x1"; then \
+ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
+ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
+ fi
+
+#========================================================================
+# Install binary executables (e.g. .exe files and dependent .dll files)
+# This is for files that must go in the bin directory (located next to
+# wish and tclsh), like dependent .dll files on Windows.
+#
+# You should not have to modify this target, except to define bin_BINARIES
+# above if necessary.
+#========================================================================
+
+install-bin-binaries: binaries
+ @$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
+ @list='$(bin_BINARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
+ fi; \
+ done
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+uninstall-binaries:
+ list='$(lib_BINARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+ done
+ list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
+ p=`basename $$p`; \
+ rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+ done
+ list='$(bin_BINARIES)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/$$p; \
+ done
+
+install-tm:
+ @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkgtmdir)
+ $(INSTALL_DATA) $(srcdir)/library/tdbcsqlite3.tcl \
+ $(DESTDIR)$(pkgtmfile)
+
+.PHONY: all binaries clean depend distclean doc install libraries test
+.PHONY: gdb gdb-test valgrind valgrindshell
+.PHONY: install-tm
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/README b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/README
index 052d7c1..a8c5b53 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/README
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/README
@@ -1,6 +1,6 @@
README: tdbcsqlite3
- This is the 1.0.6 source distribution of the bridge between Tcl
+ This is the 1.1.0 source distribution of the bridge between Tcl
Database Connectivity (TDBC) and SQLite3, an open-source SQL
database with an in-process server.
diff --git a/tcl8.6/pkgs/tdbc1.0.6/aclocal.m4 b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/aclocal.m4
index 83d361c..83d361c 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/aclocal.m4
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/aclocal.m4
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure
new file mode 100755
index 0000000..dde0772
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure
@@ -0,0 +1,7780 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for tdbcsqlite3 1.1.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"
+ 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='tdbcsqlite3'
+PACKAGE_TARNAME='tdbcsqlite3'
+PACKAGE_VERSION='1.1.0'
+PACKAGE_STRING='tdbcsqlite3 1.1.0'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+TCL_MINOR_VERSION
+TCL_MAJOR_VERSION
+TCLSH_PROG
+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
+RANLIB
+TCL_THREADS
+TDBC_LIB_FILE
+TDBC_VERSION
+tdbc_LIBRARY_PATH
+tdbc_STUB_LIB_PATH
+tdbc_STUB_LIB_SPEC
+tdbc_STUB_LIB_FILE
+tdbc_LIB_SPEC
+tdbc_LIB_FILE
+tdbc_SRC_DIR
+tdbc_BIN_DIR
+tdbc_VERSION
+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
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
+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_tdbc
+enable_threads
+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'
+
+
+# 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 tdbcsqlite3 1.1.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/tdbcsqlite3]
+ --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 tdbcsqlite3 1.1.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 (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-tdbc directory containing tdbc configuration (tdbcConfig.sh)
+ --with-celib=DIR use Windows/CE support library from DIR
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ 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>
+
+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
+tdbcsqlite3 configure 1.1.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_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
+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 tdbcsqlite3 $as_me 1.1.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_VERSION="3.13"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
+$as_echo "ok (TEA ${TEA_VERSION})" >&6; }
+
+ # 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_*|*MINGW64_*)
+ # 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_...
+
+
+
+
+
+
+
+
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
+
+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` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 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/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/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:
+
+
+
+
+
+
+
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#----------------------------------------------------------------------
+# Load the tdbcConfig.sh file
+#----------------------------------------------------------------------
+
+
+ #
+ # Ok, lets find the tdbc configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tdbc
+ #
+
+ if test x"${no_tdbc}" = x ; then
+ # we reset no_tdbc in case something fails here
+ no_tdbc=true
+
+# Check whether --with-tdbc was given.
+if test "${with_tdbc+set}" = set; then :
+ withval=$with_tdbc; with_tdbcconfig=${withval}
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdbc configuration" >&5
+$as_echo_n "checking for tdbc configuration... " >&6; }
+ if ${ac_cv_c_tdbcconfig+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+
+ # First check to see if --with-tdbc was specified.
+ if test x"${with_tdbcconfig}" != x ; then
+ case ${with_tdbcconfig} in
+ */tdbcConfig.sh )
+ if test -f ${with_tdbcconfig}; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tdbc argument should refer to directory containing tdbcConfig.sh, not to tdbcConfig.sh itself" >&5
+$as_echo "$as_me: WARNING: --with-tdbc argument should refer to directory containing tdbcConfig.sh, not to tdbcConfig.sh itself" >&2;}
+ with_tdbcconfig=`echo ${with_tdbcconfig} | sed 's!/tdbcConfig\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_tdbcconfig}/tdbcConfig.sh" ; then
+ ac_cv_c_tdbcconfig=`(cd ${with_tdbcconfig}; pwd)`
+ else
+ as_fn_error $? "${with_tdbcconfig} directory doesn't contain tdbcConfig.sh" "$LINENO" 5
+ fi
+ fi
+
+ # then check for a private tdbc installation
+ if test x"${ac_cv_c_tdbcconfig}" = x ; then
+ for i in \
+ ../tdbc \
+ `ls -dr ../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
+ `ls -dr ../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
+ `ls -dr ../tdbc*[0-9].[0-9] 2>/dev/null` \
+ `ls -dr ../tdbc*[0-9].[0-9]* 2>/dev/null` \
+ ../../tdbc \
+ `ls -dr ../../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
+ `ls -dr ../../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
+ `ls -dr ../../tdbc*[0-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../tdbc*[0-9].[0-9]* 2>/dev/null` \
+ ../../../tdbc \
+ `ls -dr ../../../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
+ `ls -dr ../../../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
+ `ls -dr ../../../tdbc*[0-9].[0-9] 2>/dev/null` \
+ `ls -dr ../../../tdbc*[0-9].[0-9]* 2>/dev/null` \
+ ${srcdir}/../tdbc \
+ `ls -dr ${srcdir}/../tdbc*[0-9].[0-9]*.[0-9]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tdbc*[0-9].[0-9][0-9] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tdbc*[0-9].[0-9] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tdbc*[0-9].[0-9]* 2>/dev/null` \
+ ; do
+ if test -f "$i/tdbcConfig.sh" ; then
+ ac_cv_c_tdbcconfig=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/tdbcConfig.sh" ; then
+ ac_cv_c_tdbcconfig=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tdbcconfig}" = 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/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/tdbcConfig.sh" ; then
+ ac_cv_c_tdbcconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ if test x"${ac_cv_c_tdbcconfig}" = x ; then
+ tdbc_BIN_DIR="# no tdbc configs found"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find tdbc configuration definitions" >&5
+$as_echo "$as_me: WARNING: Cannot find tdbc configuration definitions" >&2;}
+ exit 0
+ else
+ no_tdbc=
+ tdbc_BIN_DIR=${ac_cv_c_tdbcconfig}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $tdbc_BIN_DIR/tdbcConfig.sh" >&5
+$as_echo "found $tdbc_BIN_DIR/tdbcConfig.sh" >&6; }
+ fi
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${tdbc_BIN_DIR}/tdbcConfig.sh" >&5
+$as_echo_n "checking for existence of ${tdbc_BIN_DIR}/tdbcConfig.sh... " >&6; }
+
+ if test -f "${tdbc_BIN_DIR}/tdbcConfig.sh" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+ . "${tdbc_BIN_DIR}/tdbcConfig.sh"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
+$as_echo "file not found" >&6; }
+ fi
+
+ #
+ # If the tdbc_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 tdbc_LIB_SPEC will be set to the value
+ # of tdbc_BUILD_LIB_SPEC. An extension should make use of tdbc_LIB_SPEC
+ # instead of tdbc_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${tdbc_BIN_DIR}/Makefile" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found Makefile - using build library specs for tdbc" >&5
+$as_echo "$as_me: WARNING: Found Makefile - using build library specs for tdbc" >&2;}
+ tdbc_LIB_SPEC=${tdbc_BUILD_LIB_SPEC}
+ tdbc_STUB_LIB_SPEC=${tdbc_BUILD_STUB_LIB_SPEC}
+ tdbc_STUB_LIB_PATH=${tdbc_BUILD_STUB_LIB_PATH}
+ tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
+ tdbc_LIBRARY_PATH=${tdbc_LIBRARY_PATH}
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ if test "x" = x; then :
+
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ if test "x${tdbc_STUB_LIB_SPEC}" = x; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking For TDBC_STUB library for LIBS" >&5
+$as_echo_n "checking For TDBC_STUB library for LIBS... " >&6; }
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${TDBC_STUB_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+
+ vars="\"`${CYGPATH} ${TDBC_STUB_LIB_PATH}`\""
+ 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
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using TDBC_STUB_LIB_PATH ${TDBC_STUB_LIB_PATH}" >&5
+$as_echo "using TDBC_STUB_LIB_PATH ${TDBC_STUB_LIB_PATH}" >&6; }
+ else
+
+ vars="${TDBC_STUB_LIB_SPEC}"
+ 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
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using TDBC_STUB_LIB_SPEC ${TDBC_STUB_LIB_SPEC}" >&5
+$as_echo "using TDBC_STUB_LIB_SPEC ${TDBC_STUB_LIB_SPEC}" >&6; }
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
+$as_echo "file not found" >&6; }
+ fi
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking For tdbc_STUB library for LIBS" >&5
+$as_echo_n "checking For tdbc_STUB library for LIBS... " >&6; }
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${tdbc_STUB_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+
+ vars="\"`${CYGPATH} ${tdbc_STUB_LIB_PATH}`\""
+ 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
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using tdbc_STUB_LIB_PATH ${tdbc_STUB_LIB_PATH}" >&5
+$as_echo "using tdbc_STUB_LIB_PATH ${tdbc_STUB_LIB_PATH}" >&6; }
+ else
+
+ vars="${tdbc_STUB_LIB_SPEC}"
+ 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
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using tdbc_STUB_LIB_SPEC ${tdbc_STUB_LIB_SPEC}" >&5
+$as_echo "using tdbc_STUB_LIB_SPEC ${tdbc_STUB_LIB_SPEC}" >&6; }
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
+$as_echo "file not found" >&6; }
+ fi
+
+fi
+
+fi
+
+# The next bit probably ought to be in TEA_LOAD_CONFIG
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Looking for \"${tdbc_BIN_DIR}/Makefile\"" >&5
+$as_echo "$as_me: WARNING: Looking for \"${tdbc_BIN_DIR}/Makefile\"" >&2;}
+if test -f "${tdbc_BIN_DIR}/Makefile" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found Makefile - using build include spec and lib specs for tdbc" >&5
+$as_echo "$as_me: WARNING: Found Makefile - using build include spec and lib specs for tdbc" >&2;}
+ tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
+ tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH}
+fi
+
+
+
+
+
+#-----------------------------------------------------------------------
+# 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.
+#-----------------------------------------------------------------------
+
+#TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+#TEA_ADD_SOURCES([])
+#TEA_ADD_HEADERS([])
+#TEA_ADD_INCLUDES([])
+#TEA_ADD_LIBS([])
+#TEA_ADD_CFLAGS([])
+#TEA_ADD_STUB_SOURCES([])
+
+ vars="library/tdbcsqlite3.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__
+#
+# You can add more files to clean if your extension creates any extra
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
+#
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
+#--------------------------------------------------------------------
+
+#TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+
+ # 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.
+#--------------------------------------------------------------------
+
+#TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects. This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+#TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+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} ${CFLAGS} ${LDFLAGS} -shared'
+ { $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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
+ 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
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
+ 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"
+ CFLAGS_OPTIMIZE="-O2"
+ 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} ${SHLIB_CFLAGS} -shared'
+ 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
+ ;;
+ DragonFly-*|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_*|MINGW64_*) ;;
+ IRIX*) ;;
+ NetBSD-*|DragonFly-*|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
+
+# 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
+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
+
+
+
+
+ { $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
+
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library. It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+#TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+
+ { $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
+
+#--------------------------------------------------------------------
+# Substitute variables needed for .tm install.
+#--------------------------------------------------------------------
+
+
+
+
+
+#--------------------------------------------------------------------
+# 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 the 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 tdbcsqlite3 $as_me 1.1.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="\\
+tdbcsqlite3 config.status 1.1.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 = ""
+
+}
+{
+ 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
+
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure.ac b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure.ac
new file mode 100644
index 0000000..816ef87
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/configure.ac
@@ -0,0 +1,202 @@
+#!/bin/bash -norc
+dnl This file is an input file used by the GNU "autoconf" program to
+dnl generate the file "configure", which is run during Tcl installation
+dnl to configure the system for the local environment.
+
+#-----------------------------------------------------------------------
+# Sample configure.ac for Tcl Extensions. The only places you should
+# need to modify this file are marked by the string __CHANGE__
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Set your package name and version numbers here.
+#
+# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
+# set as provided. These will also be added as -D defs in your Makefile
+# so you can encode the package version directly into the source files.
+# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
+# so that we create the export library with the dll.
+#-----------------------------------------------------------------------
+
+AC_INIT([tdbcsqlite3], [1.1.0])
+
+#--------------------------------------------------------------------
+# Call TEA_INIT as the first TEA_ macro to set up initial vars.
+# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
+# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
+#--------------------------------------------------------------------
+
+TEA_INIT()
+
+AC_CONFIG_AUX_DIR(tclconfig)
+
+#--------------------------------------------------------------------
+# Load the tclConfig.sh file
+#--------------------------------------------------------------------
+
+TEA_PATH_TCLCONFIG
+TEA_LOAD_TCLCONFIG
+
+#--------------------------------------------------------------------
+# Load the tkConfig.sh file if necessary (Tk extension)
+#--------------------------------------------------------------------
+
+#TEA_PATH_TKCONFIG
+#TEA_LOAD_TKCONFIG
+
+#----------------------------------------------------------------------
+# Load the tdbcConfig.sh file
+#----------------------------------------------------------------------
+
+TEA_PATH_CONFIG(tdbc)
+TEA_LOAD_CONFIG(tdbc)
+# The next bit probably ought to be in TEA_LOAD_CONFIG
+AC_MSG_WARN([Looking for "${tdbc_BIN_DIR}/Makefile"])
+if test -f "${tdbc_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build include spec and lib specs for tdbc])
+ tdbc_INCLUDE_SPEC=${tdbc_BUILD_INCLUDE_SPEC}
+ tdbc_LIBRARY_PATH=${tdbc_BUILD_LIBRARY_PATH}
+fi
+AC_SUBST(tdbc_LIBRARY_PATH)
+AC_SUBST(TDBC_VERSION)
+AC_SUBST(tdbc_BIN_DIR)
+AC_SUBST(TDBC_LIB_FILE)
+
+#-----------------------------------------------------------------------
+# Handle the --prefix=... option by defaulting to what Tcl gave.
+# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
+#-----------------------------------------------------------------------
+
+TEA_PREFIX
+
+#-----------------------------------------------------------------------
+# Standard compiler checks.
+# This sets up CC by using the CC env var, or looks for gcc otherwise.
+# This also calls AC_PROG_CC and a few others to create the basic setup
+# necessary to compile executables.
+#-----------------------------------------------------------------------
+
+#TEA_SETUP_COMPILER
+
+#-----------------------------------------------------------------------
+# __CHANGE__
+# Specify the C source files to compile in TEA_ADD_SOURCES,
+# public headers that need to be installed in TEA_ADD_HEADERS,
+# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
+# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
+# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
+# and PKG_TCL_SOURCES.
+#-----------------------------------------------------------------------
+
+#TEA_ADD_SOURCES([])
+#TEA_ADD_HEADERS([])
+#TEA_ADD_INCLUDES([])
+#TEA_ADD_LIBS([])
+#TEA_ADD_CFLAGS([])
+#TEA_ADD_STUB_SOURCES([])
+TEA_ADD_TCL_SOURCES([library/tdbcsqlite3.tcl])
+
+#--------------------------------------------------------------------
+# __CHANGE__
+#
+# You can add more files to clean if your extension creates any extra
+# files by extending CLEANFILES.
+# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
+# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
+#
+# A few miscellaneous platform-specific items:
+# TEA_ADD_* any platform specific compiler/build info here.
+#--------------------------------------------------------------------
+
+#CLEANFILES="$CLEANFILES pkgIndex.tcl"
+if test "${TEA_PLATFORM}" = "windows" ; then
+ # Ensure no empty if clauses
+ :
+ #TEA_ADD_SOURCES([win/winFile.c])
+ #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
+else
+ # Ensure no empty else clauses
+ :
+ #TEA_ADD_SOURCES([unix/unixFile.c])
+ #TEA_ADD_LIBS([-lsuperfly])
+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
+#--------------------------------------------------------------------
+
+#TEA_PUBLIC_TCL_HEADERS
+#TEA_PRIVATE_TCL_HEADERS
+
+#TEA_PUBLIC_TK_HEADERS
+#TEA_PRIVATE_TK_HEADERS
+#TEA_PATH_X
+
+#--------------------------------------------------------------------
+# Check whether --enable-threads or --disable-threads was given.
+# This auto-enables if Tcl was compiled threaded.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_THREADS
+
+#--------------------------------------------------------------------
+# The statement below defines a collection of symbols related to
+# building as a shared library instead of a static library.
+#--------------------------------------------------------------------
+
+#TEA_ENABLE_SHARED
+
+#--------------------------------------------------------------------
+# This macro figures out what flags to use with the compiler/linker
+# when building shared/static debug/optimized objects. This information
+# can be taken from the tclConfig.sh file, but this figures it all out.
+#--------------------------------------------------------------------
+
+#TEA_CONFIG_CFLAGS
+
+#--------------------------------------------------------------------
+# Set the default compiler switches based on the --enable-symbols option.
+#--------------------------------------------------------------------
+
+TEA_ENABLE_SYMBOLS
+
+#--------------------------------------------------------------------
+# This macro generates a line to use when building a library. It
+# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
+# and TEA_LOAD_TCLCONFIG macros above.
+#--------------------------------------------------------------------
+
+#TEA_MAKE_LIB
+
+#--------------------------------------------------------------------
+# Determine the name of the tclsh and/or wish executables in the
+# Tcl and Tk build directories or the location they were installed
+# into. These paths are used to support running test cases only,
+# the Makefile should not be making use of these paths to generate
+# a pkgIndex.tcl file or anything else at extension build time.
+#--------------------------------------------------------------------
+
+TEA_PROG_TCLSH
+#TEA_PROG_WISH
+
+#--------------------------------------------------------------------
+# Substitute variables needed for .tm install.
+#--------------------------------------------------------------------
+
+AC_SUBST(TCL_VERSION)
+AC_SUBST(TCL_MAJOR_VERSION)
+AC_SUBST(TCL_MINOR_VERSION)
+
+#--------------------------------------------------------------------
+# 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 the AC variables in. Include these here.
+#--------------------------------------------------------------------
+
+AC_OUTPUT([Makefile pkgIndex.tcl])
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/doc/tdbc_sqlite3.n b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/doc/tdbc_sqlite3.n
index d105e41..d105e41 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/doc/tdbc_sqlite3.n
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/doc/tdbc_sqlite3.n
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/library/tdbcsqlite3.tcl b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/library/tdbcsqlite3.tcl
index 48f95f2..e265f79 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/library/tdbcsqlite3.tcl
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/library/tdbcsqlite3.tcl
@@ -13,7 +13,7 @@
package require tdbc
package require sqlite3
-package provide tdbc::sqlite3 1.0.6
+package provide tdbc::sqlite3 1.1.0
namespace eval tdbc::sqlite3 {
namespace export connection
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/license.terms b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/license.terms
index af33abc..af33abc 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/license.terms
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/license.terms
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/pkgIndex.tcl.in b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/pkgIndex.tcl.in
index f10a143..1bacea4 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/pkgIndex.tcl.in
@@ -1,5 +1,4 @@
-#
-# Tcl package index file
-#
+# Index file to load the TDBC SQLite3 package.
+
package ifneeded tdbc::sqlite3 @PACKAGE_VERSION@ \
[list source [file join $dir .. library tdbcsqlite3.tcl]]
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/README.txt b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension. For more information on TEA see:
+
+ http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+ http://tcl.sourceforge.net/
+
+This package is a freely available open source package. You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt This file
+
+install-sh Program used for copying binaries and script files
+ to their install locations.
+
+tcl.m4 Collection of Tcl autoconf macros. Included by a package's
+ aclocal.m4 to define TEA_* macros.
diff --git a/tcl8.6/pkgs/sqlite3.21.0/tclconfig/install-sh b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/sqlite3.21.0/tclconfig/install-sh
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/tcl.m4 b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/tcl.m4
new file mode 100644
index 0000000..2ec82a2
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tclconfig/tcl.m4
@@ -0,0 +1,4184 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+# 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
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig="${withval}")
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 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/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/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
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig="${withval}")
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+ else
+ no_tk=
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_PATCH_LEVEL)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ AC_MSG_CHECKING([platform])
+ hold_cc=$CC; CC="$TCL_CC"
+ AC_TRY_COMPILE(,[
+ #ifdef _WIN32
+ #error win32
+ #endif
+ ], [
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+ ], [
+ TEA_PLATFORM="windows"
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
+ )
+ CC=$hold_cc
+ AC_MSG_RESULT($TEA_PLATFORM)
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+ AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+ [Building extension source?])
+ # 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:
+ AC_SUBST(CLEANFILES)
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FLAG)
+ AC_SUBST(TK_LIB_SPEC)
+
+ AC_SUBST(TK_STUB_LIB_FILE)
+ AC_SUBST(TK_STUB_LIB_FLAG)
+ AC_SUBST(TK_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+# --enable-stubs=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+# 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)]),
+ [shared_ok=$enableval], [shared_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ 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
+
+ # 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, [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)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol defaults to
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $PACKAGE_VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${PACKAGE_VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # 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
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+ ], [
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+ ])
+ AC_CHECK_TOOL(AR, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
+ 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
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[[4-9]]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+ TEA_ADD_LIBS([ucrt.lib])
+ ;;
+ *)
+ ;;
+ 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
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ 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
+ AC_CHECK_TOOL(RC, windres)
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ AC_CACHE_CHECK(for cross-compile version of gcc,
+ ac_cv_cross,
+ AC_TRY_COMPILE([
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+ ], [],
+ ac_cv_cross=yes,
+ ac_cv_cross=no)
+ )
+ 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-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+ ], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+ ])
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ 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.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ 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} ${CFLAGS} ${LDFLAGS} -shared'
+ AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ ])
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ CFLAGS_OPTIMIZE="-O2"
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+ ])
+ # 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} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ;;
+ DragonFly-*|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=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+ 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}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and 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:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ tcl_cv_cc_visibility_hidden=yes
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+ tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+ tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done])
+ ])
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ ], [
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+ ])
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ 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.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # 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.
+
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
+ IRIX*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [extern],
+ [No Compiler support for module scope symbols])
+ ])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+ AC_TRY_RUN([
+#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;
+ }
+ ],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+ )
+ if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH, 1,
+ [Defined when mingw does not support SEH])
+ 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.
+ #
+ AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+ tcl_cv_eh_disposition,
+ AC_TRY_COMPILE([
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+ ],[
+ EXCEPTION_DISPOSITION x;
+ ],
+ tcl_cv_eh_disposition=yes,
+ tcl_cv_eh_disposition=no)
+ )
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+ AC_DEFINE(EXCEPTION_DISPOSITION, int,
+ [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+ 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.
+
+ AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+ tcl_cv_winnt_ignore_void,
+ AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+ ], [
+ CHAR c;
+ SHORT s;
+ LONG l;
+ ],
+ tcl_cv_winnt_ignore_void=yes,
+ tcl_cv_winnt_ignore_void=no)
+ )
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+ [Defined when cygwin/mingw ignores VOID define in winnt.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.
+
+ AC_CACHE_CHECK(for cast to union support,
+ tcl_cv_cast_to_union,
+ AC_TRY_COMPILE([],
+ [
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+ ],
+ tcl_cv_cast_to_union=yes,
+ tcl_cv_cast_to_union=no)
+ )
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+ AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+ [Defined when compiler supports casting to union type.])
+ fi
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# Locate the X11 header files and the X11 library archive. Try
+# the ac_path_x macro first, but if it doesn't find the X stuff
+# (e.g. because there's no xmkmf program) then check through
+# a list of possible directories. Under some conditions the
+# autoconf macro will return an include directory that contains
+# no include files, so double-check its result just to be safe.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Xlib.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Xlib.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test "$found_xincludes" = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" (provided by Tcl) that corrects the error.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ TEA_VERSION="3.13"
+
+ AC_MSG_CHECKING([TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.ac])
+ fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+
+ # 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_*|*MINGW64_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ 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
+
+ AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
+ i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+# Specify one or more CLEANFILES.
+#
+# Arguments:
+# one or more file names to clean target
+#
+# Results:
+#
+# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+ CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ AC_PROG_CC
+ AC_PROG_CPP
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_CHECK_TOOL(RANLIB, ranlib)
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ AC_CACHE_CHECK([if the compiler understands -pipe],
+ tcl_cv_cc_pipe, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+ ], [
+ # 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}"
+ TEA_ADD_CLEANFILES([*.manifest])
+ ])
+ 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
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+ AC_SUBST(VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(VC_MANIFEST_EMBED_EXE)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tcl<Plat>Port.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tk<Plat>Port.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ fi
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+ $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ AS_IF([test "x$2" = x], [
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+ [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+ [TEA_LOAD_CONFIG_LIB($1_STUB)])
+ ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+# Helper function to load correct library from another extension's
+# ${PACKAGE}Config.sh.
+#
+# Results:
+# Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+ AC_MSG_CHECKING([For $1 library for LIBS])
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${$1_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+ TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+ AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+ else
+ TEA_ADD_LIBS([${$1_LIB_SPEC}])
+ AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+ fi
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+# Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1
+#
+# Results:
+# Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+ #--------------------------------------------------------------------
+ # These are for $1Config.sh
+ #--------------------------------------------------------------------
+
+ # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+ eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+ if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+ else
+ eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ fi
+ $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
+ $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
+ $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
+ $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
+
+ AC_SUBST($1_BUILD_LIB_SPEC)
+ AC_SUBST($1_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_PATH)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ AC_SUBST(MAJOR_VERSION)
+ AC_SUBST(MINOR_VERSION)
+ AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
+###
+# Tip 430 - ZipFS Modifications
+###
+#------------------------------------------------------------------------
+# SC_ZIPFS_SUPPORT
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+# TCL_ZIPFS_FLAG
+# ZIP_PROG
+#------------------------------------------------------------------------
+
+#------------------------------------------------------------------------
+# SC_PROG_ZIP
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# ZIP_PROG
+# ZIP_PROG_OPTIONS
+# ZIP_PROG_VFSSEARCH
+# ZIP_INSTALL_OBJS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ZIPFS_SUPPORT], [
+ AC_MSG_CHECKING([for zipfs support])
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ INSTALL_MSGS=""
+ # If our native tclsh processes the "install" command line option
+ # we can use it to mint zip files
+ AS_IF([$TCLSH_PROG install],[
+ ZIP_PROG=${TCLSH_PROG}
+ ZIP_PROG_OPTIONS="install mkzip"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
+ ])
+ if test "x$ZIP_PROG" = "x" ; then
+ AC_CACHE_VAL(ac_cv_path_zip, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip "
+ AC_MSG_RESULT([$ZIP_PROG])
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Found INFO Zip in environment])
+ # Use standard arguments for zip
+ fi
+ fi
+ if test "x$ZIP_PROG" = "x" ; then
+ # It is not an error if an installed version of Zip can't be located.
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ else
+ # ZIPFS Support
+ eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
+ if test ${TCL_ZIP_FILE} = "" ; then
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ INSTALL_LIBRARIES=install-libraries
+ INSTALL_MSGS=install-msgs
+ else
+ if test ${SHARED_BUILD} = 1 ; then
+ TCL_ZIPFS_SUPPORT=1
+ INSTALL_LIBRARIES=install-libraries-zipfs-shared
+ else
+ TCL_ZIPFS_SUPPORT=2
+ INSTALL_LIBRARIES=install-libraries-zipfs-static
+ fi
+ TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
+ fi
+ fi
+
+ AC_SUBST(TCL_ZIP_FILE)
+ AC_SUBST(TCL_ZIPFS_SUPPORT)
+ AC_SUBST(TCL_ZIPFS_FLAG)
+ AC_SUBST(ZIP_PROG)
+ AC_SUBST(ZIP_PROG_OPTIONS)
+ AC_SUBST(ZIP_PROG_VFSSEARCH)
+ AC_SUBST(INSTALL_LIBRARIES)
+ AC_SUBST(INSTALL_MSGS)
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/all.tcl b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/all.tcl
index a4728d8..a4728d8 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/all.tcl
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/all.tcl
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/tdbcsqlite3.test b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/tdbcsqlite3.test
index a5b5615..a5b5615 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/tests/tdbcsqlite3.test
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/tests/tdbcsqlite3.test
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/makefile.vc b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/makefile.vc
index ea9ad94..9db52ae 100644
--- a/tcl8.6/pkgs/tdbcsqlite3-1.0.6/win/makefile.vc
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/makefile.vc
@@ -1,42 +1,42 @@
-#------------------------------------------------------------- -*- makefile -*-
-#
-# Makefile for TBDC Sqlite3 interface
-#
-# Basic test and install
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
-# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
-#
-# For other build options (debug, static etc.)
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-#------------------------------------------------------------------------------
-
-PROJECT = tdbcsqlite3
-!include "rules-ext.vc"
-
-# Pure Tcl extension, no object files
-PRJ_OBJS =
-
-TM_INSTALL_DIR = $(_INSTALLDIR)\tcl$(TCL_MAJOR_VERSION)\$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-
-$(PROJECT):
- @echo "This is a pure Tcl module and does not require a build step. Do a nmake install to install"
-setup: default-setup
-install: install-tm default-install-docs-n
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-
-install-tm:
- @echo Installing 'tdbcsqlite3.tcl' file to '$(TM_INSTALL_DIR)\tdbc\sqlite3-$(DOTVERSION).tm'
- @if not exist "$(TM_INSTALL_DIR)\tdbc" mkdir "$(TM_INSTALL_DIR)\tdbc"
- @if exist $(LIBDIR) $(COPY) $(LIBDIR)\tdbcsqlite3.tcl "$(TM_INSTALL_DIR)\tdbc\sqlite3-$(DOTVERSION).tm"
-
-test: default-test
-
-shell: default-shell
+#------------------------------------------------------------- -*- makefile -*-
+#
+# Makefile for TBDC Sqlite3 interface
+#
+# Basic test and install
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source test
+# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\installdir TCLDIR=c:\path\to\tcl\source install
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#------------------------------------------------------------------------------
+
+PROJECT = tdbcsqlite3
+!include "rules-ext.vc"
+
+# Pure Tcl extension, no object files
+PRJ_OBJS =
+
+TM_INSTALL_DIR = $(_INSTALLDIR)\tcl$(TCL_MAJOR_VERSION)\$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+
+$(PROJECT):
+ @echo "This is a pure Tcl module and does not require a build step. Do a nmake install to install"
+setup: default-setup
+install: install-tm default-install-docs-n
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+
+install-tm:
+ @echo Installing 'tdbcsqlite3.tcl' file to '$(TM_INSTALL_DIR)\tdbc\sqlite3-$(DOTVERSION).tm'
+ @if not exist "$(TM_INSTALL_DIR)\tdbc" mkdir "$(TM_INSTALL_DIR)\tdbc"
+ @if exist $(LIBDIR) $(COPY) $(LIBDIR)\tdbcsqlite3.tcl "$(TM_INSTALL_DIR)\tdbc\sqlite3-$(DOTVERSION).tm"
+
+test: default-test
+
+shell: default-shell
diff --git a/tcl8.6/pkgs/tdbc1.0.6/win/nmakehlp.c b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/nmakehlp.c
index 025bb99..025bb99 100644
--- a/tcl8.6/pkgs/tdbc1.0.6/win/nmakehlp.c
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/nmakehlp.c
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules-ext.vc b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules-ext.vc
new file mode 100644
index 0000000..58c70fa
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules-ext.vc
@@ -0,0 +1,118 @@
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!ifdef TCLDIR
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
+!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/tdbcodbc1.0.6/win/rules.vc b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules.vc
index bbb412d..7fc51c1 100644
--- a/tcl8.6/pkgs/tdbcodbc1.0.6/win/rules.vc
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/rules.vc
@@ -1,1723 +1,1723 @@
-#------------------------------------------------------------- -*- makefile -*-
-# rules.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file does all the hard work in terms of parsing build options,
-# compiler switches, defining common targets and macros. The Tcl makefile
-# directly includes this. Extensions include it via "rules-ext.vc".
-#
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
-# detailed documentation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-#
-# Copyright (c) 2001-2003 David Gravereaux.
-# Copyright (c) 2003-2008 Patrick Thoyts
-# Copyright (c) 2017 Ashok P. Nadkarni
-#------------------------------------------------------------------------------
-
-!ifndef _RULES_VC
-_RULES_VC = 1
-
-# The following macros define the version of the rules.vc nmake build system
-# For modifications that are not backward-compatible, you *must* change
-# the major version.
-RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
-
-# The PROJECT macro must be defined by parent makefile.
-!if "$(PROJECT)" == ""
-!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
-!endif
-
-!if "$(PRJ_PACKAGE_TCLNAME)" == ""
-PRJ_PACKAGE_TCLNAME = $(PROJECT)
-!endif
-
-# Also special case Tcl and Tk to save some typing later
-DOING_TCL = 0
-DOING_TK = 0
-!if "$(PROJECT)" == "tcl"
-DOING_TCL = 1
-!elseif "$(PROJECT)" == "tk"
-DOING_TK = 1
-!endif
-
-!ifndef NEED_TK
-# Backwards compatibility
-!ifdef PROJECT_REQUIRES_TK
-NEED_TK = $(PROJECT_REQUIRES_TK)
-!else
-NEED_TK = 0
-!endif
-!endif
-
-!ifndef NEED_TCL_SOURCE
-NEED_TCL_SOURCE = 0
-!endif
-
-!ifdef NEED_TK_SOURCE
-!if $(NEED_TK_SOURCE)
-NEED_TK = 1
-!endif
-!else
-NEED_TK_SOURCE = 0
-!endif
-
-################################################################
-# Nmake is a pretty weak environment in syntax and capabilities
-# so this file is necessarily verbose. It's broken down into
-# the following parts.
-#
-# 0. Sanity check that compiler environment is set up and initialize
-# any built-in settings from the parent makefile
-# 1. First define the external tools used for compiling, copying etc.
-# as this is independent of everything else.
-# 2. Figure out our build structure in terms of the directory, whether
-# we are building Tcl or an extension, etc.
-# 3. Determine the compiler and linker versions
-# 4. Build the nmakehlp helper application
-# 5. Determine the supported compiler options and features
-# 6. Parse the OPTS macro value for user-specified build configuration
-# 7. Parse the STATS macro value for statistics instrumentation
-# 8. Parse the CHECKS macro for additional compilation checks
-# 9. Extract Tcl, and possibly Tk, version numbers from the headers
-# 10. Based on this selected configuration, construct the output
-# directory and file paths
-# 11. Construct the paths where the package is to be installed
-# 12. Set up the actual options passed to compiler and linker based
-# on the information gathered above.
-# 13. Define some standard build targets and implicit rules. These may
-# be optionally disabled by the parent makefile.
-# 14. (For extensions only.) Compare the configuration of the target
-# Tcl and the extensions and warn against discrepancies.
-#
-# One final note about the macro names used. They are as they are
-# for historical reasons. We would like legacy extensions to
-# continue to work with this make include file so be wary of
-# changing them for consistency or clarity.
-
-# 0. Sanity check compiler environment
-
-# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
-# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-Visual C++ compiler environment not initialized.
-!error $(MSG)
-!endif
-
-# We need to run from the directory the parent makefile is located in.
-# nmake does not tell us what makefile was used to invoke it so parent
-# makefile has to set the MAKEFILEVC macro or we just make a guess and
-# warn if we think that is not the case.
-!if "$(MAKEFILEVC)" == ""
-
-!if exist("$(PROJECT).vc")
-MAKEFILEVC = $(PROJECT).vc
-!elseif exist("makefile.vc")
-MAKEFILEVC = makefile.vc
-!endif
-!endif # "$(MAKEFILEVC)" == ""
-
-!if !exist("$(MAKEFILEVC)")
-MSG = ^
-You must run nmake from the directory containing the project makefile.^
-If you are doing that and getting this message, set the MAKEFILEVC^
-macro to the name of the project makefile.
-!message WARNING: $(MSG)
-!endif
-
-
-################################################################
-# 1. Define external programs being used
-
-#----------------------------------------------------------
-# Set the proper copy method to avoid overwrite questions
-# to the user when copying files and selecting the right
-# "delete all" method.
-#----------------------------------------------------------
-
-RMDIR = rmdir /S /Q
-CPY = xcopy /i /y >NUL
-CPYDIR = xcopy /e /i /y >NUL
-COPY = copy /y >NUL
-MKDIR = mkdir
-
-######################################################################
-# 2. Figure out our build environment in terms of what we're building.
-#
-# (a) Tcl itself
-# (b) Tk
-# (c) a Tcl extension using libraries/includes from an *installed* Tcl
-# (d) a Tcl extension using libraries/includes from Tcl source directory
-#
-# This last is needed because some extensions still need
-# some Tcl interfaces that are not publicly exposed.
-#
-# The fragment will set the following macros:
-# ROOT - root of this module sources
-# COMPATDIR - source directory that holds compatibility sources
-# DOCDIR - source directory containing documentation files
-# GENERICDIR - platform-independent source directory
-# WINDIR - Windows-specific source directory
-# TESTDIR - directory containing test files
-# TOOLSDIR - directory containing build tools
-# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
-# when building Tcl itself.
-# _INSTALLDIR - native form of the installation path. For Tcl
-# this will be the root of the Tcl installation. For extensions
-# this will be the lib directory under the root.
-# TCLINSTALL - set to 1 if _TCLDIR refers to
-# headers and libraries from an installed Tcl, and 0 if built against
-# Tcl sources. Not set when building Tcl itself. Yes, not very well
-# named.
-# _TCL_H - native path to the tcl.h file
-#
-# If Tk is involved, also sets the following
-# _TKDIR - native form Tk installation OR Tk source. Not set if building
-# Tk itself.
-# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
-# _TK_H - native path to the tk.h file
-
-# Root directory for sources and assumed subdirectories
-ROOT = $(MAKEDIR)\..
-# The following paths CANNOT have spaces in them as they appear on the
-# left side of implicit rules.
-!ifndef COMPATDIR
-COMPATDIR = $(ROOT)\compat
-!endif
-!ifndef DOCDIR
-DOCDIR = $(ROOT)\doc
-!endif
-!ifndef GENERICDIR
-GENERICDIR = $(ROOT)\generic
-!endif
-!ifndef TOOLSDIR
-TOOLSDIR = $(ROOT)\tools
-!endif
-!ifndef TESTDIR
-TESTDIR = $(ROOT)\tests
-!endif
-!ifndef LIBDIR
-!if exist("$(ROOT)\library")
-LIBDIR = $(ROOT)\library
-!else
-LIBDIR = $(ROOT)\lib
-!endif
-!endif
-!ifndef DEMODIR
-!if exist("$(LIBDIR)\demos")
-DEMODIR = $(LIBDIR)\demos
-!else
-DEMODIR = $(ROOT)\demos
-!endif
-!endif # ifndef DEMODIR
-# Do NOT enclose WINDIR in a !ifndef because Windows always defines
-# WINDIR env var to point to c:\windows!
-# TBD - This is a potentially dangerous conflict, rename WINDIR to
-# something else
-WINDIR = $(ROOT)\win
-
-!ifndef RCDIR
-!if exist("$(WINDIR)\rc")
-RCDIR = $(WINDIR)\rc
-!else
-RCDIR = $(WINDIR)
-!endif
-!endif
-RCDIR = $(RCDIR:/=\)
-
-# The target directory where the built packages and binaries will be installed.
-# INSTALLDIR is the (optional) path specified by the user.
-# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
-!ifdef INSTALLDIR
-### Fix the path separators.
-_INSTALLDIR = $(INSTALLDIR:/=\)
-!else
-### Assume the normal default.
-_INSTALLDIR = $(HOMEDRIVE)\Tcl
-!endif
-
-!if $(DOING_TCL)
-
-# BEGIN Case 2(a) - Building Tcl itself
-
-# Only need to define _TCL_H
-_TCL_H = ..\generic\tcl.h
-
-# END Case 2(a) - Building Tcl itself
-
-!elseif $(DOING_TK)
-
-# BEGIN Case 2(b) - Building Tk
-
-TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
-!if "$(TCLDIR)" == ""
-!if [echo TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-!endif # TCLDIR == ""
-
-_TCLDIR = $(TCLDIR:/=\)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!if !exist("$(_TCL_H)")
-!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
-!endif
-
-_TK_H = ..\generic\tk.h
-
-# END Case 2(b) - Building Tk
-
-!else
-
-# BEGIN Case 2(c) or (d) - Building an extension other than Tk
-
-# If command line has specified Tcl location through TCLDIR, use it
-# else default to the INSTALLDIR setting
-!if "$(TCLDIR)" != ""
-
-_TCLDIR = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
-TCLINSTALL = 1
-_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
-TCLINSTALL = 0
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
-
-!else # # Case 2(c) for extensions with TCLDIR undefined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-
-TCLINSTALL = 1
-TCLDIR = $(_INSTALLDIR)\..
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TCLDIR = $(_INSTALLDIR)\..
-_TCL_H = $(_TCLDIR)\include\tcl.h
-
-!else # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!if [echo _TCLDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
-!error *** Could not locate Tcl source directory.
-!endif
-!include nmakehlp.out
-TCLINSTALL = 0
-TCLDIR = $(_TCLDIR)
-_TCL_H = $(_TCLDIR)\generic\tcl.h
-
-!endif # exist(...) && ! $(NEED_TCL_SOURCE)
-
-!endif # TCLDIR
-
-!ifndef _TCL_H
-MSG =^
-Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
-!error $(MSG)
-!endif
-
-# Now do the same to locate Tk headers and libs if project requires Tk
-!if $(NEED_TK)
-
-!if "$(TKDIR)" != ""
-
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL = 1
-_TK_H = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL = 0
-_TK_H = $(_TKDIR)\generic\tk.h
-!endif
-
-!else # TKDIR not defined
-
-# Need to locate Tcl depending on whether it needs Tcl source or not.
-# If we don't, check the INSTALLDIR for an installed Tcl first
-
-!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-TKINSTALL = 1
-# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
-# later so the \.. accounts for the /lib
-_TKDIR = $(_INSTALLDIR)\..
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
-
-!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!if [echo _TKDIR = \> nmakehlp.out] \
- || [nmakehlp -L generic\tk.h >> nmakehlp.out]
-!error *** Could not locate Tk source directory.
-!endif
-!include nmakehlp.out
-TKINSTALL = 0
-TKDIR = $(_TKDIR)
-_TK_H = $(_TKDIR)\generic\tk.h
-
-!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
-
-!endif # TKDIR
-
-!ifndef _TK_H
-MSG =^
-Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
-!error $(MSG)
-!endif
-
-!endif # NEED_TK
-
-!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tcl.^
-*** Please set the TCLDIR macro to point to the Tcl sources.
-!error $(MSG)
-!endif
-
-!if $(NEED_TK_SOURCE)
-!if $(TKINSTALL)
-MSG = ^
-*** Warning: This extension requires the source distribution of Tk.^
-*** Please set the TKDIR macro to point to the Tk sources.
-!error $(MSG)
-!endif
-!endif
-
-
-# If INSTALLDIR set to tcl installation root dir then reset to the
-# lib dir for installing extensions
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
-!endif
-
-# END Case 2(c) or (d) - Building an extension
-!endif # if $(DOING_TCL)
-
-################################################################
-# 3. Determine compiler version and architecture
-# In this section, we figure out the compiler version and the
-# architecture for which we are building. This sets the
-# following macros:
-# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
-# This is also printed by the compiler in dotted form 19.10 etc.
-# VCVER - the "marketing version", for example Visual C++ 6 for internal
-# compiler version 1200. This is kept only for legacy reasons as it
-# does not make sense for recent Microsoft compilers. Only used for
-# output directory names.
-# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
-# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
-# MACHINE - same as $(ARCH) - legacy
-# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
-# CFG_ENCODING - set to an character encoding.
-# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
-# see where it is used
-
-cc32 = $(CC) # built-in default.
-link32 = link
-lib32 = lib
-rc32 = $(RC) # built-in default.
-
-#----------------------------------------------------------------
-# Figure out the compiler architecture and version by writing
-# the C macros to a file, preprocessing them with the C
-# preprocessor and reading back the created file
-
-_HASH=^#
-_VC_MANIFEST_EMBED_EXE=
-_VC_MANIFEST_EMBED_DLL=
-VCVER=0
-!if ![echo VCVERSION=_MSC_VER > vercl.x] \
- && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
- && ![echo ARCH=IX86 >> vercl.x] \
- && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
- && ![echo ARCH=AMD64 >> vercl.x] \
- && ![echo $(_HASH)endif >> vercl.x] \
- && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
-!include vercl.i
-!if $(VCVERSION) < 1900
-!if ![echo VCVER= ^\> vercl.vc] \
- && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
-!include vercl.vc
-!endif
-!else
-# The simple calculation above does not apply to new Visual Studio releases
-# Keep the compiler version in its native form.
-VCVER = $(VCVERSION)
-!endif
-!endif
-
-!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
-!endif
-
-#----------------------------------------------------------------
-# The MACHINE macro is used by legacy makefiles so set it as well
-!ifdef MACHINE
-!if "$(MACHINE)" == "x86"
-!undef MACHINE
-MACHINE = IX86
-!elseif "$(MACHINE)" == "x64"
-!undef MACHINE
-MACHINE = AMD64
-!endif
-!if "$(MACHINE)" != "$(ARCH)"
-!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
-!endif
-!else
-MACHINE=$(ARCH)
-!endif
-
-#------------------------------------------------------------
-# Figure out the *host* architecture by reading the registry
-
-!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
-NATIVE_ARCH=IX86
-!else
-NATIVE_ARCH=AMD64
-!endif
-
-# Since MSVC8 we must deal with manifest resources.
-!if $(VCVERSION) >= 1400
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING = \"cp1252\"
-!endif
-
-################################################################
-# 4. Build the nmakehlp program
-# This is a helper app we need to overcome nmake's limiting
-# environment. We will call out to it to get various bits of
-# information about supported compiler options etc.
-#
-# Tcl itself will always use the nmakehlp.c program which is
-# in its own source. This is the "master" copy and kept updated.
-#
-# Extensions built against an installed Tcl will use the installed
-# copy of Tcl's nmakehlp.c if there is one and their own version
-# otherwise. In the latter case, they would also be using their own
-# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
-# or rules.vc.
-#
-# Extensions built against Tcl sources will use the one from the Tcl source.
-#
-# When building an extension using a sufficiently new version of Tcl,
-# rules-ext.vc will define NMAKEHLPC appropriately to point to the
-# copy of nmakehlp.c to be used.
-
-!ifndef NMAKEHLPC
-# Default to the one in the current directory (the extension's own nmakehlp.c)
-NMAKEHLPC = nmakehlp.c
-
-!if !$(DOING_TCL)
-!if $(TCLINSTALL)
-!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
-!endif
-!else # ! $(TCLINSTALL)
-!if exist("$(_TCLDIR)\win\nmakehlp.c")
-NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
-!endif
-!endif # $(TCLINSTALL)
-!endif # !$(DOING_TCL)
-
-!endif # NMAKEHLPC
-
-# We always build nmakehlp even if it exists since we do not know
-# what source it was built from.
-!message *** Using $(NMAKEHLPC)
-!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
-!endif
-
-################################################################
-# 5. Test for compiler features
-# Visual C++ compiler options have changed over the years. Check
-# which options are supported by the compiler in use.
-#
-# The following macros are set:
-# OPTIMIZATIONS - the compiler flags to be used for optimized builds
-# DEBUGFLAGS - the compiler flags to be used for debug builds
-# LINKERFLAGS - Flags passed to the linker
-#
-# Note that these are the compiler settings *available*, not those
-# that will be *used*. The latter depends on the OPTS macro settings
-# which we have not yet parsed.
-#
-# Also note that some of the flags in OPTIMIZATIONS are not really
-# related to optimization. They are placed there only for legacy reasons
-# as some extensions expect them to be included in that macro.
-
-# -Op improves float consistency. Note only needed for older compilers
-# Newer compilers do not need or support this option.
-!if [nmakehlp -c -Op]
-FPOPTS = -Op
-!endif
-
-# Strict floating point semantics - present in newer compilers in lieu of -Op
-!if [nmakehlp -c -fp:strict]
-FPOPTS = $(FPOPTS) -fp:strict
-!endif
-
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-FPOPTS = $(FPOPTS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
-!endif
-!endif
-
-### test for optimizations
-# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
-# documentation. Note we do NOT want /Gs as that inserts a _chkstk
-# stack probe at *every* function entry, not just those with more than
-# a page of stack allocation resulting in a performance hit. However,
-# /O2 documentation is misleading as its stack probes are simply the
-# default page size locals allocation probes and not what is implied
-# by an explicit /Gs option.
-
-OPTIMIZATIONS = $(FPOPTS)
-
-!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING = 1
-OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
-!else
-# Legacy, really. All modern compilers support this
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING = 0
-!endif
-
-# Checks for buffer overflows in local arrays
-!if [nmakehlp -c -GS]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
-!endif
-
-# Link time optimization. Note that this option (potentially) makes
-# generated libraries only usable by the specific VC++ version that
-# created it. Requires /LTCG linker option
-!if [nmakehlp -c -GL]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
-CC_GL_OPT_ENABLED = 1
-!else
-# In newer compilers -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
-!endif
-!endif # [nmakehlp -c -GL]
-
-DEBUGFLAGS = $(FPOPTS)
-
-# Run time error checks. Not available or valid in a release, non-debug build
-# RTC is for modern compilers, -GZ is legacy
-!if [nmakehlp -c -RTC1]
-DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
-!elseif [nmakehlp -c -GZ]
-DEBUGFLAGS = $(DEBUGFLAGS) -GZ
-!endif
-
-#----------------------------------------------------------------
-# Linker flags
-
-# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
-# if the linker supports a specific option. Without these flags link will
-# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
-# They are not passed through to the actual application / extension
-# link rules.
-!ifndef LINKER_TESTFLAGS
-LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
-!endif
-
-LINKERFLAGS =
-
-# If compiler has enabled link time optimization, linker must too with -ltcg
-!ifdef CC_GL_OPT_ENABLED
-!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -ltcg
-!endif
-!endif
-
-########################################################################
-# 6. Parse the OPTS macro to work out the requested build configuration.
-# Based on this, we will construct the actual switches to be passed to the
-# compiler and linker using the macros defined in the previous section.
-# The following macros are defined by this section based on OPTS
-# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
-# 1 -> build as a static library and shell
-# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
-# DEBUG - 1 -> debug build, 0 -> release builds
-# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
-# PROFILE - 1 -> generate profiling info, 0 -> no profiling
-# PGO - 1 -> profile based optimization, 0 -> no
-# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
-# 0 -> link to static C runtime for static Tcl build.
-# Does not impact shared Tcl builds (STATIC_BUILD == 0)
-# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
-# in the Tcl shell. 0 -> keep them as shared libraries
-# Does not impact shared Tcl builds.
-# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
-# 0 -> Use the non-thread allocator.
-# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
-# C runtime, 0 -> use the debug C runtime.
-# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
-# CONFIG_CHECK - 1 -> check current build configuration against Tcl
-# configuration (ignored for Tcl itself)
-# Further, LINKERFLAGS are modified based on above.
-
-# Default values for all the above
-STATIC_BUILD = 0
-TCL_THREADS = 1
-DEBUG = 0
-SYMBOLS = 0
-PROFILE = 0
-PGO = 0
-MSVCRT = 1
-TCL_USE_STATIC_PACKAGES = 0
-USE_THREAD_ALLOC = 1
-UNCHECKED = 0
-CONFIG_CHECK = 1
-!if $(DOING_TCL)
-USE_STUBS = 0
-!else
-USE_STUBS = 1
-!endif
-
-# If OPTS is not empty AND does not contain "none" which turns off all OPTS
-# set the above macros based on OPTS content
-!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
-
-# OPTS are specified, parse them
-
-!if [nmakehlp -f $(OPTS) "static"]
-!message *** Doing static
-STATIC_BUILD = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "nostubs"]
-!message *** Not using stubs
-USE_STUBS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nomsvcrt"]
-!message *** Doing nomsvcrt
-MSVCRT = 0
-!else
-!if [nmakehlp -f $(OPTS) "msvcrt"]
-!message *** Doing msvcrt
-MSVCRT = 1
-!else
-!if !$(STATIC_BUILD)
-MSVCRT = 1
-!else
-MSVCRT = 0
-!endif
-!endif
-!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
-
-!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
-!message *** Doing staticpkg
-TCL_USE_STATIC_PACKAGES = 1
-!else
-TCL_USE_STATIC_PACKAGES = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "nothreads"]
-!message *** Compile explicitly for non-threaded tcl
-TCL_THREADS = 0
-USE_THREAD_ALLOC= 0
-!else
-TCL_THREADS = 1
-USE_THREAD_ALLOC= 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "symbols"]
-!message *** Doing symbols
-DEBUG = 1
-!else
-DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pdbs"]
-!message *** Doing pdbs
-SYMBOLS = 1
-!else
-SYMBOLS = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "profile"]
-!message *** Doing profile
-PROFILE = 1
-!else
-PROFILE = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "pgi"]
-!message *** Doing profile guided optimization instrumentation
-PGO = 1
-!elseif [nmakehlp -f $(OPTS) "pgo"]
-!message *** Doing profile guided optimization
-PGO = 2
-!else
-PGO = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
-!endif
-
-# TBD - should get rid of this option
-!if [nmakehlp -f $(OPTS) "thrdalloc"]
-!message *** Doing thrdalloc
-USE_THREAD_ALLOC = 1
-!endif
-
-!if [nmakehlp -f $(OPTS) "tclalloc"]
-USE_THREAD_ALLOC = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
-!endif
-
-!if [nmakehlp -f $(OPTS) "noconfigcheck"]
-CONFIG_CHECK = 1
-!else
-CONFIG_CHECK = 0
-!endif
-
-!endif # "$(OPTS)" != "" && ... parsing of OPTS
-
-# Set linker flags based on above
-
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
-!else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
-!endif
-!endif
-
-################################################################
-# 7. Parse the STATS macro to configure code instrumentation
-# The following macros are set by this section:
-# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
-# 0 -> disables
-# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
-# 0 -> disables
-
-# Default both are off
-TCL_MEM_DEBUG = 0
-TCL_COMPILE_DEBUG = 0
-
-!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
-
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG = 1
-!else
-TCL_MEM_DEBUG = 0
-!endif
-
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG = 1
-!else
-TCL_COMPILE_DEBUG = 0
-!endif
-
-!endif
-
-####################################################################
-# 8. Parse the CHECKS macro to configure additional compiler checks
-# The following macros are set by this section:
-# WARNINGS - compiler switches that control the warnings level
-# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
-# 0 -> enable deprecated functions
-
-# Defaults - Permit deprecated functions and warning level 3
-TCL_NO_DEPRECATED = 0
-WARNINGS = -W3
-
-!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
-
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED = 1
-!endif
-
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS = -W4
-!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
-LINKERFLAGS = $(LINKERFLAGS) -warn:3
-!endif
-!endif
-
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS = $(WARNINGS) -Wp64
-!endif
-
-!endif
-
-################################################################
-# 9. Extract various version numbers
-# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
-# respectively. For extensions, versions are extracted from the
-# configure.in or configure.ac from the TEA configuration if it
-# exists, and unset otherwise.
-# Sets the following macros:
-# TCL_MAJOR_VERSION
-# TCL_MINOR_VERSION
-# TCL_PATCH_LEVEL
-# TCL_VERSION
-# TK_MAJOR_VERSION
-# TK_MINOR_VERSION
-# TK_PATCH_LEVEL
-# TK_VERSION
-# DOTVERSION - set as (for example) 2.5
-# VERSION - set as (for example 25)
-#--------------------------------------------------------------
-
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
-
-!if defined(_TK_H)
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
- && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
-!endif
-!endif # _TK_H
-
-!include versions.vc
-
-TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
-TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!if defined(_TK_H)
-TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
-TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-
-# Set DOTVERSION and VERSION
-!if $(DOING_TCL)
-
-DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-VERSION = $(TCL_VERSION)
-
-!elseif $(DOING_TK)
-
-DOTVERSION = $(TK_DOTVERSION)
-VERSION = $(TK_VERSION)
-
-!else # Doing a non-Tk extension
-
-# If parent makefile has not defined DOTVERSION, try to get it from TEA
-# first from a configure.in file, and then from configure.ac
-!ifndef DOTVERSION
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
-!if [echo DOTVERSION = \> versions.vc] \
- || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
-!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
-!endif
-!endif
-!include versions.vc
-!endif # DOTVERSION
-VERSION = $(DOTVERSION:.=)
-
-!endif # $(DOING_TCL) ... etc.
-
-################################################################
-# 10. Construct output directory and file paths
-# Figure-out how to name our intermediate and output directories.
-# In order to avoid inadvertent mixing of object files built using
-# different compilers, build configurations etc.,
-#
-# Naming convention (suffixes):
-# t = full thread support.
-# s = static library (as opposed to an import library)
-# g = linked to the debug enabled C run-time.
-# x = special static build when it links to the dynamic C run-time.
-#
-# The following macros are set in this section:
-# SUFX - the suffix to use for binaries based on above naming convention
-# BUILDDIRTOP - the toplevel default output directory
-# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
-# TMP_DIR - directory where object files are created
-# OUT_DIR - directory where output executables are created
-# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
-# parent makefile (or command line). The default values are
-# based on BUILDDIRTOP.
-# STUBPREFIX - name of the stubs library for this project
-# PRJIMPLIB - output path of the generated project import library
-# PRJLIBNAME - name of generated project library
-# PRJLIB - output path of generated project library
-# PRJSTUBLIBNAME - name of the generated project stubs library
-# PRJSTUBLIB - output path of the generated project stubs library
-# RESFILE - output resource file (only if not static build)
-
-SUFX = tsgx
-
-!if $(DEBUG)
-BUILDDIRTOP = Debug
-!else
-BUILDDIRTOP = Release
-!endif
-
-!if "$(MACHINE)" != "IX86"
-BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
-!endif
-!if $(VCVER) > 6
-BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
-!endif
-
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
-SUFX = $(SUFX:g=)
-!endif
-
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
-
-!if !$(STATIC_BUILD)
-TMP_DIRFULL = $(TMP_DIRFULL:Static=)
-SUFX = $(SUFX:s=)
-EXT = dll
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!else
-TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
-EXT = lib
-!if !$(MSVCRT)
-TMP_DIRFULL = $(TMP_DIRFULL:X=)
-SUFX = $(SUFX:x=)
-!endif
-!endif
-
-!if !$(TCL_THREADS)
-TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
-SUFX = $(SUFX:t=)
-!endif
-
-!ifndef TMP_DIR
-TMP_DIR = $(TMP_DIRFULL)
-!ifndef OUT_DIR
-OUT_DIR = .\$(BUILDDIRTOP)
-!endif
-!else
-!ifndef OUT_DIR
-OUT_DIR = $(TMP_DIR)
-!endif
-!endif
-
-# Relative paths -> absolute
-!if [echo OUT_DIR = \> nmakehlp.out] \
- || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
-!endif
-!if [echo TMP_DIR = \>> nmakehlp.out] \
- || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
-!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
-!endif
-!include nmakehlp.out
-
-# The name of the stubs library for the project being built
-STUBPREFIX = $(PROJECT)stub
-
-# Set up paths to various Tcl executables and libraries needed by extensions
-!if $(DOING_TCL)
-
-TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
-TCLSH = $(OUT_DIR)\$(TCLSHNAME)
-TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
-
-TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
-TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist("$(TCLSH)") && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\lib
-TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES = -I"$(_TCLDIR)\include"
-
-!else # Building against Tcl sources
-
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
-!endif
-TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
-TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
-TCL_LIBRARY = $(_TCLDIR)\library
-TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
-TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
-TCLTOOLSDIR = $(_TCLDIR)\tools
-TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
-
-!endif # TCLINSTALL
-
-tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
-
-!endif # $(DOING_TCL)
-
-# We need a tclsh that will run on the host machine as part of the build.
-# IX86 runs on all architectures.
-!ifndef TCLSH_NATIVE
-!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
-TCLSH_NATIVE = $(TCLSH)
-!else
-!error You must explicitly set TCLSH_NATIVE for cross-compilation
-!endif
-!endif
-
-# Do the same for Tk and Tk extensions that require the Tk libraries
-!if $(DOING_TK) || $(NEED_TK)
-WISHNAMEPREFIX = wish
-WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
-TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
-TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
-TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
-
-!if $(DOING_TK)
-WISH = $(OUT_DIR)\$(WISHNAME)
-TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
-TKLIB = $(OUT_DIR)\$(TKLIBNAME)
-TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
-
-!else # effectively NEED_TK
-
-!if $(TKINSTALL) # Building against installed Tk
-WISH = $(_TKDIR)\bin\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\include"
-!else # Building against Tk sources
-WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
-TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
-TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
-TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
-!endif # TKINSTALL
-tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
-
-!endif # $(DOING_TK)
-!endif # $(DOING_TK) || $(NEED_TK)
-
-# Various output paths
-PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
-PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
-
-# If extension parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
-!ifdef RCFILE
-RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
-!else
-RESFILE = $(TMP_DIR)\$(PROJECT).res
-!endif
-!endif
-
-###################################################################
-# 11. Construct the paths for the installation directories
-# The following macros get defined in this section:
-# LIB_INSTALL_DIR - where libraries should be installed
-# BIN_INSTALL_DIR - where the executables should be installed
-# DOC_INSTALL_DIR - where documentation should be installed
-# SCRIPT_INSTALL_DIR - where scripts should be installed
-# INCLUDE_INSTALL_DIR - where C include files should be installed
-# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
-
-!if $(DOING_TCL) || $(DOING_TK)
-LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
-BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
-DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
-!if $(DOING_TCL)
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
-!else # DOING_TK
-SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-!endif
-DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
-
-!else # extension other than Tk
-
-PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
-DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
-
-!endif
-
-###################################################################
-# 12. Set up actual options to be passed to the compiler and linker
-# Now we have all the information we need, set up the actual flags and
-# options that we will pass to the compiler and linker. The main
-# makefile should use these in combination with whatever other flags
-# and switches are specific to it.
-# The following macros are defined, names are for historical compatibility:
-# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
-# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
-# crt - Compiler switch that selects the appropriate C runtime
-# cdebug - Compiler switches related to debug AND optimizations
-# cwarn - Compiler switches that set warning levels
-# cflags - complete compiler switches (subsumes cdebug and cwarn)
-# ldebug - Linker switches controlling debug information and optimization
-# lflags - complete linker switches (subsumes ldebug) except subsystem type
-# dlllflags - complete linker switches to build DLLs (subsumes lflags)
-# conlflags - complete linker switches for console program (subsumes lflags)
-# guilflags - complete linker switches for GUI program (subsumes lflags)
-# baselibs - minimum Windows libraries required. Parent makefile can
-# define PRJ_LIBS before including rules.rc if additional libs are needed
-
-OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
-
-!if $(TCL_MEM_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
-!endif
-!if $(TCL_COMPILE_DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
-!endif
-!if $(TCL_THREADS)
-OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
-!endif
-!endif
-!if $(STATIC_BUILD)
-OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
-!endif
-!if $(TCL_NO_DEPRECATED)
-OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
-!endif
-
-!if $(USE_STUBS)
-# Note we do not define USE_TCL_STUBS even when building tk since some
-# test targets in tk do not use stubs
-!if ! $(DOING_TCL)
-USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
-!if $(NEED_TK)
-USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
-!endif
-!endif
-!endif # USE_STUBS
-
-!if !$(DEBUG)
-OPTDEFINES = $(OPTDEFINES) -DNDEBUG
-!if $(OPTIMIZING)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
-!endif
-!endif
-!if $(PROFILE)
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
-!endif
-!if "$(MACHINE)" == "AMD64"
-OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
-!endif
-!if $(VCVERSION) < 1300
-OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
-!endif
-
-# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
-COMPILERFLAGS = /D_ATL_XP_TARGETING
-
-# Following is primarily for the benefit of extensions. Tcl 8.5 builds
-# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
-# an extension, it is advisable (but not mandated) to use the same Windows
-# API as the Tcl build. This is accordingly defaulted below. A particular
-# extension can override this by pre-definining USE_WIDECHAR_API.
-!ifndef USE_WIDECHAR_API
-!if $(TCL_VERSION) > 85
-USE_WIDECHAR_API = 1
-!else
-USE_WIDECHAR_API = 0
-!endif
-!endif
-
-!if $(USE_WIDECHAR_API)
-COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
-!endif
-
-# Like the TEA system only set this non empty for non-Tk extensions
-# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
-# so we pass both
-!if !$(DOING_TCL) && !$(DOING_TK)
-PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
- -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
- -DMODULE_SCOPE=extern
-!endif
-
-# crt picks the C run time based on selected OPTS
-!if $(MSVCRT)
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG) && !$(UNCHECKED)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-# cdebug includes compiler options for debugging as well as optimization.
-!if $(DEBUG)
-
-# In debugging mode, optimizations need to be disabled
-cdebug = -Zi -Od $(DEBUGFLAGS)
-
-!else
-
-cdebug = $(OPTIMIZATIONS)
-!if $(SYMBOLS)
-cdebug = $(cdebug) -Zi
-!endif
-
-!endif # $(DEBUG)
-
-# cwarn includes default warning levels.
-cwarn = $(WARNINGS)
-
-!if "$(MACHINE)" == "AMD64"
-# Disable pointer<->int warnings related to cast between different sizes
-# There are a gadzillion of these due to use of ClientData and
-# clutter up compiler
-# output increasing chance of a real warning getting lost. So disable them.
-# Eventually some day, Tcl will be 64-bit clean.
-cwarn = $(cwarn) -wd4311 -wd4312
-!endif
-
-### Common compiler options that are architecture specific
-!if "$(MACHINE)" == "ARM"
-carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
-!else
-carch =
-!endif
-
-!if $(DEBUG)
-# Turn warnings into errors
-cwarn = $(cwarn) -WX
-!endif
-
-INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
-!if !$(DOING_TCL) && !$(DOING_TK)
-INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
-!endif
-
-# These flags are defined roughly in the order of the pre-reform
-# rules.vc/makefile.vc to help visually compare that the pre- and
-# post-reform build logs
-
-# cflags contains generic flags used for building practically all object files
-cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
-
-# appcflags contains $(cflags) and flags for building the application
-# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
-# flags used for building shared object files The two differ in the
-# BUILD_$(PROJECT) macro which should be defined only for the shared
-# library *implementation* and not for its caller interface
-
-appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
-appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
-pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
-
-# stubscflags contains $(cflags) plus flags used for building a stubs
-# library for the package. Note: -DSTATIC_BUILD is defined in
-# $(OPTDEFINES) only if the OPTS configuration indicates a static
-# library. However the stubs library is ALWAYS static hence included
-# here irrespective of the OPTS setting.
-#
-# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
-# without stating why. Tcl itself compiled stubs libs with this flag.
-# so we do not remove it from cflags. -GL may prevent extensions
-# compiled with one VC version to fail to link against stubs library
-# compiled with another VC version. Check for this and fix accordingly.
-stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
-
-# Link flags
-
-!if $(DEBUG)
-ldebug = -debug -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!if $(SYMBOLS)
-ldebug = $(ldebug) -debug -debugtype:cv
-!endif
-!endif
-
-# Note: Profiling is currently only possible with the Visual Studio Enterprise
-!if $(PROFILE)
-ldebug= $(ldebug) -profile
-!endif
-
-### Declarations common to all linker versions
-lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-lflags = $(lflags) -nodefaultlib:libucrt.lib
-!endif
-
-# Old linkers (Visual C++ 6 in particular) will link for fast loading
-# on Win98. Since we do not support Win98 any more, we specify nowin98
-# as recommended for NT and later. However, this is only required by
-# IX86 on older compilers and only needed if we are not doing a static build.
-
-!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
-!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
-# Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!endif
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-
-# Libraries that are required for every image.
-# Extensions should define any additional libraries with $(PRJ_LIBS)
-winlibs = kernel32.lib advapi32.lib
-
-!if $(NEED_TK)
-winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
-!endif
-
-# Avoid 'unresolved external symbol __security_cookie' errors.
-# c.f. http://support.microsoft.com/?id=894573
-!if "$(MACHINE)" == "AMD64"
-!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
-winlibs = $(winlibs) bufferoverflowU.lib
-!endif
-!endif
-
-baselibs = $(winlibs) $(PRJ_LIBS)
-
-!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
-baselibs = $(baselibs) ucrt.lib
-!endif
-
-################################################################
-# 13. Define standard commands, common make targets and implicit rules
-
-CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
-CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
-CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
-
-LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
-DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-
-CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
-RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
- $(TCL_INCLUDES) \
- -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
- -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
- -DDOTVERSION=\"$(DOTVERSION)\" \
- -DVERSION=\"$(VERSION)\" \
- -DSUFX=\"$(SUFX)\" \
- -DPROJECT=\"$(PROJECT)\" \
- -DPRJLIBNAME=\"$(PRJLIBNAME)\"
-
-!ifndef DEFAULT_BUILD_TARGET
-DEFAULT_BUILD_TARGET = $(PROJECT)
-!endif
-
-default-target: $(DEFAULT_BUILD_TARGET)
-
-default-pkgindex:
- @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
- [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
-
-default-pkgindex-tea:
- @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
-@PACKAGE_VERSION@ $(DOTVERSION)
-@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
-@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
-@PKG_LIB_FILE@ $(PRJLIBNAME)
-<<
-
-
-default-install: default-install-binaries default-install-libraries
-
-default-install-binaries: $(PRJLIB)
- @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
- @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
- @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
- @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
- @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
-
-default-install-stubs:
- @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
- @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
- @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-default-install-docs-html:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-docs-n:
- @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
- @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
- @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
-
-default-install-demos:
- @echo Installing demos to '$(DEMO_INSTALL_DIR)'
- @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
- @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
-
-default-clean:
- @echo Cleaning $(TMP_DIR)\* ...
- @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
- @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
- @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
- @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
- @echo Cleaning $(WINDIR)\_junk.pch ...
- @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
- @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
- @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
- @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
- @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
- @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
- @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-default-hose: default-clean
- @echo Hosing $(OUT_DIR)\* ...
- @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-# Only for backward compatibility
-default-distclean: default-hose
-
-default-setup:
- @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
- @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-!if "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!endif
-
-default-test: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
-
-default-shell: default-setup $(PROJECT)
- @set TCLLIBPATH=$(OUT_DIR:\=/)
- @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
- $(DEBUGGER) $(TCLSH)
-
-# Generation of Windows version resource
-!ifdef RCFILE
-
-# Note: don't use $** in below rule because there may be other dependencies
-# and only the "master" rc must be passed to the resource compiler
-$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
- $(RESCMD) $(RCDIR)\$(PROJECT).rc
-
-!else
-
-# If parent makefile has not defined a resource definition file,
-# we will generate one from standard template.
-$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
-
-$(TMP_DIR)\$(PROJECT).rc:
- @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
-#include <winver.h>
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION COMMAVERSION
- PRODUCTVERSION COMMAVERSION
- FILEFLAGSMASK 0x3fL
-#ifdef DEBUG
- FILEFLAGS VS_FF_DEBUG
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "FileDescription", "Tcl extension " PROJECT
- VALUE "OriginalFilename", PRJLIBNAME
- VALUE "FileVersion", DOTVERSION
- VALUE "ProductName", "Package " PROJECT " for Tcl"
- VALUE "ProductVersion", DOTVERSION
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-<<
-
-!endif # ifdef RCFILE
-
-!ifndef DISABLE_IMPLICIT_RULES
-DISABLE_IMPLICIT_RULES = 0
-!endif
-
-!if !$(DISABLE_IMPLICIT_RULES)
-# Implicit rule definitions - only for building library objects. For stubs and
-# main application, the master makefile should define explicit rules.
-
-{$(ROOT)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(WINDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
- $(CCPKGCMD) @<<
-$<
-<<
-
-{$(RCDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
- $(RESCMD) $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-!endif
-
-################################################################
-# 14. Sanity check selected options against Tcl build options
-# When building an extension, certain configuration options should
-# match the ones used when Tcl was built. Here we check and
-# warn on a mismatch.
-!if ! $(DOING_TCL)
-
-!if $(TCLINSTALL) # Building against an installed Tcl
-!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
-TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
-!endif
-!else # ! $(TCLINSTALL) - building against Tcl source
-!if exist("$(OUT_DIR)\tcl.nmake")
-TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
-!endif
-!endif # TCLINSTALL
-
-!if $(CONFIG_CHECK)
-!ifdef TCLNMAKECONFIG
-!include $(TCLNMAKECONFIG)
-
-!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
-!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
-!endif
-!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
-!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
-!endif
-!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
-!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
-!endif
-!endif
-
-!endif # TCLNMAKECONFIG
-
-!endif # ! $(DOING_TCL)
-
-
-#----------------------------------------------------------
-# Display stats being used.
-#----------------------------------------------------------
-
-!if !$(DOING_TCL)
-!message *** Building against Tcl at '$(_TCLDIR)'
-!endif
-!if !$(DOING_TK) && $(NEED_TK)
-!message *** Building against Tk at '$(_TKDIR)'
-!endif
-!message *** Intermediate directory will be '$(TMP_DIR)'
-!message *** Output directory will be '$(OUT_DIR)'
-!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
-!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-
-!endif # ifdef _RULES_VC
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 0
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!message *** Using $(NMAKEHLPC)
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+!message *** Compiler has 'Optimizations'
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+# Old linkers (Visual C++ 6 in particular) will link for fast loading
+# on Win98. Since we do not support Win98 any more, we specify nowin98
+# as recommended for NT and later. However, this is only required by
+# IX86 on older compilers and only needed if we are not doing a static build.
+
+!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
+!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
+# Align sections for PE size savings.
+lflags = $(lflags) -opt:nowin98
+!endif
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Host architecture is $(NATIVE_ARCH)
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/targets.vc b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/targets.vc
new file mode 100644
index 0000000..7f1d388
--- /dev/null
+++ b/tcl8.6/pkgs/tdbcsqlite3-1.1.0/win/targets.vc
@@ -0,0 +1,98 @@
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/thread2.8.2/tclconfig/tcl.m4 b/tcl8.6/pkgs/thread2.8.2/tclconfig/tcl.m4
deleted file mode 100644
index e8234a2..0000000
--- a/tcl8.6/pkgs/thread2.8.2/tclconfig/tcl.m4
+++ /dev/null
@@ -1,4335 +0,0 @@
-# tcl.m4 --
-#
-# This file provides a set of autoconf macros to help TEA-enable
-# a Tcl extension.
-#
-# Copyright (c) 1999-2000 Ajuba Solutions.
-# Copyright (c) 2002-2005 ActiveState Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-
-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.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
-#
-
-#------------------------------------------------------------------------
-# TEA_PATH_TCLCONFIG --
-#
-# Locate the tclConfig.sh file and perform a sanity check on
-# the Tcl compile flags
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tcl=...
-#
-# Defines the following vars:
-# TCL_BIN_DIR Full path to the directory containing
-# the tclConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TCLCONFIG], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
- #
- # Ok, lets find the tcl configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tcl
- #
-
- if test x"${no_tcl}" = x ; then
- # we reset no_tcl in case something fails here
- no_tcl=true
- AC_ARG_WITH(tcl,
- AC_HELP_STRING([--with-tcl],
- [directory containing tcl configuration (tclConfig.sh)]),
- with_tclconfig="${withval}")
- AC_MSG_CHECKING([for Tcl configuration])
- AC_CACHE_VAL(ac_cv_c_tclconfig,[
-
- # First check to see if --with-tcl was specified.
- if test x"${with_tclconfig}" != x ; then
- case "${with_tclconfig}" in
- */tclConfig.sh )
- if test -f "${with_tclconfig}"; then
- AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
- with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tclconfig}/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
- fi
- fi
-
- # then check for a private Tcl installation
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in \
- ../tcl \
- `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tcl \
- `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tcl \
- `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tcl.framework/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tclConfig.sh" ; then
- ac_cv_c_tclconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tclconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/pkg/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
- ])
-
- if test x"${ac_cv_c_tclconfig}" = x ; then
- TCL_BIN_DIR="# no Tcl configs found"
- AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
- else
- no_tcl=
- TCL_BIN_DIR="${ac_cv_c_tclconfig}"
- AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_TKCONFIG --
-#
-# Locate the tkConfig.sh file
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-tk=...
-#
-# Defines the following vars:
-# TK_BIN_DIR Full path to the directory containing
-# the tkConfig.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_TKCONFIG], [
- #
- # Ok, lets find the tk configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-tk
- #
-
- if test x"${no_tk}" = x ; then
- # we reset no_tk in case something fails here
- no_tk=true
- AC_ARG_WITH(tk,
- AC_HELP_STRING([--with-tk],
- [directory containing tk configuration (tkConfig.sh)]),
- with_tkconfig="${withval}")
- AC_MSG_CHECKING([for Tk configuration])
- AC_CACHE_VAL(ac_cv_c_tkconfig,[
-
- # First check to see if --with-tkconfig was specified.
- if test x"${with_tkconfig}" != x ; then
- case "${with_tkconfig}" in
- */tkConfig.sh )
- if test -f "${with_tkconfig}"; then
- AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
- with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
- fi ;;
- esac
- if test -f "${with_tkconfig}/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
- else
- AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
- fi
- fi
-
- # then check for a private Tk library
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ../tk \
- `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../tk \
- `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
- ../../../tk \
- `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
-
- # on Darwin, check in Framework installation locations
- if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
- `ls -d /Library/Frameworks 2>/dev/null` \
- `ls -d /Network/Library/Frameworks 2>/dev/null` \
- `ls -d /System/Library/Frameworks 2>/dev/null` \
- ; do
- if test -f "$i/Tk.framework/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # TEA specific: on Windows, check in common installation locations
- if test "${TEA_PLATFORM}" = "windows" \
- -a x"${ac_cv_c_tkconfig}" = x ; then
- for i in `ls -d C:/Tcl/lib 2>/dev/null` \
- `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
- ; do
- if test -f "$i/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i; pwd)`"
- break
- fi
- done
- fi
-
- # check in a few other private locations
- if test x"${ac_cv_c_tkconfig}" = x ; then
- for i in \
- ${srcdir}/../tk \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
- if test "${TEA_PLATFORM}" = "windows" \
- -a -f "$i/win/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
- break
- fi
- if test -f "$i/unix/tkConfig.sh" ; then
- ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_tkconfig}" = x ; then
- TK_BIN_DIR="# no Tk configs found"
- AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
- else
- no_tk=
- TK_BIN_DIR="${ac_cv_c_tkconfig}"
- AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TCLCONFIG --
-#
-# Load the tclConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TCL_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_BIN_DIR
-# TCL_SRC_DIR
-# TCL_LIB_FILE
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TCLCONFIG], [
- AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
-
- if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TCL_BIN_DIR}/tclConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
- eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
-
- # If the TCL_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TCL_LIB_SPEC will be set to the value
- # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
- # instead of TCL_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
- TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
- TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tcl.framework installed in an arbitrary location.
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
- for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
- "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
- TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
- TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
- TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TCL_DBGX substitution
- eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
- eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
- eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
- eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
-
- AC_SUBST(TCL_VERSION)
- AC_SUBST(TCL_PATCH_LEVEL)
- AC_SUBST(TCL_BIN_DIR)
- AC_SUBST(TCL_SRC_DIR)
-
- AC_SUBST(TCL_LIB_FILE)
- AC_SUBST(TCL_LIB_FLAG)
- AC_SUBST(TCL_LIB_SPEC)
-
- AC_SUBST(TCL_STUB_LIB_FILE)
- AC_SUBST(TCL_STUB_LIB_FLAG)
- AC_SUBST(TCL_STUB_LIB_SPEC)
-
- AC_MSG_CHECKING([platform])
- hold_cc=$CC; CC="$TCL_CC"
- AC_TRY_COMPILE(,[
- #ifdef _WIN32
- #error win32
- #endif
- ], [
- TEA_PLATFORM="unix"
- CYGPATH=echo
- ], [
- TEA_PLATFORM="windows"
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
- )
- CC=$hold_cc
- AC_MSG_RESULT($TEA_PLATFORM)
-
- # The BUILD_$pkg is to define the correct extern storage class
- # handling when making this package
- AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
- [Building extension source?])
- # 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:
- AC_SUBST(CLEANFILES)
- AC_SUBST(TCL_LIBS)
- AC_SUBST(TCL_DEFS)
- AC_SUBST(TCL_EXTRA_CFLAGS)
- AC_SUBST(TCL_LD_FLAGS)
- AC_SUBST(TCL_SHLIB_LD_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_TKCONFIG --
-#
-# Load the tkConfig.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# TK_BIN_DIR
-#
-# Results:
-#
-# Sets the following vars that should be in tkConfig.sh:
-# TK_BIN_DIR
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_TKCONFIG], [
- AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
-
- if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
- AC_MSG_RESULT([loading])
- . "${TK_BIN_DIR}/tkConfig.sh"
- else
- AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
- eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
-
- # If the TK_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable TK_LIB_SPEC will be set to the value
- # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
- # instead of TK_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
- TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
- TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
- elif test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use the libraries
- # from the framework at the given location so that linking works
- # against Tk.framework installed in an arbitrary location.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
- for i in "`cd "${TK_BIN_DIR}"; pwd`" \
- "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
- if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
- TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
- break
- fi
- done
- fi
- if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
- TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
- TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
- fi
- ;;
- esac
- fi
-
- # eval is required to do the TK_DBGX substitution
- eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
- eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
- eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
- eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
-
- # TEA specific: Ensure windowingsystem is defined
- if test "${TEA_PLATFORM}" = "unix" ; then
- case ${TK_DEFS} in
- *MAC_OSX_TK*)
- AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
- TEA_WINDOWINGSYSTEM="aqua"
- ;;
- *)
- TEA_WINDOWINGSYSTEM="x11"
- ;;
- esac
- elif test "${TEA_PLATFORM}" = "windows" ; then
- TEA_WINDOWINGSYSTEM="win32"
- fi
-
- AC_SUBST(TK_VERSION)
- AC_SUBST(TK_BIN_DIR)
- AC_SUBST(TK_SRC_DIR)
-
- AC_SUBST(TK_LIB_FILE)
- AC_SUBST(TK_LIB_FLAG)
- AC_SUBST(TK_LIB_SPEC)
-
- AC_SUBST(TK_STUB_LIB_FILE)
- AC_SUBST(TK_STUB_LIB_FLAG)
- AC_SUBST(TK_STUB_LIB_SPEC)
-
- # TEA specific:
- AC_SUBST(TK_LIBS)
- AC_SUBST(TK_XINCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_TCLSH
-# Determine the fully qualified path name of the tclsh executable
-# in the Tcl build directory or the tclsh installed in a bin
-# directory. This macro will correctly determine the name
-# of the tclsh executable even if tclsh has not yet been
-# built in the build directory. The tclsh found is always
-# associated with a tclConfig.sh file. This tclsh should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCLSH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_TCLSH], [
- AC_MSG_CHECKING([for tclsh])
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- # tclConfig.sh is in Tcl build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- AC_MSG_RESULT([${TCLSH_PROG}])
- AC_SUBST(TCLSH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_PROG_WISH
-# Determine the fully qualified path name of the wish executable
-# in the Tk build directory or the wish installed in a bin
-# directory. This macro will correctly determine the name
-# of the wish executable even if wish has not yet been
-# built in the build directory. The wish found is always
-# associated with a tkConfig.sh file. This wish should be used
-# only for running extension test cases. It should never be
-# or generation of files (like pkgIndex.tcl) at build time.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# WISH_PROG
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PROG_WISH], [
- AC_MSG_CHECKING([for wish])
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- # tkConfig.sh is in Tk build directory
- if test "${TEA_PLATFORM}" = "windows"; then
- 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
- else
- # tkConfig.sh is in install location
- if test "${TEA_PLATFORM}" = "windows"; then
- WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
- else
- WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
- fi
- list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
- `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
- for i in $list ; do
- if test -f "$i/${WISH_PROG}" ; then
- REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
- break
- fi
- done
- WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
- fi
- AC_MSG_RESULT([${WISH_PROG}])
- AC_SUBST(WISH_PROG)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SHARED --
-#
-# Allows the building of shared libraries
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-shared=yes|no
-# --enable-stubs=yes|no
-#
-# Defines the following vars:
-# STATIC_BUILD Used for building import/export libraries
-# on Windows.
-#
-# Sets the following vars:
-# SHARED_BUILD Value of 1 or 0
-# 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)]),
- [shared_ok=$enableval], [shared_ok=yes])
-
- if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
- shared_ok=$enableval
- else
- 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
-
- # 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, [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)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_THREADS --
-#
-# Specify if thread support should be enabled. If "yes" is specified
-# as an arg (optional), threads are enabled by default, "no" means
-# threads are disabled. "yes" is the default.
-#
-# TCL_THREADS is checked so that if you are compiling an extension
-# against a threaded core, your extension must be compiled threaded
-# as well.
-#
-# Note that it is legal to have a thread enabled extension run in a
-# threaded or non-threaded Tcl core, but a non-threaded extension may
-# only run in a non-threaded Tcl core.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-threads
-#
-# Sets the following vars:
-# THREADS_LIBS Thread library(s)
-#
-# Defines the following vars:
-# TCL_THREADS
-# _REENTRANT
-# _THREAD_SAFE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_THREADS], [
- AC_ARG_ENABLE(threads,
- AC_HELP_STRING([--enable-threads],
- [build with threads (default: on)]),
- [tcl_ok=$enableval], [tcl_ok=yes])
-
- if test "${enable_threads+set}" = set; then
- enableval="$enable_threads"
- tcl_ok=$enableval
- else
- tcl_ok=yes
- fi
-
- if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
- TCL_THREADS=1
-
- if test "${TEA_PLATFORM}" != "windows" ; then
- # We are always OK on Windows, so check what this platform wants:
-
- # USE_THREAD_ALLOC tells us to try the special thread-based
- # allocator that significantly reduces lock contention
- AC_DEFINE(USE_THREAD_ALLOC, 1,
- [Do we want to use the threaded memory allocator?])
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- if test "`uname -s`" = "SunOS" ; then
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
- fi
- AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
- AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- # Check a little harder for __pthread_mutex_init in the same
- # library, as some systems hide it there until pthread.h is
- # defined. We could alternatively do an AC_TRY_COMPILE with
- # pthread.h, but that will work with libpthread really doesn't
- # exist, like AIX 4.2. [Bug: 4359]
- AC_CHECK_LIB(pthread, __pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- fi
-
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthread"
- else
- AC_CHECK_LIB(pthreads, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -lpthreads"
- else
- AC_CHECK_LIB(c, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "no"; then
- AC_CHECK_LIB(c_r, pthread_mutex_init,
- tcl_ok=yes, tcl_ok=no)
- if test "$tcl_ok" = "yes"; then
- # The space is needed
- THREADS_LIBS=" -pthread"
- else
- TCL_THREADS=0
- AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
- fi
- fi
- fi
- fi
- fi
- else
- TCL_THREADS=0
- fi
- # Do checking message here to not mess up interleaved configure output
- AC_MSG_CHECKING([for building with threads])
- if test "${TCL_THREADS}" = 1; then
- AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
- AC_MSG_RESULT([yes (default)])
- else
- AC_MSG_RESULT([no])
- fi
- # TCL_THREADS sanity checking. See if our request for building with
- # threads is the same as the way Tcl was built. If not, warn the user.
- case ${TCL_DEFS} in
- *THREADS=1*)
- if test "${TCL_THREADS}" = "0"; then
- AC_MSG_WARN([
- Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
- that IS thread-enabled. It is recommended to use --enable-threads.])
- fi
- ;;
- *)
- if test "${TCL_THREADS}" = "1"; then
- AC_MSG_WARN([
- --enable-threads requested, but building against a Tcl that is NOT
- thread-enabled. This is an OK configuration that will also run in
- a thread-enabled core.])
- fi
- ;;
- esac
- AC_SUBST(TCL_THREADS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_SYMBOLS --
-#
-# Specify if debugging symbols should be used.
-# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
-#
-# Arguments:
-# none
-#
-# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
-# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
-# Requires the following vars to be set in the Makefile:
-# CFLAGS_DEFAULT
-# LDFLAGS_DEFAULT
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-symbols
-#
-# Defines the following vars:
-# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
-# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
-# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
-# Sets to $(LDFLAGS_OPTIMIZE) if false
-# DBGX Formerly used as debug library extension;
-# always blank now.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_SYMBOLS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_CONFIG_CFLAGS])
- AC_MSG_CHECKING([for build with symbols])
- AC_ARG_ENABLE(symbols,
- AC_HELP_STRING([--enable-symbols],
- [build with debugging symbols (default: off)]),
- [tcl_ok=$enableval], [tcl_ok=no])
- DBGX=""
- if test "$tcl_ok" = "no"; then
- CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
- LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
- AC_MSG_RESULT([no])
- else
- CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
- LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
- if test "$tcl_ok" = "yes"; then
- AC_MSG_RESULT([yes (standard debugging)])
- fi
- fi
- # TEA specific:
- if test "${TEA_PLATFORM}" != "windows" ; then
- LDFLAGS_DEFAULT="${LDFLAGS}"
- fi
- AC_SUBST(CFLAGS_DEFAULT)
- AC_SUBST(LDFLAGS_DEFAULT)
- AC_SUBST(TCL_DBGX)
-
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
- AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
- fi
-
- if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
- if test "$tcl_ok" = "all"; then
- AC_MSG_RESULT([enabled symbols mem debugging])
- else
- AC_MSG_RESULT([enabled $tcl_ok debugging])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_ENABLE_LANGINFO --
-#
-# Allows use of modern nl_langinfo check for better l10n.
-# This is only relevant for Unix.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --enable-langinfo=yes|no (default is yes)
-#
-# Defines the following vars:
-# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_ENABLE_LANGINFO], [
- AC_ARG_ENABLE(langinfo,
- AC_HELP_STRING([--enable-langinfo],
- [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
- [langinfo_ok=$enableval], [langinfo_ok=yes])
-
- HAVE_LANGINFO=0
- if test "$langinfo_ok" = "yes"; then
- AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
- fi
- AC_MSG_CHECKING([whether to use nl_langinfo])
- if test "$langinfo_ok" = "yes"; then
- AC_CACHE_VAL(tcl_cv_langinfo_h, [
- AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
- [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
- AC_MSG_RESULT([$tcl_cv_langinfo_h])
- if test $tcl_cv_langinfo_h = yes; then
- AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
- fi
- else
- AC_MSG_RESULT([$langinfo_ok])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_SYSTEM
-#
-# Determine what the system is (some things cannot be easily checked
-# on a feature-driven basis, alas). This can usually be done via the
-# "uname" command.
-#
-# Arguments:
-# none
-#
-# Results:
-# Defines the following var:
-#
-# system - System/platform/version identification code.
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_SYSTEM], [
- AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
- # TEA specific:
- if test "${TEA_PLATFORM}" = "windows" ; then
- tcl_cv_sys_version=windows
- else
- tcl_cv_sys_version=`uname -s`-`uname -r`
- if test "$?" -ne 0 ; then
- AC_MSG_WARN([can't find uname command])
- tcl_cv_sys_version=unknown
- else
- if test "`uname -s`" = "AIX" ; then
- tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
- fi
- fi
- fi
- ])
- system=$tcl_cv_sys_version
-])
-
-#--------------------------------------------------------------------
-# TEA_CONFIG_CFLAGS
-#
-# Try to determine the proper flags to pass to the compiler
-# for building shared libraries and other such nonsense.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substitutes the following vars:
-#
-# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
-# LDFLAGS - Flags to pass to the compiler when linking object
-# files into an executable application binary such
-# as tclsh.
-# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile. Could
-# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
-# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
-# that tell the run-time dynamic linker where to look
-# for shared libraries such as libtcl.so. Depends on
-# the variable LIB_RUNTIME_DIR in the Makefile.
-# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
-# of a shared library (may request position-independent
-# code, among other things).
-# SHLIB_LD - Base command to use for combining object files
-# into a shared library.
-# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
-# creating shared libraries. This symbol typically
-# goes at the end of the "ld" commands that build
-# shared libraries. The value of the symbol defaults to
-# "${LIBS}" if all of the dependent libraries should
-# be specified when creating a shared library. If
-# dependent libraries should not be specified (as on
-# SunOS 4.x, where they cause the link to fail, or in
-# general if Tcl and Tk aren't themselves shared
-# libraries), then this symbol has an empty string
-# as its value.
-# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
-# extensions. An empty string means we don't know how
-# to use shared libraries on this platform.
-# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
-# in a static or shared library name, using the $PACKAGE_VERSION variable
-# to put the version in the right place. This is used
-# by platforms that need non-standard library names.
-# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
-# to have a version after the .so, and ${PACKAGE_VERSION}.a
-# on AIX, since a shared library needs to have
-# a .a extension whereas shared objects for loadable
-# extensions have a .so extension. Defaults to
-# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
-# CFLAGS_DEBUG -
-# Flags used when running the compiler in debug mode
-# CFLAGS_OPTIMIZE -
-# Flags used when running the compiler in optimize mode
-# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_CONFIG_CFLAGS], [
- dnl TEA specific: Make sure we are initialized
- AC_REQUIRE([TEA_INIT])
-
- # Step 0.a: Enable 64 bit support?
-
- AC_MSG_CHECKING([if 64bit support is requested])
- AC_ARG_ENABLE(64bit,
- AC_HELP_STRING([--enable-64bit],
- [enable 64bit support (default: off)]),
- [do64bit=$enableval], [do64bit=no])
- AC_MSG_RESULT([$do64bit])
-
- # Step 0.b: Enable Solaris 64 bit VIS support?
-
- AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
- AC_ARG_ENABLE(64bit-vis,
- AC_HELP_STRING([--enable-64bit-vis],
- [enable 64bit Sparc VIS support (default: off)]),
- [do64bitVIS=$enableval], [do64bitVIS=no])
- AC_MSG_RESULT([$do64bitVIS])
- # Force 64bit on with VIS
- AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
-
- # Step 0.c: Check if visibility support is available. Do this here so
- # that platform specific alternatives can be used below if this fails.
-
- AC_CACHE_CHECK([if compiler supports visibility "hidden"],
- tcl_cv_cc_visibility_hidden, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- AC_TRY_LINK([
- extern __attribute__((__visibility__("hidden"))) void f(void);
- void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
- tcl_cv_cc_visibility_hidden=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
- AC_DEFINE(MODULE_SCOPE,
- [extern __attribute__((__visibility__("hidden")))],
- [Compiler support for module scope symbols])
- AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
- ])
-
- # Step 0.d: Disable -rpath support?
-
- AC_MSG_CHECKING([if rpath support is requested])
- AC_ARG_ENABLE(rpath,
- AC_HELP_STRING([--disable-rpath],
- [disable rpath support (default: on)]),
- [doRpath=$enableval], [doRpath=yes])
- AC_MSG_RESULT([$doRpath])
-
- # TEA specific: Cross-compiling options for Windows/CE builds?
-
- AS_IF([test "${TEA_PLATFORM}" = windows], [
- AC_MSG_CHECKING([if Windows/CE build is requested])
- AC_ARG_ENABLE(wince,
- AC_HELP_STRING([--enable-wince],
- [enable Win/CE support (where applicable)]),
- [doWince=$enableval], [doWince=no])
- AC_MSG_RESULT([$doWince])
- ])
-
- # Set the variable "system" to hold the name and version number
- # for the system.
-
- TEA_CONFIG_SYSTEM
-
- # Require ranlib early so we can override it in special cases below.
-
- AC_REQUIRE([AC_PROG_RANLIB])
-
- # 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
- AS_IF([test "$GCC" = yes], [
- CFLAGS_OPTIMIZE=-O2
- CFLAGS_WARNING="-Wall"
- ], [
- CFLAGS_OPTIMIZE=-O
- CFLAGS_WARNING=""
- ])
- AC_CHECK_TOOL(AR, ar)
- STLIB_LD='${AR} cr'
- LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
- AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
- 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
- AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
- AC_MSG_WARN([Ensure latest Platform SDK is installed])
- do64bit="no"
- else
- AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
- do64bit_ok="yes"
- fi
- fi
-
- if test "$doWince" != "no" ; then
- if test "$do64bit" != "no" ; then
- AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
- fi
- if test "$GCC" = "yes" ; then
- AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
- fi
- TEA_PATH_CELIB
- # Set defaults for common evc4/PPC2003 setup
- # Currently Tcl requires 300+, possibly 420+ for sockets
- CEVERSION=420; # could be 211 300 301 400 420 ...
- TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
- ARCH=ARM; # could be ARM MIPS X86EM ...
- PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
- if test "$doWince" != "yes"; then
- # If !yes then the user specified something
- # Reset ARCH to allow user to skip specifying it
- ARCH=
- eval `echo $doWince | awk -F, '{ \
- if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
- if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
- if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
- if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
- if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
- }'`
- if test "x${ARCH}" = "x" ; then
- ARCH=$TARGETCPU;
- fi
- fi
- OSVERSION=WCE$CEVERSION;
- if test "x${WCEROOT}" = "x" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
- if test ! -d "${WCEROOT}" ; then
- WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
- fi
- fi
- if test "x${SDKROOT}" = "x" ; then
- SDKROOT="C:/Program Files/Windows CE Tools"
- if test ! -d "${SDKROOT}" ; then
- SDKROOT="C:/Windows CE Tools"
- fi
- fi
- WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
- SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
- if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
- -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
- AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
- doWince="no"
- else
- # We could PATH_NOSPACE these, but that's not important,
- # as long as we quote them when used.
- CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
- if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
- CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
- fi
- CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
- fi
- fi
-
- if test "$GCC" != "yes" ; then
- if test "${SHARED_BUILD}" = "0" ; then
- runtime=-MT
- else
- runtime=-MD
- fi
- case "x`echo \${VisualStudioVersion}`" in
- x1[[4-9]]*)
- lflags="${lflags} -nodefaultlib:libucrt.lib"
- TEA_ADD_LIBS([ucrt.lib])
- ;;
- *)
- ;;
- 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
- TEA_ADD_LIBS([bufferoverflowU.lib])
- elif test "$doWince" != "no" ; then
- CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
- if test "${TARGETCPU}" = "X86"; then
- CC="\"${CEBINROOT}/cl.exe\""
- else
- CC="\"${CEBINROOT}/cl${ARCH}.exe\""
- fi
- CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
- RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
- arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
- defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
- if test "${SHARED_BUILD}" = "1" ; then
- # Static CE builds require static celib as well
- defs="${defs} _DLL"
- fi
- for i in $defs ; do
- AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
- done
- AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
- AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
- CFLAGS_DEBUG="-nologo -Zi -Od"
- CFLAGS_OPTIMIZE="-nologo -Ox"
- lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
- lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
- LINKBIN="\"${CEBINROOT}/link.exe\""
- AC_SUBST(CELIB_DIR)
- 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
- AC_CHECK_TOOL(RC, windres)
- CFLAGS_DEBUG="-g"
- CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
- SHLIB_LD='${CC} -shared'
- UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
- LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
- LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
-
- AC_CACHE_CHECK(for cross-compile version of gcc,
- ac_cv_cross,
- AC_TRY_COMPILE([
- #ifdef _WIN32
- #error cross-compiler
- #endif
- ], [],
- ac_cv_cross=yes,
- ac_cv_cross=no)
- )
- 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-*)
- AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
- # AIX requires the _r compiler when gcc isn't being used
- case "${CC}" in
- *_r|*_r\ *)
- # ok ...
- ;;
- *)
- # Make sure only first arg gets _r
- CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
- ;;
- esac
- AC_MSG_RESULT([Using $CC for compiling with threads])
- ])
- LIBS="$LIBS -lc"
- SHLIB_CFLAGS=""
- SHLIB_SUFFIX=".so"
-
- LD_LIBRARY_PATH_VAR="LIBPATH"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -q64"
- LDFLAGS_ARCH="-q64"
- RANLIB="${RANLIB} -X64"
- AR="${AR} -X64"
- SHLIB_LD_FLAGS="-b64"
- ])
- ])
-
- AS_IF([test "`uname -m`" = ia64], [
- # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- AS_IF([test "$GCC" = yes], [
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- ], [
- CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
- ])
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ], [
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared -Wl,-bexpall'
- ], [
- SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
- LDFLAGS="$LDFLAGS -brtl"
- ])
- SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
- CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- 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.
- #-----------------------------------------------------------
- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
- ;;
- 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} ${CFLAGS} ${LDFLAGS} -shared'
- AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
- ;;
- HP-UX-*.11.*)
- # Use updated header definitions where possible
- AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
- # TEA specific: Needed by Tcl, but not most extensions
- #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
- #LIBS="$LIBS -lxnet" # Use the XOPEN network library
-
- AS_IF([test "`uname -m`" = ia64], [
- SHLIB_SUFFIX=".so"
- # Use newer C++ library for C++ extensions
- #if test "$GCC" != "yes" ; then
- # CPPFLAGS="-AA"
- #fi
- ], [
- SHLIB_SUFFIX=".sl"
- ])
- AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
- AS_IF([test "$tcl_ok" = yes], [
- LDFLAGS="$LDFLAGS -Wl,-E"
- CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
- LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
- LD_LIBRARY_PATH_VAR="SHLIB_PATH"
- ])
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- CFLAGS="$CFLAGS -z"
- # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
- #CFLAGS="$CFLAGS +DAportable"
- SHLIB_CFLAGS="+z"
- SHLIB_LD="ld -b"
- ])
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = "yes"], [
- AS_IF([test "$GCC" = yes], [
- case `${CC} -dumpmachine` in
- hppa64*)
- # 64-bit gcc in use. Fix flags for GNU ld.
- do64bit_ok=yes
- SHLIB_LD='${CC} -shared'
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ;;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system])
- ;;
- esac
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS +DD64"
- LDFLAGS_ARCH="+DD64"
- ])
- ]) ;;
- IRIX-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [
- CFLAGS="$CFLAGS -mabi=n32"
- LDFLAGS="$LDFLAGS -mabi=n32"
- ], [
- case $system in
- IRIX-6.3)
- # Use to build 6.2 compatible binaries on 6.3.
- CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
- ;;
- *)
- CFLAGS="$CFLAGS -n32"
- ;;
- esac
- LDFLAGS="$LDFLAGS -n32"
- ])
- ;;
- IRIX64-6.*)
- SHLIB_CFLAGS=""
- SHLIB_LD="ld -n32 -shared -rdata_shared"
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
-
- # Check to enable 64-bit flags for compiler/linker
-
- AS_IF([test "$do64bit" = yes], [
- AS_IF([test "$GCC" = yes], [
- AC_MSG_WARN([64bit mode not supported by gcc])
- ], [
- do64bit_ok=yes
- SHLIB_LD="ld -64 -shared -rdata_shared"
- CFLAGS="$CFLAGS -64"
- LDFLAGS_ARCH="-64"
- ])
- ])
- ;;
- Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
- LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
- AS_IF([test $do64bit = yes], [
- AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -m64"
- AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_m64 = yes], [
- CFLAGS="$CFLAGS -m64"
- do64bit_ok=yes
- ])
- ])
-
- # The combo of gcc + glibc has a bug related to inlining of
- # functions like strtod(). The -fno-builtin flag should address
- # this problem but it does not work. The -fno-inline flag is kind
- # of overkill but it works. Disable inlining only when one of the
- # files in compat/*.c is being linked in.
-
- AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
- ;;
- Lynx*)
- SHLIB_CFLAGS="-fPIC"
- SHLIB_SUFFIX=".so"
- CFLAGS_OPTIMIZE=-02
- SHLIB_LD='${CC} -shared'
- LD_FLAGS="-Wl,--export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- ;;
- OpenBSD-*)
- arch=`arch -s`
- case "$arch" in
- alpha|sparc64)
- SHLIB_CFLAGS="-fPIC"
- ;;
- *)
- SHLIB_CFLAGS="-fpic"
- ;;
- esac
- SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
- LDFLAGS="-Wl,-export-dynamic"
- CFLAGS_OPTIMIZE="-O2"
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # On OpenBSD: Compile with -pthread
- # Don't link with -lpthread
- LIBS=`echo $LIBS | sed s/-lpthread//`
- CFLAGS="$CFLAGS -pthread"
- ])
- # 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} ${SHLIB_CFLAGS} -shared'
- SHLIB_SUFFIX=".so"
- LDFLAGS="$LDFLAGS -export-dynamic"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the CFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ;;
- 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=""
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
- AS_IF([test "${TCL_THREADS}" = "1"], [
- # The -pthread needs to go in the LDFLAGS, not LIBS
- LIBS=`echo $LIBS | sed s/-pthread//`
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
- 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}'`"
- AS_IF([test $do64bit = yes], [
- case `arch` in
- ppc)
- AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
- tcl_cv_cc_arch_ppc64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
- tcl_cv_cc_arch_ppc64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
- CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- do64bit_ok=yes
- ]);;
- i386)
- AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
- tcl_cv_cc_arch_x86_64, [
- hold_cflags=$CFLAGS
- CFLAGS="$CFLAGS -arch x86_64"
- AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
- tcl_cv_cc_arch_x86_64=no)
- CFLAGS=$hold_cflags])
- AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
- CFLAGS="$CFLAGS -arch x86_64"
- do64bit_ok=yes
- ]);;
- *)
- AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
- esac
- ], [
- # Check for combined 32-bit and 64-bit fat build
- AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
- && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
- fat_32_64=yes])
- ])
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
- AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_single_module = yes], [
- SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
- ])
- # TEA specific: link shlib with current and 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:
- AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
- "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
- LDFLAGS="$LDFLAGS -prebind"])
- LDFLAGS="$LDFLAGS -headerpad_max_install_names"
- AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
- tcl_cv_ld_search_paths_first, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
- tcl_cv_ld_search_paths_first=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
- LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- ])
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [__private_extern__],
- [Compiler support for module scope symbols])
- tcl_cv_cc_visibility_hidden=yes
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
- # TEA specific: for combined 32 & 64 bit fat builds of Tk
- # extensions, verify that 64-bit build is possible.
- AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
- AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
- LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
- AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
- tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
- AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
- done
- CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
- LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
- AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
- tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="$hold_'$v'"'
- done])
- ])
- # remove 64-bit arch flags from CFLAGS et al. if configuration
- # does not support 64-bit.
- AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
- AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
- for v in CFLAGS CPPFLAGS LDFLAGS; do
- eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
- done])
- ])
- ;;
- OS/390-*)
- CFLAGS_OPTIMIZE="" # Optimizer is buggy
- AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
- [Should OS/390 do the right thing with sockets?])
- ;;
- OSF1-V*)
- # Digital OSF/1
- SHLIB_CFLAGS=""
- AS_IF([test "$SHARED_BUILD" = 1], [
- SHLIB_LD='ld -shared -expect_unresolved "*"'
- ], [
- SHLIB_LD='ld -non_shared -expect_unresolved "*"'
- ])
- SHLIB_SUFFIX=".so"
- AS_IF([test $doRpath = yes], [
- CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
- AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
- CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
- # see pthread_intro(3) for pthread support on osf1, k.furukawa
- AS_IF([test "${TCL_THREADS}" = 1], [
- CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
- CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
- LIBS=`echo $LIBS | sed s/-lpthreads//`
- AS_IF([test "$GCC" = yes], [
- LIBS="$LIBS -lpthread -lmach -lexc"
- ], [
- CFLAGS="$CFLAGS -pthread"
- LDFLAGS="$LDFLAGS -pthread"
- ])
- ])
- ;;
- QNX-6*)
- # QNX RTP
- # This may work for all QNX, but it was only reported for v6.
- SHLIB_CFLAGS="-fPIC"
- SHLIB_LD="ld -Bshareable -x"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- SCO_SV-3.2*)
- AS_IF([test "$GCC" = yes], [
- SHLIB_CFLAGS="-fPIC -melf"
- LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
- ], [
- SHLIB_CFLAGS="-Kpic -belf"
- LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
- ])
- SHLIB_LD="ld -G"
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- 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.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ], [
- SHLIB_LD="/usr/ccs/bin/ld -G -z text"
- CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- ])
- ;;
- SunOS-5*)
- # Note: If _REENTRANT isn't defined, then Solaris
- # won't define thread-safe library routines.
-
- AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
- AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
- [Do we really want to follow the standard? Yes we do!])
-
- SHLIB_CFLAGS="-KPIC"
-
- # Check to enable 64-bit flags for compiler/linker
- AS_IF([test "$do64bit" = yes], [
- arch=`isainfo`
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- AS_IF([test "$GCC" = yes], [
- AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
- AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
- ], [
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64 -mcpu=v9"
- LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
- SHLIB_CFLAGS="-fPIC"
- ])
- ], [
- do64bit_ok=yes
- AS_IF([test "$do64bitVIS" = yes], [
- CFLAGS="$CFLAGS -xarch=v9a"
- LDFLAGS_ARCH="-xarch=v9a"
- ], [
- CFLAGS="$CFLAGS -xarch=v9"
- LDFLAGS_ARCH="-xarch=v9"
- ])
- # Solaris 64 uses this as well
- #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
- ])
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- AS_IF([test "$GCC" = yes], [
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- do64bit_ok=yes
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
- esac
- ], [
- do64bit_ok=yes
- case $system in
- SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
- CFLAGS="$CFLAGS -m64"
- LDFLAGS="$LDFLAGS -m64";;
- *)
- CFLAGS="$CFLAGS -xarch=amd64"
- LDFLAGS="$LDFLAGS -xarch=amd64";;
- esac
- ])
- ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
- ])
-
- SHLIB_SUFFIX=".so"
- AS_IF([test "$GCC" = yes], [
- SHLIB_LD='${CC} -shared'
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- AS_IF([test "$do64bit_ok" = yes], [
- AS_IF([test "$arch" = "sparcv9 sparc"], [
- # We need to specify -static-libgcc or we need to
- # add the path to the sparv9 libgcc.
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
- # for finding sparcv9 libgcc, get the regular libgcc
- # path, remove so name and append 'sparcv9'
- #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
- #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
- ], [AS_IF([test "$arch" = "amd64 i386"], [
- # JH: static-libgcc is necessary for core Tcl, but may
- # not be necessary for extensions.
- SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
- ])])
- ])
- ], [
- case $system in
- SunOS-5.[[1-9]][[0-9]]*)
- # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
- SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
- *)
- SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
- esac
- CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
- LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
- ])
- ;;
- UNIX_SV* | UnixWare-5*)
- SHLIB_CFLAGS="-KPIC"
- SHLIB_LD='${CC} -G'
- SHLIB_LD_LIBS=""
- SHLIB_SUFFIX=".so"
- # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
- # that don't grok the -Bexport option. Test that it does.
- AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
- hold_ldflags=$LDFLAGS
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
- LDFLAGS=$hold_ldflags])
- AS_IF([test $tcl_cv_ld_Bexport = yes], [
- LDFLAGS="$LDFLAGS -Wl,-Bexport"
- ])
- CC_SEARCH_FLAGS=""
- LD_SEARCH_FLAGS=""
- ;;
- esac
-
- AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
- AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
- ])
-
-dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
-dnl # until the end of configure, as configure's compile and link tests use
-dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
-dnl # preprocessing tests use only CPPFLAGS.
- AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
-
- # 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.
-
- AS_IF([test "$GCC" = yes], [
- case $system in
- AIX-*) ;;
- BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
- IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
- Darwin-*) ;;
- SCO_SV-3.2*) ;;
- windows) ;;
- *) SHLIB_CFLAGS="-fPIC" ;;
- esac])
-
- AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
- AC_DEFINE(MODULE_SCOPE, [extern],
- [No Compiler support for module scope symbols])
- ])
-
- AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
- AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
- # TEA specific: use PACKAGE_VERSION instead of VERSION
- UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
-
- if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
- AC_CACHE_CHECK(for SEH support in compiler,
- tcl_cv_seh,
- AC_TRY_RUN([
-#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;
- }
- ],
- tcl_cv_seh=yes,
- tcl_cv_seh=no,
- tcl_cv_seh=no)
- )
- if test "$tcl_cv_seh" = "no" ; then
- AC_DEFINE(HAVE_NO_SEH, 1,
- [Defined when mingw does not support SEH])
- 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.
- #
- AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
- tcl_cv_eh_disposition,
- AC_TRY_COMPILE([
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# undef WIN32_LEAN_AND_MEAN
- ],[
- EXCEPTION_DISPOSITION x;
- ],
- tcl_cv_eh_disposition=yes,
- tcl_cv_eh_disposition=no)
- )
- if test "$tcl_cv_eh_disposition" = "no" ; then
- AC_DEFINE(EXCEPTION_DISPOSITION, int,
- [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
- 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.
-
- AC_CACHE_CHECK(for winnt.h that ignores VOID define,
- tcl_cv_winnt_ignore_void,
- AC_TRY_COMPILE([
-#define VOID void
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
- ], [
- CHAR c;
- SHORT s;
- LONG l;
- ],
- tcl_cv_winnt_ignore_void=yes,
- tcl_cv_winnt_ignore_void=no)
- )
- if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
- AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
- [Defined when cygwin/mingw ignores VOID define in winnt.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.
-
- AC_CACHE_CHECK(for cast to union support,
- tcl_cv_cast_to_union,
- AC_TRY_COMPILE([],
- [
- union foo { int i; double d; };
- union foo f = (union foo) (int) 0;
- ],
- tcl_cv_cast_to_union=yes,
- tcl_cv_cast_to_union=no)
- )
- if test "$tcl_cv_cast_to_union" = "yes"; then
- AC_DEFINE(HAVE_CAST_TO_UNION, 1,
- [Defined when compiler supports casting to union type.])
- fi
-
- AC_SUBST(CFLAGS_DEBUG)
- AC_SUBST(CFLAGS_OPTIMIZE)
- AC_SUBST(CFLAGS_WARNING)
-
- AC_SUBST(STLIB_LD)
- AC_SUBST(SHLIB_LD)
-
- AC_SUBST(SHLIB_LD_LIBS)
- AC_SUBST(SHLIB_CFLAGS)
-
- AC_SUBST(LD_LIBRARY_PATH_VAR)
-
- # These must be called after we do the basic CFLAGS checks and
- # verify any possible 64-bit or similar switches are necessary
- TEA_TCL_EARLY_FLAGS
- TEA_TCL_64BIT_FLAGS
-])
-
-#--------------------------------------------------------------------
-# TEA_SERIAL_PORT
-#
-# Determine which interface to use to talk to the serial port.
-# Note that #include lines must begin in leftmost column for
-# some compilers to recognize them as preprocessor directives,
-# and some build environments have stdin not pointing at a
-# pseudo-terminal (usually /dev/null instead.)
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines only one of the following vars:
-# HAVE_SYS_MODEM_H
-# USE_TERMIOS
-# USE_TERMIO
-# USE_SGTTY
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_SERIAL_PORT], [
- AC_CHECK_HEADERS(sys/modem.h)
- AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
- AC_TRY_RUN([
-#include <termios.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termio.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <sgtty.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no ; then
- AC_TRY_RUN([
-#include <termios.h>
-#include <errno.h>
-
-int main() {
- struct termios t;
- if (tcgetattr(0, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- cfsetospeed(&t, 0);
- t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <termio.h>
-#include <errno.h>
-
-int main() {
- struct termio t;
- if (ioctl(0, TCGETA, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
- return 0;
- }
- return 1;
- }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
- fi
- if test $tcl_cv_api_serial = no; then
- AC_TRY_RUN([
-#include <sgtty.h>
-#include <errno.h>
-
-int main() {
- struct sgttyb t;
- if (ioctl(0, TIOCGETP, &t) == 0
- || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
- t.sg_ospeed = 0;
- t.sg_flags |= ODDP | EVENP | RAW;
- return 0;
- }
- return 1;
-}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
- fi])
- case $tcl_cv_api_serial in
- termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
- termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
- sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_MISSING_POSIX_HEADERS
-#
-# Supply substitutes for missing POSIX header files. Special
-# notes:
-# - stdlib.h doesn't define strtol, strtoul, or
-# strtod in some versions of SunOS
-# - some versions of string.h don't declare procedures such
-# as strstr
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# NO_DIRENT_H
-# NO_ERRNO_H
-# NO_VALUES_H
-# HAVE_LIMITS_H or NO_LIMITS_H
-# NO_STDLIB_H
-# NO_STRING_H
-# NO_SYS_WAIT_H
-# NO_DLFCN_H
-# HAVE_SYS_PARAM_H
-#
-# HAVE_STRING_H ?
-#
-# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
-# CHECK on limits.h
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
- AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
- AC_TRY_LINK([#include <sys/types.h>
-#include <dirent.h>], [
-#ifndef _POSIX_SOURCE
-# ifdef __Lynx__
- /*
- * Generate compilation error to make the test fail: Lynx headers
- * are only valid if really in the POSIX environment.
- */
-
- missing_procedure();
-# endif
-#endif
-DIR *d;
-struct dirent *entryPtr;
-char *p;
-d = opendir("foobar");
-entryPtr = readdir(d);
-p = entryPtr->d_name;
-closedir(d);
-], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
-
- if test $tcl_cv_dirent_h = no; then
- AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
- fi
-
- # TEA specific:
- AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
- AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
- AC_CHECK_HEADER(limits.h,
- [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
- [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
- AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
- AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
- fi
- AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
- AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
- AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
-
- # See also memmove check below for a place where NO_STRING_H can be
- # set and why.
-
- if test $tcl_ok = 0; then
- AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
- fi
-
- AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
- AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
-
- # OS/390 lacks sys/param.h (and doesn't need it, by chance).
- AC_HAVE_HEADERS(sys/param.h)
-])
-
-#--------------------------------------------------------------------
-# TEA_PATH_X
-#
-# Locate the X11 header files and the X11 library archive. Try
-# the ac_path_x macro first, but if it doesn't find the X stuff
-# (e.g. because there's no xmkmf program) then check through
-# a list of possible directories. Under some conditions the
-# autoconf macro will return an include directory that contains
-# no include files, so double-check its result just to be safe.
-#
-# This should be called after TEA_CONFIG_CFLAGS as setting the
-# LIBS line can confuse some configure macro magic.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets the following vars:
-# XINCLUDES
-# XLIBSW
-# PKG_LIBS (appends to)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_X], [
- if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
- TEA_PATH_UNIX_X
- fi
-])
-
-AC_DEFUN([TEA_PATH_UNIX_X], [
- AC_PATH_X
- not_really_there=""
- if test "$no_x" = ""; then
- if test "$x_includes" = ""; then
- AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
- else
- if test ! -r $x_includes/X11/Xlib.h; then
- not_really_there="yes"
- fi
- fi
- fi
- if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
- AC_MSG_CHECKING([for X11 header files])
- found_xincludes="no"
- AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
- if test "$found_xincludes" = "no"; then
- dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
- for i in $dirs ; do
- if test -r $i/X11/Xlib.h; then
- AC_MSG_RESULT([$i])
- XINCLUDES=" -I$i"
- found_xincludes="yes"
- break
- fi
- done
- fi
- else
- if test "$x_includes" != ""; then
- XINCLUDES="-I$x_includes"
- found_xincludes="yes"
- fi
- fi
- if test "$found_xincludes" = "no"; then
- AC_MSG_RESULT([couldn't find any!])
- fi
-
- if test "$no_x" = yes; then
- AC_MSG_CHECKING([for X11 libraries])
- XLIBSW=nope
- dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
- for i in $dirs ; do
- if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
- AC_MSG_RESULT([$i])
- XLIBSW="-L$i -lX11"
- x_libraries="$i"
- break
- fi
- done
- else
- if test "$x_libraries" = ""; then
- XLIBSW=-lX11
- else
- XLIBSW="-L$x_libraries -lX11"
- fi
- fi
- if test "$XLIBSW" = nope ; then
- AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
- fi
- if test "$XLIBSW" = nope ; then
- AC_MSG_RESULT([could not find any! Using -lX11.])
- XLIBSW=-lX11
- fi
- # TEA specific:
- if test x"${XLIBSW}" != x ; then
- PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BLOCKING_STYLE
-#
-# The statements below check for systems where POSIX-style
-# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
-# On these systems (mostly older ones), use the old BSD-style
-# FIONBIO approach instead.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# HAVE_SYS_IOCTL_H
-# HAVE_SYS_FILIO_H
-# USE_FIONBIO
-# O_NONBLOCK
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BLOCKING_STYLE], [
- AC_CHECK_HEADERS(sys/ioctl.h)
- AC_CHECK_HEADERS(sys/filio.h)
- TEA_CONFIG_SYSTEM
- AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
- case $system in
- OSF*)
- AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
- AC_MSG_RESULT([FIONBIO])
- ;;
- *)
- AC_MSG_RESULT([O_NONBLOCK])
- ;;
- esac
-])
-
-#--------------------------------------------------------------------
-# TEA_TIME_HANDLER
-#
-# Checks how the system deals with time.h, what time structures
-# are used on the system, and what fields the structures have.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines some of the following vars:
-# USE_DELTA_FOR_TZ
-# HAVE_TM_GMTOFF
-# HAVE_TM_TZADJ
-# HAVE_TIMEZONE_VAR
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TIME_HANDLER], [
- AC_CHECK_HEADERS(sys/time.h)
- AC_HEADER_TIME
- AC_STRUCT_TIMEZONE
-
- AC_CHECK_FUNCS(gmtime_r localtime_r)
-
- AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
- tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
- if test $tcl_cv_member_tm_tzadj = yes ; then
- AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
- fi
-
- AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
- AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
- tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
- if test $tcl_cv_member_tm_gmtoff = yes ; then
- AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
- fi
-
- #
- # Its important to include time.h in this check, as some systems
- # (like convex) have timezone functions, etc.
- #
- AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern long timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
- if test $tcl_cv_timezone_long = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- else
- #
- # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
- #
- AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
- AC_TRY_COMPILE([#include <time.h>],
- [extern time_t timezone;
- timezone += 1;
- exit (0);],
- tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
- if test $tcl_cv_timezone_time = yes ; then
- AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_BUGGY_STRTOD
-#
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" (provided by Tcl) that corrects the error.
-# Also, on Compaq's Tru64 Unix 5.0,
-# strtod(" ") returns 0.0 instead of a failure to convert.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Might defines some of the following vars:
-# strtod (=fixstrtod)
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_BUGGY_STRTOD], [
- AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
- if test "$tcl_strtod" = 1; then
- AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
- AC_TRY_RUN([
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
- tcl_cv_strtod_buggy=buggy)])
- if test "$tcl_cv_strtod_buggy" = buggy; then
- AC_LIBOBJ([fixstrtod])
- USE_COMPAT=1
- AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_LINK_LIBS
-#
-# Search for the libraries needed to link the Tcl shell.
-# Things like the math library (-lm) and socket stuff (-lsocket vs.
-# -lnsl) are dealt with here.
-#
-# Arguments:
-# Requires the following vars to be set in the Makefile:
-# DL_LIBS (not in TEA, only needed in core)
-# LIBS
-# MATH_LIBS
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_LIBS
-# MATH_LIBS
-#
-# Might append to the following vars:
-# LIBS
-#
-# Might define the following vars:
-# HAVE_NET_ERRNO_H
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_LINK_LIBS], [
- #--------------------------------------------------------------------
- # On a few very rare systems, all of the libm.a stuff is
- # already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
- #--------------------------------------------------------------------
-
- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
-
- #--------------------------------------------------------------------
- # Interactive UNIX requires -linet instead of -lsocket, plus it
- # needs net/errno.h to define the socket-related error codes.
- #--------------------------------------------------------------------
-
- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
- AC_CHECK_HEADER(net/errno.h, [
- AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
-
- #--------------------------------------------------------------------
- # Check for the existence of the -lsocket and -lnsl libraries.
- # The order here is important, so that they end up in the right
- # order in the command line generated by make. Here are some
- # special considerations:
- # 1. Use "connect" and "accept" to check for -lsocket, and
- # "gethostbyname" to check for -lnsl.
- # 2. Use each function name only once: can't redo a check because
- # autoconf caches the results of the last check and won't redo it.
- # 3. Use -lnsl and -lsocket only if they supply procedures that
- # aren't already present in the normal libraries. This is because
- # IRIX 5.2 has libraries, but they aren't needed and they're
- # bogus: they goof up name resolution if used.
- # 4. On some SVR4 systems, can't use -lsocket without -lnsl too.
- # To get around this problem, check for both libraries together
- # if -lsocket doesn't work by itself.
- #--------------------------------------------------------------------
-
- tcl_checkBoth=0
- AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
- if test "$tcl_checkSocket" = 1; then
- AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
- LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
- fi
- if test "$tcl_checkBoth" = 1; then
- tk_oldLibs=$LIBS
- LIBS="$LIBS -lsocket -lnsl"
- AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
- fi
- AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
- [LIBS="$LIBS -lnsl"])])
-
- # TEA specific: Don't perform the eval of the libraries here because
- # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
-
- TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
- AC_SUBST(TCL_LIBS)
- AC_SUBST(MATH_LIBS)
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_EARLY_FLAGS
-#
-# Check for what flags are needed to be passed so the correct OS
-# features are available.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# _ISOC99_SOURCE
-# _LARGEFILE64_SOURCE
-# _LARGEFILE_SOURCE64
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_EARLY_FLAG],[
- AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
- AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
- AC_TRY_COMPILE([[#define ]$1[ 1
-]$2], $3,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
- [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
- if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
- AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
- tcl_flags="$tcl_flags $1"
- fi
-])
-
-AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
- AC_MSG_CHECKING([for required early compiler flags])
- tcl_flags=""
- TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
- [char *p = (char *)strtoll; char *q = (char *)strtoull;])
- TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
- [struct stat64 buf; int i = stat64("/", &buf);])
- TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
- [char *p = (char *)open64;])
- if test "x${tcl_flags}" = "x" ; then
- AC_MSG_RESULT([none])
- else
- AC_MSG_RESULT([${tcl_flags}])
- fi
-])
-
-#--------------------------------------------------------------------
-# TEA_TCL_64BIT_FLAGS
-#
-# Check for what is defined in the way of 64-bit features.
-#
-# Arguments:
-# None
-#
-# Results:
-#
-# Might define the following vars:
-# TCL_WIDE_INT_IS_LONG
-# TCL_WIDE_INT_TYPE
-# HAVE_STRUCT_DIRENT64
-# HAVE_STRUCT_STAT64
-# HAVE_TYPE_OFF64_T
-#--------------------------------------------------------------------
-
-AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
- AC_MSG_CHECKING([for 64-bit integer type])
- AC_CACHE_VAL(tcl_cv_type_64bit,[
- tcl_cv_type_64bit=none
- # See if the compiler knows natively about __int64
- AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
- tcl_type_64bit=__int64, tcl_type_64bit="long long")
- # See if we should use long anyway Note that we substitute in the
- # type that is our current guess for a 64-bit type inside this check
- # program, so it should be modified only carefully...
- AC_TRY_COMPILE(,[switch (0) {
- case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
- }],tcl_cv_type_64bit=${tcl_type_64bit})])
- if test "${tcl_cv_type_64bit}" = none ; then
- AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
- AC_MSG_RESULT([using long])
- elif test "${tcl_cv_type_64bit}" = "__int64" \
- -a "${TEA_PLATFORM}" = "windows" ; then
- # TEA specific: We actually want to use the default tcl.h checks in
- # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
- AC_MSG_RESULT([using Tcl header defaults])
- else
- AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
- [What type should be used to define wide integers?])
- AC_MSG_RESULT([${tcl_cv_type_64bit}])
-
- # Now check for auxiliary declarations
- AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
- AC_TRY_COMPILE([#include <sys/types.h>
-#include <dirent.h>],[struct dirent64 p;],
- tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
- if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
- fi
-
- AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
- AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
-],
- tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
- if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
- AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
- fi
-
- AC_CHECK_FUNCS(open64 lseek64)
- AC_MSG_CHECKING([for off64_t])
- AC_CACHE_VAL(tcl_cv_type_off64_t,[
- AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
-],
- tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
- dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
- dnl functions lseek64 and open64 are defined.
- if test "x${tcl_cv_type_off64_t}" = "xyes" && \
- test "x${ac_cv_func_lseek64}" = "xyes" && \
- test "x${ac_cv_func_open64}" = "xyes" ; then
- AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- fi
-])
-
-##
-## Here ends the standard Tcl configuration bits and starts the
-## TEA specific functions
-##
-
-#------------------------------------------------------------------------
-# TEA_INIT --
-#
-# Init various Tcl Extension Architecture (TEA) variables.
-# This should be the first called TEA_* macro.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Defines and substs the following vars:
-# CYGPATH
-# EXEEXT
-# Defines only:
-# TEA_VERSION
-# TEA_INITED
-# TEA_PLATFORM (windows or unix)
-#
-# "cygpath" is used on windows to generate native path names for include
-# files. These variables should only be used with the compiler and linker
-# since they generate native path names.
-#
-# EXEEXT
-# Select the executable extension based on the host type. This
-# is a lightweight replacement for AC_EXEEXT that doesn't require
-# a compiler.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_INIT], [
- # TEA extensions pass this us the version of TEA they think they
- # are compatible with.
- TEA_VERSION="3.10"
-
- AC_MSG_CHECKING([for correct TEA configuration])
- if test x"${PACKAGE_NAME}" = x ; then
- AC_MSG_ERROR([
-The PACKAGE_NAME variable must be defined by your TEA configure.ac])
- fi
- if test x"$1" = x ; then
- AC_MSG_ERROR([
-TEA version not specified.])
- elif test "$1" != "${TEA_VERSION}" ; then
- AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
- else
- AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
- fi
-
- # 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_*)
- AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
- 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
-
- AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
-
- AC_SUBST(EXEEXT)
- AC_SUBST(CYGPATH)
-
- # This package name must be replaced statically for AC_SUBST to work
- AC_SUBST(PKG_LIB_FILE)
- # Substitute STUB_LIB_FILE in case package creates a stub library too.
- AC_SUBST(PKG_STUB_LIB_FILE)
-
- # We AC_SUBST these here to ensure they are subst'ed,
- # in case the user doesn't call TEA_ADD_...
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
- AC_SUBST(PKG_TCL_SOURCES)
- AC_SUBST(PKG_HEADERS)
- AC_SUBST(PKG_INCLUDES)
- AC_SUBST(PKG_LIBS)
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_SOURCES
-# PKG_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_SOURCES], [
- vars="$@"
- for i in $vars; do
- case $i in
- [\$]*)
- # allow $-var names
- PKG_SOURCES="$PKG_SOURCES $i"
- PKG_OBJECTS="$PKG_OBJECTS $i"
- ;;
- *)
- # check for existence - allows for generic/win/unix VPATH
- # To add more dirs here (like 'src'), you have to update VPATH
- # in Makefile.in as well
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find source file '$i'])
- fi
- PKG_SOURCES="$PKG_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_OBJECTS="$PKG_OBJECTS $j"
- ;;
- esac
- done
- AC_SUBST(PKG_SOURCES)
- AC_SUBST(PKG_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_STUB_SOURCES --
-#
-# Specify one or more source files. Users should check for
-# the right platform before adding to their list.
-# It is not important to specify the directory, as long as it is
-# in the generic, win or unix subdirectory of $(srcdir).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_STUB_SOURCES
-# PKG_STUB_OBJECTS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_STUB_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence - allows for generic/win/unix VPATH
- if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
- -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
- -a ! -f "${srcdir}/macosx/$i" \
- ; then
- AC_MSG_ERROR([could not find stub source file '$i'])
- fi
- PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
- # this assumes it is in a VPATH dir
- i=`basename $i`
- # handle user calling this before or after TEA_SETUP_COMPILER
- if test x"${OBJEXT}" != x ; then
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
- else
- j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
- fi
- PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
- done
- AC_SUBST(PKG_STUB_SOURCES)
- AC_SUBST(PKG_STUB_OBJECTS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_TCL_SOURCES --
-#
-# Specify one or more Tcl source files. These should be platform
-# independent runtime files.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_TCL_SOURCES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_TCL_SOURCES], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
- fi
- PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
- done
- AC_SUBST(PKG_TCL_SOURCES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_HEADERS --
-#
-# Specify one or more source headers. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_HEADERS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_HEADERS], [
- vars="$@"
- for i in $vars; do
- # check for existence, be strict because it is installed
- if test ! -f "${srcdir}/$i" ; then
- AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
- fi
- PKG_HEADERS="$PKG_HEADERS $i"
- done
- AC_SUBST(PKG_HEADERS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_INCLUDES --
-#
-# Specify one or more include dirs. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_INCLUDES
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_INCLUDES], [
- vars="$@"
- for i in $vars; do
- PKG_INCLUDES="$PKG_INCLUDES $i"
- done
- AC_SUBST(PKG_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_LIBS --
-#
-# Specify one or more libraries. Users should check for
-# the right platform before adding to their list. For Windows,
-# libraries provided in "foo.lib" format will be converted to
-# "-lfoo" when using GCC (mingw).
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_LIBS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_LIBS], [
- vars="$@"
- for i in $vars; do
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
- # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
- i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
- fi
- PKG_LIBS="$PKG_LIBS $i"
- done
- AC_SUBST(PKG_LIBS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CFLAGS --
-#
-# Specify one or more CFLAGS. Users should check for
-# the right platform before adding to their list.
-#
-# Arguments:
-# one or more file names
-#
-# Results:
-#
-# Defines and substs the following vars:
-# PKG_CFLAGS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CFLAGS], [
- PKG_CFLAGS="$PKG_CFLAGS $@"
- AC_SUBST(PKG_CFLAGS)
-])
-
-#------------------------------------------------------------------------
-# TEA_ADD_CLEANFILES --
-#
-# Specify one or more CLEANFILES.
-#
-# Arguments:
-# one or more file names to clean target
-#
-# Results:
-#
-# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ADD_CLEANFILES], [
- CLEANFILES="$CLEANFILES $@"
-])
-
-#------------------------------------------------------------------------
-# TEA_PREFIX --
-#
-# Handle the --prefix=... option by defaulting to what Tcl gave
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# If --prefix or --exec-prefix was not specified, $prefix and
-# $exec_prefix will be set to the values given to Tcl when it was
-# configured.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_PREFIX], [
- if test "${prefix}" = "NONE"; then
- prefix_default=yes
- if test x"${TCL_PREFIX}" != x; then
- AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
- prefix=${TCL_PREFIX}
- else
- AC_MSG_NOTICE([--prefix defaulting to /usr/local])
- prefix=/usr/local
- fi
- fi
- if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
- -o x"${exec_prefix_default}" = x"yes" ; then
- if test x"${TCL_EXEC_PREFIX}" != x; then
- AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
- exec_prefix=${TCL_EXEC_PREFIX}
- else
- AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
- exec_prefix=$prefix
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER_CC --
-#
-# Do compiler checks the way we want. This is just a replacement
-# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER_CC], [
- # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
- # in this macro, they need to go into TEA_SETUP_COMPILER instead.
-
- AC_PROG_CC
- AC_PROG_CPP
-
- 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}'
-
- AC_SUBST(INSTALL)
- AC_SUBST(INSTALL_DATA_DIR)
- AC_SUBST(INSTALL_DATA)
- AC_SUBST(INSTALL_PROGRAM)
- AC_SUBST(INSTALL_SCRIPT)
- AC_SUBST(INSTALL_LIBRARY)
-
- #--------------------------------------------------------------------
- # Checks to see if the make program sets the $MAKE variable.
- #--------------------------------------------------------------------
-
- AC_PROG_MAKE_SET
-
- #--------------------------------------------------------------------
- # Find ranlib
- #--------------------------------------------------------------------
-
- AC_CHECK_TOOL(RANLIB, ranlib)
-
- #--------------------------------------------------------------------
- # Determines the correct binary file extension (.o, .obj, .exe etc.)
- #--------------------------------------------------------------------
-
- AC_OBJEXT
- AC_EXEEXT
-])
-
-#------------------------------------------------------------------------
-# TEA_SETUP_COMPILER --
-#
-# Do compiler checks that use the compiler. This must go after
-# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Sets up CC var and other standard bits we need to make executables.
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_SETUP_COMPILER], [
- # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
- AC_REQUIRE([TEA_SETUP_COMPILER_CC])
-
- #------------------------------------------------------------------------
- # If we're using GCC, see if the compiler understands -pipe. If so, use it.
- # It makes compiling go faster. (This is only a performance feature.)
- #------------------------------------------------------------------------
-
- if test -z "$no_pipe" -a -n "$GCC"; then
- AC_CACHE_CHECK([if the compiler understands -pipe],
- tcl_cv_cc_pipe, [
- hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
- AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
- CFLAGS=$hold_cflags])
- if test $tcl_cv_cc_pipe = yes; then
- CFLAGS="$CFLAGS -pipe"
- fi
- fi
-
- #--------------------------------------------------------------------
- # Common compiler flag setup
- #--------------------------------------------------------------------
-
- AC_C_BIGENDIAN
- if test "${TEA_PLATFORM}" = "unix" ; then
- TEA_TCL_LINK_LIBS
- TEA_MISSING_POSIX_HEADERS
- # Let the user call this, because if it triggers, they will
- # need a compat/strtod.c that is correct. Users can also
- # use Tcl_GetDouble(FromObj) instead.
- #TEA_BUGGY_STRTOD
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_MAKE_LIB --
-#
-# Generate a line that can be used to build a shared/unshared library
-# in a platform independent manner.
-#
-# Arguments:
-# none
-#
-# Requires:
-#
-# Results:
-#
-# Defines the following vars:
-# CFLAGS - Done late here to note disturb other AC macros
-# MAKE_LIB - Command to execute to build the Tcl library;
-# differs depending on whether or not Tcl is being
-# compiled as a shared library.
-# MAKE_SHARED_LIB Makefile rule for building a shared library
-# MAKE_STATIC_LIB Makefile rule for building a static library
-# MAKE_STUB_LIB Makefile rule for building a stub library
-# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
-# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_MAKE_LIB], [
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
- MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
- MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
- AC_EGREP_CPP([manifest needed], [
-#if defined(_MSC_VER) && _MSC_VER >= 1400
-print("manifest needed")
-#endif
- ], [
- # 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}"
- TEA_ADD_CLEANFILES([*.manifest])
- ])
- 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
-
- AC_SUBST(MAKE_LIB)
- AC_SUBST(MAKE_SHARED_LIB)
- AC_SUBST(MAKE_STATIC_LIB)
- AC_SUBST(MAKE_STUB_LIB)
- AC_SUBST(RANLIB_STUB)
- AC_SUBST(VC_MANIFEST_EMBED_DLL)
- AC_SUBST(VC_MANIFEST_EMBED_EXE)
-])
-
-#------------------------------------------------------------------------
-# TEA_LIB_SPEC --
-#
-# Compute the name of an existing object library located in libdir
-# from the given base name and produce the appropriate linker flags.
-#
-# Arguments:
-# basename The base name of the library without version
-# numbers, extensions, or "lib" prefixes.
-# extra_dir Extra directory in which to search for the
-# library. This location is used first, then
-# $prefix/$exec-prefix, then some defaults.
-#
-# Requires:
-# TEA_INIT and TEA_PREFIX must be called first.
-#
-# Results:
-#
-# Defines the following vars:
-# ${basename}_LIB_NAME The computed library name.
-# ${basename}_LIB_SPEC The computed linker flags.
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LIB_SPEC], [
- AC_MSG_CHECKING([for $1 library])
-
- # Look in exec-prefix for the library (defined by TEA_PREFIX).
-
- tea_lib_name_dir="${exec_prefix}/lib"
-
- # Or in a user-specified location.
-
- if test x"$2" != x ; then
- tea_extra_lib_dir=$2
- else
- tea_extra_lib_dir=NONE
- fi
-
- for i in \
- `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
- `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
- `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
- if test -f "$i" ; then
- tea_lib_name_dir=`dirname $i`
- $1_LIB_NAME=`basename $i`
- $1_LIB_PATH_NAME=$i
- break
- fi
- done
-
- if test "${TEA_PLATFORM}" = "windows"; then
- $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
- else
- # Strip off the leading "lib" and trailing ".a" or ".so"
-
- tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
- $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
- fi
-
- if test "x${$1_LIB_NAME}" = x ; then
- AC_MSG_ERROR([not found])
- else
- AC_MSG_RESULT([${$1_LIB_SPEC}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TCL_HEADERS --
-#
-# Locate the private Tcl include files
-#
-# Arguments:
-#
-# Requires:
-# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TCL_TOP_DIR_NATIVE
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
- # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
- AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
- AC_MSG_CHECKING([for Tcl private include files])
-
- TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
- TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
-
- # Check to see if tcl<Plat>Port.h isn't already with the public headers
- # Don't look for tclInt.h because that resides with tcl.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tclh}/tclWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
- result="private headers found with public headers"
- else
- TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
- else
- TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TCL_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- if test -d "${TCL_BIN_DIR}/Headers" -a \
- -d "${TCL_BIN_DIR}/PrivateHeaders"; then
- TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
- else
- TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TCL_INCLUDES}"
- else
- if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
- fi
- result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TCL_TOP_DIR_NATIVE)
-
- AC_SUBST(TCL_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TCL_HEADERS --
-#
-# Locate the installed public Tcl header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tclinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TCL_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
- AC_MSG_CHECKING([for Tcl public headers])
-
- AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tclh, [
- # Use the value from --with-tclinclude, if it was given
-
- if test x"${with_tclinclude}" != x ; then
- if test -f "${with_tclinclude}/tcl.h" ; then
- ac_cv_c_tclh=${with_tclinclude}
- else
- AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tcl was built as a framework, attempt to use
- # the framework's Headers directory
- case ${TCL_DEFS} in
- *TCL_FRAMEWORK*)
- list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tcl is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TCL_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TCL_INCLUDE_SPEC}" != x ; then
- d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tcl.h" ; then
- ac_cv_c_tclh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tclh}" = x ; then
- AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tclh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
-
- TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TCL_INCLUDES)
-])
-
-#------------------------------------------------------------------------
-# TEA_PRIVATE_TK_HEADERS --
-#
-# Locate the private Tk include files
-#
-# Arguments:
-#
-# Requires:
-# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
-# already been called.
-#
-# Results:
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
- # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
- AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
- AC_MSG_CHECKING([for Tk private include files])
-
- TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
- TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
-
- # Check to see if tk<Plat>Port.h isn't already with the public headers
- # Don't look for tkInt.h because that resides with tk.h in the core
- # sources, but the <plat>Port headers are in a different directory
- if test "${TEA_PLATFORM}" = "windows" -a \
- -f "${ac_cv_c_tkh}/tkWinPort.h"; then
- result="private headers found with public headers"
- elif test "${TEA_PLATFORM}" = "unix" -a \
- -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
- result="private headers found with public headers"
- else
- TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
- TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
- if test "${TEA_PLATFORM}" = "windows"; then
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
- else
- TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
- fi
- # Overwrite the previous TK_INCLUDES as this should capture both
- # public and private headers in the same set.
- # We want to ensure these are substituted so as not to require
- # any *_NATIVE vars be defined in the Makefile
- TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
- # Detect and add ttk subdir
- if test -d "${TK_SRC_DIR}/generic/ttk"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
- fi
- if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
- TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
- fi
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers and PrivateHeaders directories
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- if test -d "${TK_BIN_DIR}/Headers" -a \
- -d "${TK_BIN_DIR}/PrivateHeaders"; then
- TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
- else
- TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
- fi
- ;;
- esac
- result="Using ${TK_INCLUDES}"
- else
- if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
- AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
- fi
- result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
- fi
- fi
-
- AC_SUBST(TK_TOP_DIR_NATIVE)
- AC_SUBST(TK_XLIB_DIR_NATIVE)
-
- AC_SUBST(TK_INCLUDES)
- AC_MSG_RESULT([${result}])
-])
-
-#------------------------------------------------------------------------
-# TEA_PUBLIC_TK_HEADERS --
-#
-# Locate the installed public Tk header files
-#
-# Arguments:
-# None.
-#
-# Requires:
-# CYGPATH must be set
-#
-# Results:
-#
-# Adds a --with-tkinclude switch to configure.
-# Result is cached.
-#
-# Substitutes the following vars:
-# TK_INCLUDES
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
- AC_MSG_CHECKING([for Tk public headers])
-
- AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
-
- AC_CACHE_VAL(ac_cv_c_tkh, [
- # Use the value from --with-tkinclude, if it was given
-
- if test x"${with_tkinclude}" != x ; then
- if test -f "${with_tkinclude}/tk.h" ; then
- ac_cv_c_tkh=${with_tkinclude}
- else
- AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
- fi
- else
- list=""
- if test "`uname -s`" = "Darwin"; then
- # If Tk was built as a framework, attempt to use
- # the framework's Headers directory.
- case ${TK_DEFS} in
- *TK_FRAMEWORK*)
- list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
- ;;
- esac
- fi
-
- # Look in the source dir only if Tk is not installed,
- # and in that situation, look there before installed locations.
- if test -f "${TK_BIN_DIR}/Makefile" ; then
- list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
- fi
-
- # Check order: pkg --prefix location, Tk's --prefix location,
- # relative to directory of tkConfig.sh, Tcl's --prefix location,
- # relative to directory of tclConfig.sh.
-
- eval "temp_includedir=${includedir}"
- list="$list \
- `ls -d ${temp_includedir} 2>/dev/null` \
- `ls -d ${TK_PREFIX}/include 2>/dev/null` \
- `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
- `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
- `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
- if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
- list="$list /usr/local/include /usr/include"
- if test x"${TK_INCLUDE_SPEC}" != x ; then
- d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
- list="$list `ls -d ${d} 2>/dev/null`"
- fi
- fi
- for i in $list ; do
- if test -f "$i/tk.h" ; then
- ac_cv_c_tkh=$i
- break
- fi
- done
- fi
- ])
-
- # Print a message based on how we determined the include path
-
- if test x"${ac_cv_c_tkh}" = x ; then
- AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
- else
- AC_MSG_RESULT([${ac_cv_c_tkh}])
- fi
-
- # Convert to a native path and substitute into the output files.
-
- INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
-
- TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
-
- AC_SUBST(TK_INCLUDES)
-
- if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
- # On Windows and Aqua, we need the X compat headers
- AC_MSG_CHECKING([for X11 header files])
- if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
- INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
- TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
- AC_SUBST(TK_XINCLUDES)
- fi
- AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_PATH_CONFIG --
-#
-# Locate the ${1}Config.sh file and perform a sanity check on
-# the ${1} compile flags. These are used by packages like
-# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-$1=...
-#
-# Defines the following vars:
-# $1_BIN_DIR Full path to the directory containing
-# the $1Config.sh file
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CONFIG], [
- #
- # Ok, lets find the $1 configuration
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-$1
- #
-
- if test x"${no_$1}" = x ; then
- # we reset no_$1 in case something fails here
- no_$1=true
- AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
- AC_MSG_CHECKING([for $1 configuration])
- AC_CACHE_VAL(ac_cv_c_$1config,[
-
- # First check to see if --with-$1 was specified.
- if test x"${with_$1config}" != x ; then
- case ${with_$1config} in
- */$1Config.sh )
- if test -f ${with_$1config}; then
- AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
- with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
- fi;;
- esac
- if test -f "${with_$1config}/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
- else
- AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
- fi
- fi
-
- # then check for a private $1 installation
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in \
- ../$1 \
- `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../$1 \
- `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ../../../$1 \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ${srcdir}/../$1 \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
- `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- if test -f "$i/unix/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i/unix; pwd)`
- break
- fi
- done
- fi
-
- # check in a few common install locations
- if test x"${ac_cv_c_$1config}" = x ; then
- for i in `ls -d ${libdir} 2>/dev/null` \
- `ls -d ${exec_prefix}/lib 2>/dev/null` \
- `ls -d ${prefix}/lib 2>/dev/null` \
- `ls -d /usr/local/lib 2>/dev/null` \
- `ls -d /usr/contrib/lib 2>/dev/null` \
- `ls -d /usr/lib 2>/dev/null` \
- `ls -d /usr/lib64 2>/dev/null` \
- ; do
- if test -f "$i/$1Config.sh" ; then
- ac_cv_c_$1config=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
-
- if test x"${ac_cv_c_$1config}" = x ; then
- $1_BIN_DIR="# no $1 configs found"
- AC_MSG_WARN([Cannot find $1 configuration definitions])
- exit 0
- else
- no_$1=
- $1_BIN_DIR=${ac_cv_c_$1config}
- AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
- fi
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG --
-#
-# Load the $1Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1_BIN_DIR
-#
-# Results:
-#
-# Substitutes the following vars:
-# $1_SRC_DIR
-# $1_LIB_FILE
-# $1_LIB_SPEC
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_LOAD_CONFIG], [
- AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
-
- if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
- AC_MSG_RESULT([loading])
- . "${$1_BIN_DIR}/$1Config.sh"
- else
- AC_MSG_RESULT([file not found])
- fi
-
- #
- # If the $1_BIN_DIR is the build directory (not the install directory),
- # then set the common variable name to the value of the build variables.
- # For example, the variable $1_LIB_SPEC will be set to the value
- # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
- # instead of $1_BUILD_LIB_SPEC since it will work with both an
- # installed and uninstalled version of Tcl.
- #
-
- if test -f "${$1_BIN_DIR}/Makefile" ; then
- AC_MSG_WARN([Found Makefile - using build library specs for $1])
- $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
- $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
- $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
- $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
- $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
- fi
-
- AC_SUBST($1_VERSION)
- AC_SUBST($1_BIN_DIR)
- AC_SUBST($1_SRC_DIR)
-
- AC_SUBST($1_LIB_FILE)
- AC_SUBST($1_LIB_SPEC)
-
- AC_SUBST($1_STUB_LIB_FILE)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_PATH)
-
- # Allow the caller to prevent this auto-check by specifying any 2nd arg
- AS_IF([test "x$2" = x], [
- # Check both upper and lower-case variants
- # If a dev wanted non-stubs libs, this function could take an option
- # to not use _STUB in the paths below
- AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
- [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
- [TEA_LOAD_CONFIG_LIB($1_STUB)])
- ])
-])
-
-#------------------------------------------------------------------------
-# TEA_LOAD_CONFIG_LIB --
-#
-# Helper function to load correct library from another extension's
-# ${PACKAGE}Config.sh.
-#
-# Results:
-# Adds to LIBS the appropriate extension library
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
- AC_MSG_CHECKING([For $1 library for LIBS])
- # This simplifies the use of stub libraries by automatically adding
- # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
- # but this is called before CONFIG_CFLAGS. More importantly, this adds
- # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
- if test "x${$1_LIB_SPEC}" != "x" ; then
- if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
- TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
- AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
- else
- TEA_ADD_LIBS([${$1_LIB_SPEC}])
- AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
- fi
- else
- AC_MSG_RESULT([file not found])
- fi
-])
-
-#------------------------------------------------------------------------
-# TEA_EXPORT_CONFIG --
-#
-# Define the data to insert into the ${PACKAGE}Config.sh file
-#
-# Arguments:
-#
-# Requires the following vars to be set:
-# $1
-#
-# Results:
-# Substitutes the following vars:
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_EXPORT_CONFIG], [
- #--------------------------------------------------------------------
- # These are for $1Config.sh
- #--------------------------------------------------------------------
-
- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
- eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
- if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
- eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
- else
- eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
- fi
- $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
- $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
- $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
- $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
- $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
- $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
-
- AC_SUBST($1_BUILD_LIB_SPEC)
- AC_SUBST($1_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_SPEC)
- AC_SUBST($1_STUB_LIB_SPEC)
- AC_SUBST($1_BUILD_STUB_LIB_PATH)
- AC_SUBST($1_STUB_LIB_PATH)
-
- AC_SUBST(MAJOR_VERSION)
- AC_SUBST(MINOR_VERSION)
- AC_SUBST(PATCHLEVEL)
-])
-
-
-#------------------------------------------------------------------------
-# TEA_PATH_CELIB --
-#
-# Locate Keuchel's celib emulation layer for targeting Win/CE
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Adds the following arguments to configure:
-# --with-celib=...
-#
-# Defines the following vars:
-# CELIB_DIR Full path to the directory containing
-# the include and platform lib files
-#------------------------------------------------------------------------
-
-AC_DEFUN([TEA_PATH_CELIB], [
- # First, look for one uninstalled.
- # the alternative search directory is invoked by --with-celib
-
- if test x"${no_celib}" = x ; then
- # we reset no_celib in case something fails here
- no_celib=true
- AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
- AC_MSG_CHECKING([for Windows/CE celib directory])
- AC_CACHE_VAL(ac_cv_c_celibconfig,[
- # First check to see if --with-celibconfig was specified.
- if test x"${with_celibconfig}" != x ; then
- if test -d "${with_celibconfig}/inc" ; then
- ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
- else
- AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
- fi
- fi
-
- # then check for a celib library
- if test x"${ac_cv_c_celibconfig}" = x ; then
- for i in \
- ../celib-palm-3.0 \
- ../celib \
- ../../celib-palm-3.0 \
- ../../celib \
- `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
- ${srcdir}/../celib-palm-3.0 \
- ${srcdir}/../celib \
- `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
- ; do
- if test -d "$i/inc" ; then
- ac_cv_c_celibconfig=`(cd $i; pwd)`
- break
- fi
- done
- fi
- ])
- if test x"${ac_cv_c_celibconfig}" = x ; then
- AC_MSG_ERROR([Cannot find celib support library directory])
- else
- no_celib=
- CELIB_DIR=${ac_cv_c_celibconfig}
- CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
- AC_MSG_RESULT([found $CELIB_DIR])
- fi
- fi
-])
-
-###
-# Tip 430 - ZipFS Modifications
-###
-#------------------------------------------------------------------------
-# SC_ZIPFS_SUPPORT
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# TCL_ZIP_FILE
-# TCL_ZIPFS_SUPPORT
-# TCL_ZIPFS_FLAG
-# ZIP_PROG
-#------------------------------------------------------------------------
-
-#------------------------------------------------------------------------
-# SC_PROG_ZIP
-# Locate a zip encoder installed on the system path, or none.
-#
-# Arguments:
-# none
-#
-# Results:
-# Substitutes the following vars:
-# ZIP_PROG
-# ZIP_PROG_OPTIONS
-# ZIP_PROG_VFSSEARCH
-# ZIP_INSTALL_OBJS
-#------------------------------------------------------------------------
-AC_DEFUN([TEA_ZIPFS_SUPPORT], [
- AC_MSG_CHECKING([for zipfs support])
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- INSTALL_MSGS=""
- # If our native tclsh processes the "install" command line option
- # we can use it to mint zip files
- AS_IF([$TCLSH_PROG install],[
- ZIP_PROG=${TCLSH_PROG}
- ZIP_PROG_OPTIONS="install mkzip"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
- ])
- if test "x$ZIP_PROG" = "x" ; then
- AC_CACHE_VAL(ac_cv_path_zip, [
- search_path=`echo ${PATH} | sed -e 's/:/ /g'`
- for dir in $search_path ; do
- for j in `ls -r $dir/zip 2> /dev/null` \
- `ls -r $dir/zip 2> /dev/null` ; do
- if test x"$ac_cv_path_zip" = x ; then
- if test -f "$j" ; then
- ac_cv_path_zip=$j
- break
- fi
- fi
- done
- done
- ])
- if test -f "$ac_cv_path_zip" ; then
- ZIP_PROG="$ac_cv_path_zip "
- AC_MSG_RESULT([$ZIP_PROG])
- ZIP_PROG_OPTIONS="-rq"
- ZIP_PROG_VFSSEARCH="."
- AC_MSG_RESULT([Found INFO Zip in environment])
- # Use standard arguments for zip
- fi
- fi
- if test "x$ZIP_PROG" = "x" ; then
- # It is not an error if an installed version of Zip can't be located.
- ZIP_PROG=""
- ZIP_PROG_OPTIONS=""
- ZIP_PROG_VFSSEARCH=""
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- else
- # ZIPFS Support
- eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
- if test ${TCL_ZIP_FILE} = "" ; then
- TCL_ZIPFS_SUPPORT=0
- TCL_ZIPFS_FLAG=
- INSTALL_LIBRARIES=install-libraries
- INSTALL_MSGS=install-msgs
- else
- if test ${SHARED_BUILD} = 1 ; then
- TCL_ZIPFS_SUPPORT=1
- INSTALL_LIBRARIES=install-libraries-zipfs-shared
- else
- TCL_ZIPFS_SUPPORT=2
- INSTALL_LIBRARIES=install-libraries-zipfs-static
- fi
- TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
- fi
- fi
-
- AC_SUBST(TCL_ZIP_FILE)
- AC_SUBST(TCL_ZIPFS_SUPPORT)
- AC_SUBST(TCL_ZIPFS_FLAG)
- AC_SUBST(ZIP_PROG)
- AC_SUBST(ZIP_PROG_OPTIONS)
- AC_SUBST(ZIP_PROG_VFSSEARCH)
- AC_SUBST(INSTALL_LIBRARIES)
- AC_SUBST(INSTALL_MSGS)
-])
-
-# Local Variables:
-# mode: autoconf
-# End:
diff --git a/tcl8.6/pkgs/thread2.8.2/win/targets.vc b/tcl8.6/pkgs/thread2.8.2/win/targets.vc
deleted file mode 100644
index 312022d..0000000
--- a/tcl8.6/pkgs/thread2.8.2/win/targets.vc
+++ /dev/null
@@ -1,98 +0,0 @@
-#------------------------------------------------------------- -*- makefile -*-
-# targets.vc --
-#
-# Part of the nmake based build system for Tcl and its extensions.
-# This file defines some standard targets for the convenience of extensions
-# and can be optionally included by the extension makefile.
-# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
-
-$(PROJECT): setup pkgindex $(PRJLIB)
-
-!ifdef PRJ_STUBOBJS
-$(PROJECT): $(PRJSTUBLIB)
-$(PRJSTUBLIB): $(PRJ_STUBOBJS)
- $(LIBCMD) $**
-
-$(PRJ_STUBOBJS):
- $(CCSTUBSCMD) %s
-!endif # PRJ_STUBOBJS
-
-!ifdef PRJ_MANIFEST
-$(PROJECT): $(PRJLIB).manifest
-$(PRJLIB).manifest: $(PRJ_MANIFEST)
- @nmakehlp -s << $** >$@
-@MACHINE@ $(MACHINE:IX86=X86)
-<<
-!endif
-
-!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
-$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-!if $(STATIC_BUILD)
- $(LIBCMD) $**
-!else
- $(DLLCMD) $**
- $(_VC_MANIFEST_EMBED_DLL)
-!endif
- -@del $*.exp
-!endif
-
-!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
-$(PRJ_OBJS): $(PRJ_HEADERS)
-!endif
-
-# If parent makefile has defined stub objects, add their installation
-# to the default install
-!if "$(PRJ_STUBOBJS)" != ""
-default-install: default-install-stubs
-!endif
-
-# Unlike the other default targets, these cannot be in rules.vc because
-# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
-# that the parent makefile will not define until after including rules-ext.vc
-!if "$(PRJ_HEADERS_PUBLIC)" != ""
-default-install: default-install-headers
-default-install-headers:
- @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
- @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
-!endif
-
-!if "$(DISABLE_STANDARD_TARGETS)" == ""
-DISABLE_STANDARD_TARGETS = 0
-!endif
-
-!if "$(DISABLE_TARGET_setup)" == ""
-DISABLE_TARGET_setup = 0
-!endif
-!if "$(DISABLE_TARGET_install)" == ""
-DISABLE_TARGET_install = 0
-!endif
-!if "$(DISABLE_TARGET_clean)" == ""
-DISABLE_TARGET_clean = 0
-!endif
-!if "$(DISABLE_TARGET_test)" == ""
-DISABLE_TARGET_test = 0
-!endif
-!if "$(DISABLE_TARGET_shell)" == ""
-DISABLE_TARGET_shell = 0
-!endif
-
-!if !$(DISABLE_STANDARD_TARGETS)
-!if !$(DISABLE_TARGET_setup)
-setup: default-setup
-!endif
-!if !$(DISABLE_TARGET_install)
-install: default-install
-!endif
-!if !$(DISABLE_TARGET_clean)
-clean: default-clean
-realclean: hose
-hose: default-hose
-distclean: realclean default-distclean
-!endif
-!if !$(DISABLE_TARGET_test)
-test: default-test
-!endif
-!if !$(DISABLE_TARGET_shell)
-shell: default-shell
-!endif
-!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/thread2.8.2/ChangeLog b/tcl8.6/pkgs/thread2.8.4/ChangeLog
index 79452cc..79452cc 100644
--- a/tcl8.6/pkgs/thread2.8.2/ChangeLog
+++ b/tcl8.6/pkgs/thread2.8.4/ChangeLog
diff --git a/tcl8.6/pkgs/thread2.8.2/Makefile.in b/tcl8.6/pkgs/thread2.8.4/Makefile.in
index 27cbe63..8356eea 100644
--- a/tcl8.6/pkgs/thread2.8.2/Makefile.in
+++ b/tcl8.6/pkgs/thread2.8.4/Makefile.in
@@ -86,7 +86,7 @@ pkgincludedir = $(includedir)/$(PKG_DIR)
top_builddir = .
INSTALL_OPTIONS =
-INSTALL = @INSTALL@ ${INSTALL_OPTIONS}
+INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -156,7 +156,7 @@ PKG_CFLAGS = @PKG_CFLAGS@
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
-DEFS = @DEFS@ $(PKG_CFLAGS)
+DEFS = @DEFS@ $(PKG_CFLAGS) -DTCL_NO_DEPRECATED=1
# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
@@ -230,13 +230,12 @@ install-doc: doc
@echo "Installing documentation in $(DESTDIR)$(mandir)"
@list='$(srcdir)/doc/man/*.n'; for i in $$list; do \
echo "Installing $$i"; \
- rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
done
test: binaries libraries
$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \
- -load "package ifneeded ${PACKAGE_NAME} ${PACKAGE_VERSION} \
+ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
[list load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME)]"
shell: binaries libraries
@@ -307,43 +306,50 @@ COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
+DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
+DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
+
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
dist: dist-clean
$(INSTALL_DATA_DIR) $(DIST_DIR)
- cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license.terms \
- $(srcdir)/aclocal.m4 $(srcdir)/naviserver.m4 $(srcdir)/configure \
- $(srcdir)/*.in $(srcdir)/configure.ac $(DIST_DIR)/
- chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
- chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.ac
+ $(DIST_INSTALL_DATA) $(srcdir)/license.terms \
+ $(srcdir)/ChangeLog $(srcdir)/README \
+ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
+ $(srcdir)/Makefile.in $(srcdir)/pkgIndex.tcl.in \
+ $(srcdir)/naviserver.m4 \
+ $(DIST_DIR)/
+ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
- cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
+ $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
+ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
$(DIST_DIR)/tclconfig/
- chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
- chmod +x $(DIST_DIR)/tclconfig/install-sh
$(INSTALL_DATA_DIR) $(DIST_DIR)/unix
- cp $(srcdir)/unix/README $(srcdir)/unix/CONFIG \
- $(srcdir)/unix/threadUnix.c $(DIST_DIR)/unix/
+ $(DIST_INSTALL_DATA) $(srcdir)/unix/README $(srcdir)/unix/CONFIG \
+ $(srcdir)/unix/threadUnix.c \
+ $(DIST_DIR)/unix/
$(INSTALL_DATA_DIR) $(DIST_DIR)/win
- cp $(srcdir)/win/README.txt $(srcdir)/win/CONFIG $(srcdir)/win/thread.rc \
+ $(DIST_INSTALL_DATA) \
+ $(srcdir)/win/README.txt $(srcdir)/win/CONFIG $(srcdir)/win/thread.rc \
$(srcdir)/win/threadWin.c $(srcdir)/win/makefile.vc \
$(srcdir)/win/nmakehlp.c $(srcdir)/win/pkg.vc \
$(srcdir)/win/targets.vc $(srcdir)/win/rules-ext.vc \
- $(srcdir)/win/rules.vc $(srcdir)/win/thread_win.dsw \
- $(srcdir)/win/thread_win.dsp $(DIST_DIR)/win/
+ $(srcdir)/win/rules.vc $(srcdir)/win/thread_win.dsw \
+ $(srcdir)/win/thread_win.dsp \
+ $(DIST_DIR)/win/
$(INSTALL_DATA_DIR) $(DIST_DIR)/tcl
- cp $(srcdir)/tcl/README $(DIST_DIR)/tcl/
+ $(DIST_INSTALL_DATA) $(srcdir)/tcl/README $(DIST_DIR)/tcl/
list='tests doc doc/man doc/html generic lib tcl/cmdsrv tcl/phttpd tcl/tpool';\
for p in $$list; do \
if test -d $(srcdir)/$$p ; then \
$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
- cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
+ $(DIST_INSTALL_DATA) $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
fi; \
done
diff --git a/tcl8.6/pkgs/thread2.8.2/README b/tcl8.6/pkgs/thread2.8.4/README
index 7ec98db..7ec98db 100644
--- a/tcl8.6/pkgs/thread2.8.2/README
+++ b/tcl8.6/pkgs/thread2.8.4/README
diff --git a/tcl8.6/pkgs/thread2.8.2/aclocal.m4 b/tcl8.6/pkgs/thread2.8.4/aclocal.m4
index 9a825fb..9a825fb 100644
--- a/tcl8.6/pkgs/thread2.8.2/aclocal.m4
+++ b/tcl8.6/pkgs/thread2.8.4/aclocal.m4
diff --git a/tcl8.6/pkgs/thread2.8.2/configure b/tcl8.6/pkgs/thread2.8.4/configure
index e5a32e6..1323630 100755
--- a/tcl8.6/pkgs/thread2.8.2/configure
+++ b/tcl8.6/pkgs/thread2.8.4/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for thread 2.8.2.
+# Generated by GNU Autoconf 2.69 for thread 2.8.4.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='thread'
PACKAGE_TARNAME='thread'
-PACKAGE_VERSION='2.8.2'
-PACKAGE_STRING='thread 2.8.2'
+PACKAGE_VERSION='2.8.4'
+PACKAGE_STRING='thread 2.8.4'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -648,17 +648,10 @@ 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
@@ -682,6 +675,12 @@ TCL_SRC_DIR
TCL_BIN_DIR
TCL_PATCH_LEVEL
TCL_VERSION
+INSTALL_LIBRARY
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+INSTALL_DATA
+INSTALL_DATA_DIR
+INSTALL
PKG_CFLAGS
PKG_LIBS
PKG_INCLUDES
@@ -1298,7 +1297,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 thread 2.8.2 to adapt to many kinds of systems.
+\`configure' configures thread 2.8.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1359,7 +1358,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of thread 2.8.2:";;
+ short | recursive ) echo "Configuration of thread 2.8.4:";;
esac
cat <<\_ACEOF
@@ -1464,7 +1463,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-thread configure 2.8.2
+thread configure 2.8.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1738,98 +1737,11 @@ $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.2, which was
+It was created by thread $as_me 2.8.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2185,26 +2097,16 @@ 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.10"
+ TEA_VERSION="3.13"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
-$as_echo_n "checking for correct TEA configuration... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking TEA configuration" >&5
+$as_echo_n "checking 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.10" = x ; then
- as_fn_error $? "
-TEA version not specified." "$LINENO" 5
- 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 "$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".
@@ -2213,7 +2115,7 @@ $as_echo "ok (TEA ${TEA_VERSION})" >&6; }
fi
case "`uname -s`" in
- *win32*|*WIN32*|*MINGW32_*)
+ *win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
# 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
@@ -2305,6 +2207,55 @@ $as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
+ # Configure the installer.
+
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+
+ { $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
+
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+
+
+
+
+
+
+
+
ac_aux_dir=
for ac_dir in tclconfig "$srcdir"/tclconfig; do
@@ -2414,6 +2365,9 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
`ls -d /Library/Frameworks 2>/dev/null` \
`ls -d /Network/Library/Frameworks 2>/dev/null` \
`ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
; do
if test -f "$i/Tcl.framework/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
@@ -2440,13 +2394,17 @@ $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory contain
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -4176,20 +4134,6 @@ 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}'
-
-
-
-
-
-
-
-
#--------------------------------------------------------------------
# Checks to see if the make program sets the $MAKE variable.
#--------------------------------------------------------------------
@@ -4861,470 +4805,6 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
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" "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
#--------------------------------------------------------------------
@@ -7538,7 +7018,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8172,9 +7652,9 @@ fi
case $system in
AIX-*) ;;
BSD/OS*) ;;
- CYGWIN_*|MINGW32_*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
windows) ;;
@@ -9523,7 +9003,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 thread $as_me 2.8.2, which was
+This file was extended by thread $as_me 2.8.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9576,7 +9056,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="\\
-thread config.status 2.8.2
+thread config.status 2.8.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/tcl8.6/pkgs/thread2.8.2/configure.ac b/tcl8.6/pkgs/thread2.8.4/configure.ac
index 8c598f9..059a45c 100755..100644
--- a/tcl8.6/pkgs/thread2.8.2/configure.ac
+++ b/tcl8.6/pkgs/thread2.8.4/configure.ac
@@ -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.8.2])
+AC_INIT([thread], [2.8.4])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -25,7 +25,7 @@ AC_INIT([thread], [2.8.2])
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
-TEA_INIT([3.10])
+TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/format.tcl b/tcl8.6/pkgs/thread2.8.4/doc/format.tcl
index 394c462..394c462 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/format.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/doc/format.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/html/thread.html b/tcl8.6/pkgs/thread2.8.4/doc/html/thread.html
index 6e89dfc..6e89dfc 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/html/thread.html
+++ b/tcl8.6/pkgs/thread2.8.4/doc/html/thread.html
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/html/tpool.html b/tcl8.6/pkgs/thread2.8.4/doc/html/tpool.html
index 468d7ce..468d7ce 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/html/tpool.html
+++ b/tcl8.6/pkgs/thread2.8.4/doc/html/tpool.html
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/html/tsv.html b/tcl8.6/pkgs/thread2.8.4/doc/html/tsv.html
index 6461f5e..6461f5e 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/html/tsv.html
+++ b/tcl8.6/pkgs/thread2.8.4/doc/html/tsv.html
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/html/ttrace.html b/tcl8.6/pkgs/thread2.8.4/doc/html/ttrace.html
index c4271b8..c4271b8 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/html/ttrace.html
+++ b/tcl8.6/pkgs/thread2.8.4/doc/html/ttrace.html
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/man.macros b/tcl8.6/pkgs/thread2.8.4/doc/man.macros
index 8626abf..8626abf 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/man.macros
+++ b/tcl8.6/pkgs/thread2.8.4/doc/man.macros
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/man/thread.n b/tcl8.6/pkgs/thread2.8.4/doc/man/thread.n
index 4b5f1cc..4b5f1cc 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/man/thread.n
+++ b/tcl8.6/pkgs/thread2.8.4/doc/man/thread.n
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/man/tpool.n b/tcl8.6/pkgs/thread2.8.4/doc/man/tpool.n
index a915bcb..a915bcb 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/man/tpool.n
+++ b/tcl8.6/pkgs/thread2.8.4/doc/man/tpool.n
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/man/tsv.n b/tcl8.6/pkgs/thread2.8.4/doc/man/tsv.n
index 386e904..386e904 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/man/tsv.n
+++ b/tcl8.6/pkgs/thread2.8.4/doc/man/tsv.n
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/man/ttrace.n b/tcl8.6/pkgs/thread2.8.4/doc/man/ttrace.n
index e326acd..e326acd 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/man/ttrace.n
+++ b/tcl8.6/pkgs/thread2.8.4/doc/man/ttrace.n
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/thread.man b/tcl8.6/pkgs/thread2.8.4/doc/thread.man
index 2dfadfb..2dfadfb 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/thread.man
+++ b/tcl8.6/pkgs/thread2.8.4/doc/thread.man
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/tpool.man b/tcl8.6/pkgs/thread2.8.4/doc/tpool.man
index 81122e2..81122e2 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/tpool.man
+++ b/tcl8.6/pkgs/thread2.8.4/doc/tpool.man
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/tsv.man b/tcl8.6/pkgs/thread2.8.4/doc/tsv.man
index f35cda1..f35cda1 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/tsv.man
+++ b/tcl8.6/pkgs/thread2.8.4/doc/tsv.man
diff --git a/tcl8.6/pkgs/thread2.8.2/doc/ttrace.man b/tcl8.6/pkgs/thread2.8.4/doc/ttrace.man
index 244b16a..244b16a 100644
--- a/tcl8.6/pkgs/thread2.8.2/doc/ttrace.man
+++ b/tcl8.6/pkgs/thread2.8.4/doc/ttrace.man
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/psGdbm.c b/tcl8.6/pkgs/thread2.8.4/generic/psGdbm.c
index fcaad37..fcaad37 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/psGdbm.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/psGdbm.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/psGdbm.h b/tcl8.6/pkgs/thread2.8.4/generic/psGdbm.h
index 4d68dd6..4d68dd6 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/psGdbm.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/psGdbm.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/psLmdb.c b/tcl8.6/pkgs/thread2.8.4/generic/psLmdb.c
index 90900e6..90900e6 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/psLmdb.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/psLmdb.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/psLmdb.h b/tcl8.6/pkgs/thread2.8.4/generic/psLmdb.h
index 1881c30..1881c30 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/psLmdb.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/psLmdb.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/tclThread.h b/tcl8.6/pkgs/thread2.8.4/generic/tclThread.h
index fad4a71..fad4a71 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/tclThread.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/tclThread.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/tclThreadInt.h b/tcl8.6/pkgs/thread2.8.4/generic/tclThreadInt.h
index 00466c9..60c6880 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/tclThreadInt.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/tclThreadInt.h
@@ -137,38 +137,41 @@ typedef struct {
int errorLine;
} tclInterpType;
-#if defined(TCL_TIP285)
+#if defined(TCL_TIP285) && defined(USE_TCL_STUBS)
# undef Tcl_GetErrorLine
-# if defined(USE_TCL_STUBS)
-# define Tcl_GetErrorLine(interp) ((threadTclVersion>85)? \
+# define Tcl_GetErrorLine(interp) ((threadTclVersion>85)? \
((int (*)(Tcl_Interp *))((&(tclStubsPtr->tcl_PkgProvideEx))[605]))(interp): \
(((tclInterpType *)(interp))->errorLine))
-# undef Tcl_AddErrorInfo
-# define Tcl_AddErrorInfo(interp, msg) ((threadTclVersion>85)? \
+/* TIP #270 */
+# undef Tcl_AddErrorInfo
+# define Tcl_AddErrorInfo(interp, msg) ((threadTclVersion>85)? \
((void (*)(Tcl_Interp *, Tcl_Obj *))((&(tclStubsPtr->tcl_PkgProvideEx))[574]))(interp, Tcl_NewStringObj(msg, -1)): \
((void (*)(Tcl_Interp *, const char *))((&(tclStubsPtr->tcl_PkgProvideEx))[66]))(interp, msg))
-# undef Tcl_BackgroundError
-# define Tcl_BackgroundError(interp) ((threadTclVersion>85)? \
+/* TIP #337 */
+# undef Tcl_BackgroundError
+# define Tcl_BackgroundError(interp) ((threadTclVersion>85)? \
((void (*)(Tcl_Interp *, int))((&(tclStubsPtr->tcl_PkgProvideEx))[609]))(interp, TCL_ERROR): \
((void (*)(Tcl_Interp *))((&(tclStubsPtr->tcl_PkgProvideEx))[76]))(interp))
-# else
-# define Tcl_GetErrorLine(interp) (((tclInterpType *)(interp))->errorLine)
-# endif
+#elif !TCL_MINIMUM_VERSION(8,6)
+ /* 8.5, 8.4, or less - Emulate access to the error-line information */
+# define Tcl_GetErrorLine(interp) (((tclInterpType *)(interp))->errorLine)
#endif
-
-/* 8.5, 8.4, or less - Emulate access to the error-line information
- * This is TIP 336, unrelated to 285 (async cancellation). When doing
- * a static link of the thread package (use case: basekits, tclkits,
- * ...) and the core Tcl is < 8.6 we cannot use TCL_TIP285 to get
- * things done, because USE_TCL_STUBS is not set for static builds,
- * causing the check in threadCmd.c to bomb.
+/* When running on Tcl >= 8.7, make sure that Thread still runs when Tcl is compiled
+ * with -DTCL_NO_DEPRECATED=1. Stub entries for Tcl_SetIntObj/Tcl_NewIntObj are NULL then.
+ * Just use Tcl_SetWideIntObj/Tcl_NewWideIntObj in stead. We don't simply want to use
+ * Tcl_SetWideIntObj/Tcl_NewWideIntObj always, since extensions might not expect to
+ * get an actual "wideInt".
*/
-
-#ifndef TCL_TIP285
-# if !TCL_MINIMUM_VERSION(8,6)
-# define Tcl_GetErrorLine(interp) (((tclInterpType *)(interp))->errorLine)
-# endif
+#if defined(USE_TCL_STUBS)
+# undef Tcl_SetIntObj
+# define Tcl_SetIntObj(objPtr, value) ((threadTclVersion>86)? \
+ ((void (*)(Tcl_Obj *, Tcl_WideInt))((&(tclStubsPtr->tcl_PkgProvideEx))[489]))(objPtr, (int)(value)): \
+ ((void (*)(Tcl_Obj *, int))((&(tclStubsPtr->tcl_PkgProvideEx))[61]))(objPtr, value))
+# undef Tcl_NewIntObj
+# define Tcl_NewIntObj(value) ((threadTclVersion>86)? \
+ ((Tcl_Obj * (*)(Tcl_WideInt))((&(tclStubsPtr->tcl_PkgProvideEx))[488]))((int)(value)): \
+ ((Tcl_Obj * (*)(int))((&(tclStubsPtr->tcl_PkgProvideEx))[52]))(value))
#endif
#endif /* _TCL_THREAD_INT_H_ */
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.c b/tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.c
index 56722e6..8a557f7 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.c
@@ -76,9 +76,6 @@
# define TclX_Assert(expr)
#endif
-#define TRUE 1
-#define FALSE 0
-
/*
* Macro that behaves like strdup, only uses ckalloc. Also macro that does the
* same with a string that might contain zero bytes,
@@ -106,7 +103,7 @@ static const Tcl_ObjType *listType;
* Parameters:
* o objPtr - Object to check.
* Returns:
- * True if NULL, FALSE if not.
+ * 1 if NULL, 0 if not.
*-----------------------------------------------------------------------------
*/
static int
@@ -364,9 +361,9 @@ ValidateKeyedList (keylIntPtr)
TclX_Assert (keylIntPtr->arraySize >= 0);
TclX_Assert (keylIntPtr->numEntries >= 0);
TclX_Assert ((keylIntPtr->arraySize > 0) ?
- (keylIntPtr->entries != NULL) : TRUE);
+ (keylIntPtr->entries != NULL) : 1);
TclX_Assert ((keylIntPtr->numEntries > 0) ?
- (keylIntPtr->entries != NULL) : TRUE);
+ (keylIntPtr->entries != NULL) : 1);
for (idx = 0; idx < keylIntPtr->numEntries; idx++) {
keylEntry_t *entryPtr = &(keylIntPtr->entries [idx]);
@@ -387,7 +384,7 @@ ValidateKeyedList (keylIntPtr)
* o interp - Used to return error messages.
* o key - Key string to check.
* o keyLen - Length of the string, used to check for binary data.
- * o isPath - TRUE if this is a key path, FALSE if its a simple key and
+ * o isPath - 1 if this is a key path, 0 if its a simple key and
* thus "." is illegal.
* Returns:
* TCL_OK or TCL_ERROR.
@@ -636,7 +633,7 @@ ObjToKeyedListEntry (interp, objPtr, entryPtr)
}
key = Tcl_GetString(objv[0]);
- if (ValidateKey(interp, key, objv[0]->length, FALSE) == TCL_ERROR) {
+ if (ValidateKey(interp, key, objv[0]->length, 0) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -1210,7 +1207,7 @@ Tcl_KeylgetObjCmd (clientData, interp, objc, objv)
* Handle retrieving a value for a specified key.
*/
key = Tcl_GetString(objv[2]);
- if (ValidateKey(interp, key, objv[2]->length, TRUE) == TCL_ERROR) {
+ if (ValidateKey(interp, key, objv[2]->length, 1) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -1229,7 +1226,7 @@ Tcl_KeylgetObjCmd (clientData, interp, objc, objv)
return TCL_ERROR;
} else {
Tcl_ResetResult(interp);
- Tcl_SetBooleanObj (Tcl_GetObjResult (interp), FALSE);
+ Tcl_SetIntObj(Tcl_GetObjResult (interp), 0);
return TCL_OK;
}
}
@@ -1251,7 +1248,7 @@ Tcl_KeylgetObjCmd (clientData, interp, objc, objv)
return TCL_ERROR;
}
Tcl_ResetResult(interp);
- Tcl_SetBooleanObj (Tcl_GetObjResult (interp), TRUE);
+ Tcl_SetIntObj(Tcl_GetObjResult (interp), 1);
return TCL_OK;
}
@@ -1296,7 +1293,7 @@ Tcl_KeylsetObjCmd (clientData, interp, objc, objv)
for (idx = 2; idx < objc; idx += 2) {
key = Tcl_GetString(objv[idx]);
- if (ValidateKey(interp, key, objv[idx]->length, TRUE) == TCL_ERROR) {
+ if (ValidateKey(interp, key, objv[idx]->length, 1) == TCL_ERROR) {
goto errorExit;
}
if (TclX_KeyedListSet (interp, keylVarPtr, key, objv [idx+1]) != TCL_OK) {
@@ -1362,7 +1359,7 @@ Tcl_KeyldelObjCmd (clientData, interp, objc, objv)
for (idx = 2; idx < objc; idx++) {
key = Tcl_GetString(objv[idx]);
- if (ValidateKey(interp, key, objv[idx]->length, TRUE) == TCL_ERROR) {
+ if (ValidateKey(interp, key, objv[idx]->length, 1) == TCL_ERROR) {
return TCL_ERROR;
}
@@ -1414,7 +1411,7 @@ Tcl_KeylkeysObjCmd (clientData, interp, objc, objv)
key = NULL;
} else {
key = Tcl_GetString(objv[2]);
- if (ValidateKey(interp, key, objv[2]->length, TRUE) == TCL_ERROR) {
+ if (ValidateKey(interp, key, objv[2]->length, 1) == TCL_ERROR) {
return TCL_ERROR;
}
}
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.h b/tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.h
index 8abfac9..8abfac9 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/tclXkeylist.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/tclXkeylist.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadCmd.c
index 6ce5c2c..cf8f19d 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadCmd.c
@@ -27,7 +27,7 @@
* files built as part of that shell. Example: basekits.
*/
#ifndef PACKAGE_VERSION
-#define PACKAGE_VERSION "2.8.2"
+#define PACKAGE_VERSION "2.8.4"
#endif
/*
@@ -435,11 +435,7 @@ 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);
+ return TCL_ERROR;
}
if (!threadTclVersion) {
@@ -938,7 +934,7 @@ ThreadSendObjCmd(dummy, interp, objc, objv)
int objc; /* Number of arguments. */
Tcl_Obj *const objv[]; /* Argument objects. */
{
- size_t len, vlen = 0;
+ size_t size;
int ret, ii = 0, flags = 0;
Tcl_ThreadId thrId;
const char *script, *arg;
@@ -980,12 +976,14 @@ ThreadSendObjCmd(dummy, interp, objc, objv)
}
script = Tcl_GetString(objv[ii]);
- len = objv[ii]->length;
+ size = objv[ii]->length+1;
if (++ii < objc) {
var = objv[ii];
- vlen = objv[ii]->length;
}
if (var && (flags & THREAD_SEND_WAIT) == 0) {
+ const char *varName = Tcl_GetString(var);
+ size_t vsize = var->length + 1;
+
if (thrId == Tcl_GetCurrentThread()) {
/*
* FIXME: Do something for callbacks to self
@@ -1005,7 +1003,7 @@ ThreadSendObjCmd(dummy, interp, objc, objv)
clbkPtr->freeProc = threadSendFree;
clbkPtr->interp = interp;
clbkPtr->threadId = Tcl_GetCurrentThread();
- clbkPtr->clientData = (ClientData)strcpy(ckalloc(1+vlen), Tcl_GetString(var));
+ clbkPtr->clientData = (ClientData)memcpy(ckalloc(vsize), varName, vsize);
}
/*
@@ -1016,7 +1014,7 @@ ThreadSendObjCmd(dummy, interp, objc, objv)
sendPtr->interp = NULL; /* Signal to use thread main interp */
sendPtr->execProc = ThreadSendEval;
sendPtr->freeProc = threadSendFree;
- sendPtr->clientData = (ClientData)strcpy(ckalloc(1+len), script);
+ sendPtr->clientData = (ClientData)memcpy(ckalloc(size), script, size);
ret = ThreadSend(interp, thrId, sendPtr, clbkPtr, flags);
@@ -1067,7 +1065,7 @@ ThreadBroadcastObjCmd(dummy, interp, objc, objv)
Tcl_Obj *const objv[]; /* Argument objects. */
{
int ii, nthreads;
- size_t len;
+ size_t size;
const char *script;
Tcl_ThreadId *thrIdArray;
ThreadSendData *sendPtr, job;
@@ -1080,7 +1078,7 @@ ThreadBroadcastObjCmd(dummy, interp, objc, objv)
}
script = Tcl_GetString(objv[1]);
- len = objv[1]->length;
+ size = objv[1]->length + 1;
/*
* Get the list of known threads. Note that this one may
@@ -1119,7 +1117,7 @@ ThreadBroadcastObjCmd(dummy, interp, objc, objv)
}
sendPtr = (ThreadSendData*)ckalloc(sizeof(ThreadSendData));
*sendPtr = job;
- sendPtr->clientData = (ClientData)strcpy(ckalloc(1+len), script);
+ sendPtr->clientData = (ClientData)memcpy(ckalloc(size), script, size);
ThreadSend(interp, thrIdArray[ii], sendPtr, NULL, THREAD_SEND_HEAD);
}
@@ -3259,7 +3257,7 @@ ThreadSetResult(interp, code, resultPtr)
int code;
ThreadEventResult *resultPtr;
{
- size_t reslen;
+ size_t size;
const char *errorCode, *errorInfo, *result;
if (interp == NULL) {
@@ -3267,14 +3265,14 @@ ThreadSetResult(interp, code, resultPtr)
errorInfo = "";
errorCode = "THREAD";
result = "no target interp!";
- reslen = strlen(result);
- resultPtr->result = (reslen) ?
- strcpy(ckalloc(1+reslen), result) : threadEmptyResult;
+ size = strlen(result);
+ resultPtr->result = (size) ?
+ memcpy(ckalloc(1+size), result, 1+size) : threadEmptyResult;
} else {
result = Tcl_GetString(Tcl_GetObjResult(interp));
- reslen = Tcl_GetObjResult(interp)->length;
- resultPtr->result = (reslen) ?
- strcpy(ckalloc(1+reslen), result) : threadEmptyResult;
+ size = Tcl_GetObjResult(interp)->length;
+ resultPtr->result = (size) ?
+ memcpy(ckalloc(1+size), result, 1+size) : threadEmptyResult;
if (code == TCL_ERROR) {
errorCode = Tcl_GetVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY);
errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
@@ -3287,14 +3285,14 @@ ThreadSetResult(interp, code, resultPtr)
resultPtr->code = code;
if (errorCode != NULL) {
- resultPtr->errorCode = ckalloc(1+strlen(errorCode));
- strcpy(resultPtr->errorCode, errorCode);
+ size = strlen(errorCode) + 1;
+ resultPtr->errorCode = memcpy(ckalloc(size), errorCode, size);
} else {
resultPtr->errorCode = NULL;
}
if (errorInfo != NULL) {
- resultPtr->errorInfo = ckalloc(1+strlen(errorInfo));
- strcpy(resultPtr->errorInfo, errorInfo);
+ size = strlen(errorInfo) + 1;
+ resultPtr->errorInfo = memcpy(ckalloc(size), errorInfo, size);
} else {
resultPtr->errorInfo = NULL;
}
@@ -3546,8 +3544,8 @@ TransferEventProc(evPtr, mask)
Tcl_MutexLock(&threadMutex);
resultPtr->resultCode = code;
if (msg != NULL) {
- resultPtr->resultMsg = (char*)ckalloc(1+strlen (msg));
- strcpy (resultPtr->resultMsg, msg);
+ size_t size = strlen(msg)+1;
+ resultPtr->resultMsg = memcpy(ckalloc(size), msg, size);
}
Tcl_ConditionNotify(&resultPtr->done);
Tcl_MutexUnlock(&threadMutex);
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadNs.c b/tcl8.6/pkgs/thread2.8.4/generic/threadNs.c
index 45b6b09..45b6b09 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadNs.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadNs.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadPoolCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadPoolCmd.c
index 3252baf..3252baf 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadPoolCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadPoolCmd.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.c
index dbb849e..dbb849e 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.h b/tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.h
index 70fcc4f..70fcc4f 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSpCmd.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSpCmd.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.c
index a54f3b1..a54f3b1 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.h b/tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.h
index 228d134..228d134 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvCmd.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvCmd.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.c
index 67a84d1..67a84d1 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.h b/tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.h
index 1f23554..1f23554 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvKeylistCmd.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvKeylistCmd.h
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.c b/tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.c
index e23ee28..e23ee28 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.c
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.c
diff --git a/tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.h b/tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.h
index 7647810..7647810 100644
--- a/tcl8.6/pkgs/thread2.8.2/generic/threadSvListCmd.h
+++ b/tcl8.6/pkgs/thread2.8.4/generic/threadSvListCmd.h
diff --git a/tcl8.6/pkgs/thread2.8.2/lib/ttrace.tcl b/tcl8.6/pkgs/thread2.8.4/lib/ttrace.tcl
index 16173f1..f90ef89 100644
--- a/tcl8.6/pkgs/thread2.8.2/lib/ttrace.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/lib/ttrace.tcl
@@ -73,7 +73,7 @@ namespace eval ttrace {
}
# Keep in sync with the Thread package
- package provide Ttrace 2.8.2
+ package provide Ttrace 2.8.4
# Package variables
variable resolvers "" ; # List of registered resolvers
diff --git a/tcl8.6/pkgs/thread2.8.2/license.terms b/tcl8.6/pkgs/thread2.8.4/license.terms
index f87ed92..f87ed92 100644
--- a/tcl8.6/pkgs/thread2.8.2/license.terms
+++ b/tcl8.6/pkgs/thread2.8.4/license.terms
diff --git a/tcl8.6/pkgs/thread2.8.2/naviserver.m4 b/tcl8.6/pkgs/thread2.8.4/naviserver.m4
index f0ab1fc..f0ab1fc 100644
--- a/tcl8.6/pkgs/thread2.8.2/naviserver.m4
+++ b/tcl8.6/pkgs/thread2.8.4/naviserver.m4
diff --git a/tcl8.6/pkgs/thread2.8.2/pkgIndex.tcl.in b/tcl8.6/pkgs/thread2.8.4/pkgIndex.tcl.in
index 22f5f8f..22f5f8f 100755..100644
--- a/tcl8.6/pkgs/thread2.8.2/pkgIndex.tcl.in
+++ b/tcl8.6/pkgs/thread2.8.4/pkgIndex.tcl.in
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/README b/tcl8.6/pkgs/thread2.8.4/tcl/README
index 15e1edd..15e1edd 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/README
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/README
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/cmdsrv/cmdsrv.tcl b/tcl8.6/pkgs/thread2.8.4/tcl/cmdsrv/cmdsrv.tcl
index 01ec508..01ec508 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/cmdsrv/cmdsrv.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/cmdsrv/cmdsrv.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/index.htm b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/index.htm
index 324f1f7..324f1f7 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/index.htm
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/index.htm
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/phttpd.tcl b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/phttpd.tcl
index 8f0c42d..8f0c42d 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/phttpd.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/phttpd.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/uhttpd.tcl b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/uhttpd.tcl
index b44338a..b44338a 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/phttpd/uhttpd.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/phttpd/uhttpd.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/tcl/tpool/tpool.tcl b/tcl8.6/pkgs/thread2.8.4/tcl/tpool/tpool.tcl
index 021e231..021e231 100644
--- a/tcl8.6/pkgs/thread2.8.2/tcl/tpool/tpool.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tcl/tpool/tpool.tcl
diff --git a/tcl8.6/pkgs/thread2.8.4/tclconfig/README.txt b/tcl8.6/pkgs/thread2.8.4/tclconfig/README.txt
new file mode 100644
index 0000000..59b5a3e
--- /dev/null
+++ b/tcl8.6/pkgs/thread2.8.4/tclconfig/README.txt
@@ -0,0 +1,26 @@
+These files comprise the basic building blocks for a Tcl Extension
+Architecture (TEA) extension. For more information on TEA see:
+
+ http://www.tcl.tk/doc/tea/
+
+This package is part of the Tcl project at SourceForge, and latest
+sources should be available there:
+
+ http://tcl.sourceforge.net/
+
+This package is a freely available open source package. You can do
+virtually anything you like with it, such as modifying it, redistributing
+it, and selling it either in whole or in part.
+
+CONTENTS
+========
+The following is a short description of the files you will find in
+the sample extension.
+
+README.txt This file
+
+install-sh Program used for copying binaries and script files
+ to their install locations.
+
+tcl.m4 Collection of Tcl autoconf macros. Included by a package's
+ aclocal.m4 to define TEA_* macros.
diff --git a/tcl8.6/pkgs/itcl4.1.1/tclconfig/install-sh b/tcl8.6/pkgs/thread2.8.4/tclconfig/install-sh
index 7c34c3f..7c34c3f 100755..100644
--- a/tcl8.6/pkgs/itcl4.1.1/tclconfig/install-sh
+++ b/tcl8.6/pkgs/thread2.8.4/tclconfig/install-sh
diff --git a/tcl8.6/pkgs/thread2.8.4/tclconfig/tcl.m4 b/tcl8.6/pkgs/thread2.8.4/tclconfig/tcl.m4
new file mode 100644
index 0000000..2ec82a2
--- /dev/null
+++ b/tcl8.6/pkgs/thread2.8.4/tclconfig/tcl.m4
@@ -0,0 +1,4184 @@
+# tcl.m4 --
+#
+# This file provides a set of autoconf macros to help TEA-enable
+# a Tcl extension.
+#
+# Copyright (c) 1999-2000 Ajuba Solutions.
+# Copyright (c) 2002-2005 ActiveState Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+AC_PREREQ(2.57)
+
+# 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
+#
+
+#------------------------------------------------------------------------
+# TEA_PATH_TCLCONFIG --
+#
+# Locate the tclConfig.sh file and perform a sanity check on
+# the Tcl compile flags
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tcl=...
+#
+# Defines the following vars:
+# TCL_BIN_DIR Full path to the directory containing
+# the tclConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TCLCONFIG], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+ #
+ # Ok, lets find the tcl configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tcl
+ #
+
+ if test x"${no_tcl}" = x ; then
+ # we reset no_tcl in case something fails here
+ no_tcl=true
+ AC_ARG_WITH(tcl,
+ AC_HELP_STRING([--with-tcl],
+ [directory containing tcl configuration (tclConfig.sh)]),
+ with_tclconfig="${withval}")
+ AC_MSG_CHECKING([for Tcl configuration])
+ AC_CACHE_VAL(ac_cv_c_tclconfig,[
+
+ # First check to see if --with-tcl was specified.
+ if test x"${with_tclconfig}" != x ; then
+ case "${with_tclconfig}" in
+ */tclConfig.sh )
+ if test -f "${with_tclconfig}"; then
+ AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
+ with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tclconfig}/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tcl installation
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ for i in \
+ ../tcl \
+ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tcl \
+ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tcl \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tclConfig.sh" ; then
+ ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 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/pkg/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` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/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
+ ])
+
+ if test x"${ac_cv_c_tclconfig}" = x ; then
+ TCL_BIN_DIR="# no Tcl configs found"
+ AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
+ else
+ no_tcl=
+ TCL_BIN_DIR="${ac_cv_c_tclconfig}"
+ AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_TKCONFIG --
+#
+# Locate the tkConfig.sh file
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-tk=...
+#
+# Defines the following vars:
+# TK_BIN_DIR Full path to the directory containing
+# the tkConfig.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_TKCONFIG], [
+ #
+ # Ok, lets find the tk configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-tk
+ #
+
+ if test x"${no_tk}" = x ; then
+ # we reset no_tk in case something fails here
+ no_tk=true
+ AC_ARG_WITH(tk,
+ AC_HELP_STRING([--with-tk],
+ [directory containing tk configuration (tkConfig.sh)]),
+ with_tkconfig="${withval}")
+ AC_MSG_CHECKING([for Tk configuration])
+ AC_CACHE_VAL(ac_cv_c_tkconfig,[
+
+ # First check to see if --with-tkconfig was specified.
+ if test x"${with_tkconfig}" != x ; then
+ case "${with_tkconfig}" in
+ */tkConfig.sh )
+ if test -f "${with_tkconfig}"; then
+ AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
+ with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
+ fi ;;
+ esac
+ if test -f "${with_tkconfig}/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
+ else
+ AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
+ fi
+ fi
+
+ # then check for a private Tk library
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ../tk \
+ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../tk \
+ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
+ ../../../tk \
+ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # on Darwin, check in Framework installation locations
+ if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
+ `ls -d /Library/Frameworks 2>/dev/null` \
+ `ls -d /Network/Library/Frameworks 2>/dev/null` \
+ `ls -d /System/Library/Frameworks 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
+ ; do
+ if test -f "$i/Tk.framework/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # TEA specific: on Windows, check in common installation locations
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a x"${ac_cv_c_tkconfig}" = x ; then
+ for i in `ls -d C:/Tcl/lib 2>/dev/null` \
+ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
+ ; do
+ if test -f "$i/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i; pwd)`"
+ break
+ fi
+ done
+ fi
+
+ # check in a few other private locations
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ for i in \
+ ${srcdir}/../tk \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
+ if test "${TEA_PLATFORM}" = "windows" \
+ -a -f "$i/win/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
+ break
+ fi
+ if test -f "$i/unix/tkConfig.sh" ; then
+ ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_tkconfig}" = x ; then
+ TK_BIN_DIR="# no Tk configs found"
+ AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
+ else
+ no_tk=
+ TK_BIN_DIR="${ac_cv_c_tkconfig}"
+ AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TCLCONFIG --
+#
+# Load the tclConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TCL_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_BIN_DIR
+# TCL_SRC_DIR
+# TCL_LIB_FILE
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TCLCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
+
+ if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TCL_BIN_DIR}/tclConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+ eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
+
+ # If the TCL_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TCL_LIB_SPEC will be set to the value
+ # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
+ # instead of TCL_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+ TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+ TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tcl.framework installed in an arbitrary location.
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
+ for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
+ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
+ TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
+ TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
+ TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TCL_DBGX substitution
+ eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+ eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+ eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
+ eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
+
+ AC_SUBST(TCL_VERSION)
+ AC_SUBST(TCL_PATCH_LEVEL)
+ AC_SUBST(TCL_BIN_DIR)
+ AC_SUBST(TCL_SRC_DIR)
+
+ AC_SUBST(TCL_LIB_FILE)
+ AC_SUBST(TCL_LIB_FLAG)
+ AC_SUBST(TCL_LIB_SPEC)
+
+ AC_SUBST(TCL_STUB_LIB_FILE)
+ AC_SUBST(TCL_STUB_LIB_FLAG)
+ AC_SUBST(TCL_STUB_LIB_SPEC)
+
+ AC_MSG_CHECKING([platform])
+ hold_cc=$CC; CC="$TCL_CC"
+ AC_TRY_COMPILE(,[
+ #ifdef _WIN32
+ #error win32
+ #endif
+ ], [
+ TEA_PLATFORM="unix"
+ CYGPATH=echo
+ ], [
+ TEA_PLATFORM="windows"
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]
+ )
+ CC=$hold_cc
+ AC_MSG_RESULT($TEA_PLATFORM)
+
+ # The BUILD_$pkg is to define the correct extern storage class
+ # handling when making this package
+ AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
+ [Building extension source?])
+ # 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:
+ AC_SUBST(CLEANFILES)
+ AC_SUBST(TCL_LIBS)
+ AC_SUBST(TCL_DEFS)
+ AC_SUBST(TCL_EXTRA_CFLAGS)
+ AC_SUBST(TCL_LD_FLAGS)
+ AC_SUBST(TCL_SHLIB_LD_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_TKCONFIG --
+#
+# Load the tkConfig.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# TK_BIN_DIR
+#
+# Results:
+#
+# Sets the following vars that should be in tkConfig.sh:
+# TK_BIN_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_TKCONFIG], [
+ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
+
+ if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${TK_BIN_DIR}/tkConfig.sh"
+ else
+ AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
+ eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
+
+ # If the TK_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable TK_LIB_SPEC will be set to the value
+ # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
+ # instead of TK_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+ TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+ TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+ elif test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use the libraries
+ # from the framework at the given location so that linking works
+ # against Tk.framework installed in an arbitrary location.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
+ for i in "`cd "${TK_BIN_DIR}"; pwd`" \
+ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
+ if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
+ TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
+ break
+ fi
+ done
+ fi
+ if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
+ TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
+ TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
+ fi
+ ;;
+ esac
+ fi
+
+ # eval is required to do the TK_DBGX substitution
+ eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
+ eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
+ eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
+ eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
+
+ # TEA specific: Ensure windowingsystem is defined
+ if test "${TEA_PLATFORM}" = "unix" ; then
+ case ${TK_DEFS} in
+ *MAC_OSX_TK*)
+ AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
+ TEA_WINDOWINGSYSTEM="aqua"
+ ;;
+ *)
+ TEA_WINDOWINGSYSTEM="x11"
+ ;;
+ esac
+ elif test "${TEA_PLATFORM}" = "windows" ; then
+ TEA_WINDOWINGSYSTEM="win32"
+ fi
+
+ AC_SUBST(TK_VERSION)
+ AC_SUBST(TK_BIN_DIR)
+ AC_SUBST(TK_SRC_DIR)
+
+ AC_SUBST(TK_LIB_FILE)
+ AC_SUBST(TK_LIB_FLAG)
+ AC_SUBST(TK_LIB_SPEC)
+
+ AC_SUBST(TK_STUB_LIB_FILE)
+ AC_SUBST(TK_STUB_LIB_FLAG)
+ AC_SUBST(TK_STUB_LIB_SPEC)
+
+ # TEA specific:
+ AC_SUBST(TK_LIBS)
+ AC_SUBST(TK_XINCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_TCLSH
+# Determine the fully qualified path name of the tclsh executable
+# in the Tcl build directory or the tclsh installed in a bin
+# directory. This macro will correctly determine the name
+# of the tclsh executable even if tclsh has not yet been
+# built in the build directory. The tclsh found is always
+# associated with a tclConfig.sh file. This tclsh should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCLSH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_TCLSH], [
+ AC_MSG_CHECKING([for tclsh])
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ # tclConfig.sh is in Tcl build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ AC_MSG_RESULT([${TCLSH_PROG}])
+ AC_SUBST(TCLSH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_PROG_WISH
+# Determine the fully qualified path name of the wish executable
+# in the Tk build directory or the wish installed in a bin
+# directory. This macro will correctly determine the name
+# of the wish executable even if wish has not yet been
+# built in the build directory. The wish found is always
+# associated with a tkConfig.sh file. This wish should be used
+# only for running extension test cases. It should never be
+# or generation of files (like pkgIndex.tcl) at build time.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# WISH_PROG
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PROG_WISH], [
+ AC_MSG_CHECKING([for wish])
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ # tkConfig.sh is in Tk build directory
+ if test "${TEA_PLATFORM}" = "windows"; then
+ 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
+ else
+ # tkConfig.sh is in install location
+ if test "${TEA_PLATFORM}" = "windows"; then
+ WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
+ else
+ WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
+ fi
+ list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/bin 2>/dev/null`"
+ for i in $list ; do
+ if test -f "$i/${WISH_PROG}" ; then
+ REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+ break
+ fi
+ done
+ WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+ fi
+ AC_MSG_RESULT([${WISH_PROG}])
+ AC_SUBST(WISH_PROG)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SHARED --
+#
+# Allows the building of shared libraries
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-shared=yes|no
+# --enable-stubs=yes|no
+#
+# Defines the following vars:
+# STATIC_BUILD Used for building import/export libraries
+# on Windows.
+#
+# Sets the following vars:
+# SHARED_BUILD Value of 1 or 0
+# 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)]),
+ [shared_ok=$enableval], [shared_ok=yes])
+
+ if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ shared_ok=$enableval
+ else
+ 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
+
+ # 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, [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)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_THREADS --
+#
+# Specify if thread support should be enabled. If "yes" is specified
+# as an arg (optional), threads are enabled by default, "no" means
+# threads are disabled. "yes" is the default.
+#
+# TCL_THREADS is checked so that if you are compiling an extension
+# against a threaded core, your extension must be compiled threaded
+# as well.
+#
+# Note that it is legal to have a thread enabled extension run in a
+# threaded or non-threaded Tcl core, but a non-threaded extension may
+# only run in a non-threaded Tcl core.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-threads
+#
+# Sets the following vars:
+# THREADS_LIBS Thread library(s)
+#
+# Defines the following vars:
+# TCL_THREADS
+# _REENTRANT
+# _THREAD_SAFE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_THREADS], [
+ AC_ARG_ENABLE(threads,
+ AC_HELP_STRING([--enable-threads],
+ [build with threads (default: on)]),
+ [tcl_ok=$enableval], [tcl_ok=yes])
+
+ if test "${enable_threads+set}" = set; then
+ enableval="$enable_threads"
+ tcl_ok=$enableval
+ else
+ tcl_ok=yes
+ fi
+
+ if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
+ TCL_THREADS=1
+
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ # We are always OK on Windows, so check what this platform wants:
+
+ # USE_THREAD_ALLOC tells us to try the special thread-based
+ # allocator that significantly reduces lock contention
+ AC_DEFINE(USE_THREAD_ALLOC, 1,
+ [Do we want to use the threaded memory allocator?])
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ if test "`uname -s`" = "SunOS" ; then
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+ fi
+ AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
+ AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ # Check a little harder for __pthread_mutex_init in the same
+ # library, as some systems hide it there until pthread.h is
+ # defined. We could alternatively do an AC_TRY_COMPILE with
+ # pthread.h, but that will work with libpthread really doesn't
+ # exist, like AIX 4.2. [Bug: 4359]
+ AC_CHECK_LIB(pthread, __pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ fi
+
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthread"
+ else
+ AC_CHECK_LIB(pthreads, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -lpthreads"
+ else
+ AC_CHECK_LIB(c, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "no"; then
+ AC_CHECK_LIB(c_r, pthread_mutex_init,
+ tcl_ok=yes, tcl_ok=no)
+ if test "$tcl_ok" = "yes"; then
+ # The space is needed
+ THREADS_LIBS=" -pthread"
+ else
+ TCL_THREADS=0
+ AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
+ fi
+ fi
+ fi
+ fi
+ fi
+ else
+ TCL_THREADS=0
+ fi
+ # Do checking message here to not mess up interleaved configure output
+ AC_MSG_CHECKING([for building with threads])
+ if test "${TCL_THREADS}" = 1; then
+ AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
+ AC_MSG_RESULT([yes (default)])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ # TCL_THREADS sanity checking. See if our request for building with
+ # threads is the same as the way Tcl was built. If not, warn the user.
+ case ${TCL_DEFS} in
+ *THREADS=1*)
+ if test "${TCL_THREADS}" = "0"; then
+ AC_MSG_WARN([
+ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
+ that IS thread-enabled. It is recommended to use --enable-threads.])
+ fi
+ ;;
+ *)
+ if test "${TCL_THREADS}" = "1"; then
+ AC_MSG_WARN([
+ --enable-threads requested, but building against a Tcl that is NOT
+ thread-enabled. This is an OK configuration that will also run in
+ a thread-enabled core.])
+ fi
+ ;;
+ esac
+ AC_SUBST(TCL_THREADS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_SYMBOLS --
+#
+# Specify if debugging symbols should be used.
+# Memory (TCL_MEM_DEBUG) debugging can also be enabled.
+#
+# Arguments:
+# none
+#
+# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
+# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
+# Requires the following vars to be set in the Makefile:
+# CFLAGS_DEFAULT
+# LDFLAGS_DEFAULT
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-symbols
+#
+# Defines the following vars:
+# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true
+# Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
+# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true
+# Sets to $(LDFLAGS_OPTIMIZE) if false
+# DBGX Formerly used as debug library extension;
+# always blank now.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_SYMBOLS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_CONFIG_CFLAGS])
+ AC_MSG_CHECKING([for build with symbols])
+ AC_ARG_ENABLE(symbols,
+ AC_HELP_STRING([--enable-symbols],
+ [build with debugging symbols (default: off)]),
+ [tcl_ok=$enableval], [tcl_ok=no])
+ DBGX=""
+ if test "$tcl_ok" = "no"; then
+ CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
+ LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
+ AC_MSG_RESULT([no])
+ else
+ CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
+ LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
+ if test "$tcl_ok" = "yes"; then
+ AC_MSG_RESULT([yes (standard debugging)])
+ fi
+ fi
+ # TEA specific:
+ if test "${TEA_PLATFORM}" != "windows" ; then
+ LDFLAGS_DEFAULT="${LDFLAGS}"
+ fi
+ AC_SUBST(CFLAGS_DEFAULT)
+ AC_SUBST(LDFLAGS_DEFAULT)
+ AC_SUBST(TCL_DBGX)
+
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
+ fi
+
+ if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
+ if test "$tcl_ok" = "all"; then
+ AC_MSG_RESULT([enabled symbols mem debugging])
+ else
+ AC_MSG_RESULT([enabled $tcl_ok debugging])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_ENABLE_LANGINFO --
+#
+# Allows use of modern nl_langinfo check for better l10n.
+# This is only relevant for Unix.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --enable-langinfo=yes|no (default is yes)
+#
+# Defines the following vars:
+# HAVE_LANGINFO Triggers use of nl_langinfo if defined.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_ENABLE_LANGINFO], [
+ AC_ARG_ENABLE(langinfo,
+ AC_HELP_STRING([--enable-langinfo],
+ [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
+ [langinfo_ok=$enableval], [langinfo_ok=yes])
+
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
+ fi
+ AC_MSG_CHECKING([whether to use nl_langinfo])
+ if test "$langinfo_ok" = "yes"; then
+ AC_CACHE_VAL(tcl_cv_langinfo_h, [
+ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
+ [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
+ AC_MSG_RESULT([$tcl_cv_langinfo_h])
+ if test $tcl_cv_langinfo_h = yes; then
+ AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
+ fi
+ else
+ AC_MSG_RESULT([$langinfo_ok])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_SYSTEM
+#
+# Determine what the system is (some things cannot be easily checked
+# on a feature-driven basis, alas). This can usually be done via the
+# "uname" command.
+#
+# Arguments:
+# none
+#
+# Results:
+# Defines the following var:
+#
+# system - System/platform/version identification code.
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_SYSTEM], [
+ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
+ # TEA specific:
+ if test "${TEA_PLATFORM}" = "windows" ; then
+ tcl_cv_sys_version=windows
+ else
+ tcl_cv_sys_version=`uname -s`-`uname -r`
+ if test "$?" -ne 0 ; then
+ AC_MSG_WARN([can't find uname command])
+ tcl_cv_sys_version=unknown
+ else
+ if test "`uname -s`" = "AIX" ; then
+ tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
+ fi
+ fi
+ fi
+ ])
+ system=$tcl_cv_sys_version
+])
+
+#--------------------------------------------------------------------
+# TEA_CONFIG_CFLAGS
+#
+# Try to determine the proper flags to pass to the compiler
+# for building shared libraries and other such nonsense.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substitutes the following vars:
+#
+# DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
+# LDFLAGS - Flags to pass to the compiler when linking object
+# files into an executable application binary such
+# as tclsh.
+# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile. Could
+# be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
+# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
+# that tell the run-time dynamic linker where to look
+# for shared libraries such as libtcl.so. Depends on
+# the variable LIB_RUNTIME_DIR in the Makefile.
+# SHLIB_CFLAGS - Flags to pass to cc when compiling the components
+# of a shared library (may request position-independent
+# code, among other things).
+# SHLIB_LD - Base command to use for combining object files
+# into a shared library.
+# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
+# creating shared libraries. This symbol typically
+# goes at the end of the "ld" commands that build
+# shared libraries. The value of the symbol defaults to
+# "${LIBS}" if all of the dependent libraries should
+# be specified when creating a shared library. If
+# dependent libraries should not be specified (as on
+# SunOS 4.x, where they cause the link to fail, or in
+# general if Tcl and Tk aren't themselves shared
+# libraries), then this symbol has an empty string
+# as its value.
+# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable
+# extensions. An empty string means we don't know how
+# to use shared libraries on this platform.
+# LIB_SUFFIX - Specifies everything that comes after the "libfoo"
+# in a static or shared library name, using the $PACKAGE_VERSION variable
+# to put the version in the right place. This is used
+# by platforms that need non-standard library names.
+# Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
+# to have a version after the .so, and ${PACKAGE_VERSION}.a
+# on AIX, since a shared library needs to have
+# a .a extension whereas shared objects for loadable
+# extensions have a .so extension. Defaults to
+# ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
+# CFLAGS_DEBUG -
+# Flags used when running the compiler in debug mode
+# CFLAGS_OPTIMIZE -
+# Flags used when running the compiler in optimize mode
+# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_CONFIG_CFLAGS], [
+ dnl TEA specific: Make sure we are initialized
+ AC_REQUIRE([TEA_INIT])
+
+ # Step 0.a: Enable 64 bit support?
+
+ AC_MSG_CHECKING([if 64bit support is requested])
+ AC_ARG_ENABLE(64bit,
+ AC_HELP_STRING([--enable-64bit],
+ [enable 64bit support (default: off)]),
+ [do64bit=$enableval], [do64bit=no])
+ AC_MSG_RESULT([$do64bit])
+
+ # Step 0.b: Enable Solaris 64 bit VIS support?
+
+ AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
+ AC_ARG_ENABLE(64bit-vis,
+ AC_HELP_STRING([--enable-64bit-vis],
+ [enable 64bit Sparc VIS support (default: off)]),
+ [do64bitVIS=$enableval], [do64bitVIS=no])
+ AC_MSG_RESULT([$do64bitVIS])
+ # Force 64bit on with VIS
+ AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
+
+ # Step 0.c: Check if visibility support is available. Do this here so
+ # that platform specific alternatives can be used below if this fails.
+
+ AC_CACHE_CHECK([if compiler supports visibility "hidden"],
+ tcl_cv_cc_visibility_hidden, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
+ AC_TRY_LINK([
+ extern __attribute__((__visibility__("hidden"))) void f(void);
+ void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
+ tcl_cv_cc_visibility_hidden=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
+ AC_DEFINE(MODULE_SCOPE,
+ [extern __attribute__((__visibility__("hidden")))],
+ [Compiler support for module scope symbols])
+ AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
+ ])
+
+ # Step 0.d: Disable -rpath support?
+
+ AC_MSG_CHECKING([if rpath support is requested])
+ AC_ARG_ENABLE(rpath,
+ AC_HELP_STRING([--disable-rpath],
+ [disable rpath support (default: on)]),
+ [doRpath=$enableval], [doRpath=yes])
+ AC_MSG_RESULT([$doRpath])
+
+ # TEA specific: Cross-compiling options for Windows/CE builds?
+
+ AS_IF([test "${TEA_PLATFORM}" = windows], [
+ AC_MSG_CHECKING([if Windows/CE build is requested])
+ AC_ARG_ENABLE(wince,
+ AC_HELP_STRING([--enable-wince],
+ [enable Win/CE support (where applicable)]),
+ [doWince=$enableval], [doWince=no])
+ AC_MSG_RESULT([$doWince])
+ ])
+
+ # Set the variable "system" to hold the name and version number
+ # for the system.
+
+ TEA_CONFIG_SYSTEM
+
+ # Require ranlib early so we can override it in special cases below.
+
+ AC_REQUIRE([AC_PROG_RANLIB])
+
+ # 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
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS_OPTIMIZE=-O2
+ CFLAGS_WARNING="-Wall"
+ ], [
+ CFLAGS_OPTIMIZE=-O
+ CFLAGS_WARNING=""
+ ])
+ AC_CHECK_TOOL(AR, ar)
+ STLIB_LD='${AR} cr'
+ LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
+ AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
+ 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
+ AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
+ AC_MSG_WARN([Ensure latest Platform SDK is installed])
+ do64bit="no"
+ else
+ AC_MSG_RESULT([ Using 64-bit $MACHINE mode])
+ do64bit_ok="yes"
+ fi
+ fi
+
+ if test "$doWince" != "no" ; then
+ if test "$do64bit" != "no" ; then
+ AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
+ fi
+ if test "$GCC" = "yes" ; then
+ AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
+ fi
+ TEA_PATH_CELIB
+ # Set defaults for common evc4/PPC2003 setup
+ # Currently Tcl requires 300+, possibly 420+ for sockets
+ CEVERSION=420; # could be 211 300 301 400 420 ...
+ TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ...
+ ARCH=ARM; # could be ARM MIPS X86EM ...
+ PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
+ if test "$doWince" != "yes"; then
+ # If !yes then the user specified something
+ # Reset ARCH to allow user to skip specifying it
+ ARCH=
+ eval `echo $doWince | awk -F, '{ \
+ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
+ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
+ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
+ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
+ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
+ }'`
+ if test "x${ARCH}" = "x" ; then
+ ARCH=$TARGETCPU;
+ fi
+ fi
+ OSVERSION=WCE$CEVERSION;
+ if test "x${WCEROOT}" = "x" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
+ if test ! -d "${WCEROOT}" ; then
+ WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
+ fi
+ fi
+ if test "x${SDKROOT}" = "x" ; then
+ SDKROOT="C:/Program Files/Windows CE Tools"
+ if test ! -d "${SDKROOT}" ; then
+ SDKROOT="C:/Windows CE Tools"
+ fi
+ fi
+ WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
+ SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
+ if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
+ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
+ AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
+ doWince="no"
+ else
+ # We could PATH_NOSPACE these, but that's not important,
+ # as long as we quote them when used.
+ CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
+ if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
+ CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
+ fi
+ CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
+ fi
+ fi
+
+ if test "$GCC" != "yes" ; then
+ if test "${SHARED_BUILD}" = "0" ; then
+ runtime=-MT
+ else
+ runtime=-MD
+ fi
+ case "x`echo \${VisualStudioVersion}`" in
+ x1[[4-9]]*)
+ lflags="${lflags} -nodefaultlib:libucrt.lib"
+ TEA_ADD_LIBS([ucrt.lib])
+ ;;
+ *)
+ ;;
+ 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
+ TEA_ADD_LIBS([bufferoverflowU.lib])
+ elif test "$doWince" != "no" ; then
+ CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
+ if test "${TARGETCPU}" = "X86"; then
+ CC="\"${CEBINROOT}/cl.exe\""
+ else
+ CC="\"${CEBINROOT}/cl${ARCH}.exe\""
+ fi
+ CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
+ RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
+ arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
+ defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
+ if test "${SHARED_BUILD}" = "1" ; then
+ # Static CE builds require static celib as well
+ defs="${defs} _DLL"
+ fi
+ for i in $defs ; do
+ AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
+ done
+ AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
+ AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
+ CFLAGS_DEBUG="-nologo -Zi -Od"
+ CFLAGS_OPTIMIZE="-nologo -Ox"
+ lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
+ lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
+ LINKBIN="\"${CEBINROOT}/link.exe\""
+ AC_SUBST(CELIB_DIR)
+ 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
+ AC_CHECK_TOOL(RC, windres)
+ CFLAGS_DEBUG="-g"
+ CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
+ SHLIB_LD='${CC} -shared'
+ UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
+ LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
+ LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
+
+ AC_CACHE_CHECK(for cross-compile version of gcc,
+ ac_cv_cross,
+ AC_TRY_COMPILE([
+ #ifdef _WIN32
+ #error cross-compiler
+ #endif
+ ], [],
+ ac_cv_cross=yes,
+ ac_cv_cross=no)
+ )
+ 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-*)
+ AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
+ # AIX requires the _r compiler when gcc isn't being used
+ case "${CC}" in
+ *_r|*_r\ *)
+ # ok ...
+ ;;
+ *)
+ # Make sure only first arg gets _r
+ CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
+ ;;
+ esac
+ AC_MSG_RESULT([Using $CC for compiling with threads])
+ ])
+ LIBS="$LIBS -lc"
+ SHLIB_CFLAGS=""
+ SHLIB_SUFFIX=".so"
+
+ LD_LIBRARY_PATH_VAR="LIBPATH"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -q64"
+ LDFLAGS_ARCH="-q64"
+ RANLIB="${RANLIB} -X64"
+ AR="${AR} -X64"
+ SHLIB_LD_FLAGS="-b64"
+ ])
+ ])
+
+ AS_IF([test "`uname -m`" = ia64], [
+ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ AS_IF([test "$GCC" = yes], [
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ ], [
+ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
+ ])
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ], [
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared -Wl,-bexpall'
+ ], [
+ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
+ LDFLAGS="$LDFLAGS -brtl"
+ ])
+ SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
+ CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ 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.
+ #-----------------------------------------------------------
+ AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
+ ;;
+ 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} ${CFLAGS} ${LDFLAGS} -shared'
+ AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
+ ;;
+ HP-UX-*.11.*)
+ # Use updated header definitions where possible
+ AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
+ # TEA specific: Needed by Tcl, but not most extensions
+ #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
+ #LIBS="$LIBS -lxnet" # Use the XOPEN network library
+
+ AS_IF([test "`uname -m`" = ia64], [
+ SHLIB_SUFFIX=".so"
+ # Use newer C++ library for C++ extensions
+ #if test "$GCC" != "yes" ; then
+ # CPPFLAGS="-AA"
+ #fi
+ ], [
+ SHLIB_SUFFIX=".sl"
+ ])
+ AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
+ AS_IF([test "$tcl_ok" = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-E"
+ CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
+ LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
+ LD_LIBRARY_PATH_VAR="SHLIB_PATH"
+ ])
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ CFLAGS="$CFLAGS -z"
+ # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
+ #CFLAGS="$CFLAGS +DAportable"
+ SHLIB_CFLAGS="+z"
+ SHLIB_LD="ld -b"
+ ])
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$GCC" = yes], [
+ case `${CC} -dumpmachine` in
+ hppa64*)
+ # 64-bit gcc in use. Fix flags for GNU ld.
+ do64bit_ok=yes
+ SHLIB_LD='${CC} -shared'
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ;;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system])
+ ;;
+ esac
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS +DD64"
+ LDFLAGS_ARCH="+DD64"
+ ])
+ ]) ;;
+ IRIX-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [
+ CFLAGS="$CFLAGS -mabi=n32"
+ LDFLAGS="$LDFLAGS -mabi=n32"
+ ], [
+ case $system in
+ IRIX-6.3)
+ # Use to build 6.2 compatible binaries on 6.3.
+ CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
+ ;;
+ *)
+ CFLAGS="$CFLAGS -n32"
+ ;;
+ esac
+ LDFLAGS="$LDFLAGS -n32"
+ ])
+ ;;
+ IRIX64-6.*)
+ SHLIB_CFLAGS=""
+ SHLIB_LD="ld -n32 -shared -rdata_shared"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+
+ # Check to enable 64-bit flags for compiler/linker
+
+ AS_IF([test "$do64bit" = yes], [
+ AS_IF([test "$GCC" = yes], [
+ AC_MSG_WARN([64bit mode not supported by gcc])
+ ], [
+ do64bit_ok=yes
+ SHLIB_LD="ld -64 -shared -rdata_shared"
+ CFLAGS="$CFLAGS -64"
+ LDFLAGS_ARCH="-64"
+ ])
+ ])
+ ;;
+ Linux*|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} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'
+ LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
+ AS_IF([test $do64bit = yes], [
+ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -m64"
+ AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_m64 = yes], [
+ CFLAGS="$CFLAGS -m64"
+ do64bit_ok=yes
+ ])
+ ])
+
+ # The combo of gcc + glibc has a bug related to inlining of
+ # functions like strtod(). The -fno-builtin flag should address
+ # this problem but it does not work. The -fno-inline flag is kind
+ # of overkill but it works. Disable inlining only when one of the
+ # files in compat/*.c is being linked in.
+
+ AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
+ ;;
+ Lynx*)
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_SUFFIX=".so"
+ CFLAGS_OPTIMIZE=-02
+ SHLIB_LD='${CC} -shared'
+ LD_FLAGS="-Wl,--export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ ;;
+ OpenBSD-*)
+ arch=`arch -s`
+ case "$arch" in
+ alpha|sparc64)
+ SHLIB_CFLAGS="-fPIC"
+ ;;
+ *)
+ SHLIB_CFLAGS="-fpic"
+ ;;
+ esac
+ SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
+ LDFLAGS="-Wl,-export-dynamic"
+ CFLAGS_OPTIMIZE="-O2"
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # On OpenBSD: Compile with -pthread
+ # Don't link with -lpthread
+ LIBS=`echo $LIBS | sed s/-lpthread//`
+ CFLAGS="$CFLAGS -pthread"
+ ])
+ # 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} ${SHLIB_CFLAGS} -shared'
+ SHLIB_SUFFIX=".so"
+ LDFLAGS="$LDFLAGS -export-dynamic"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the CFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ;;
+ DragonFly-*|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=""
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
+ AS_IF([test "${TCL_THREADS}" = "1"], [
+ # The -pthread needs to go in the LDFLAGS, not LIBS
+ LIBS=`echo $LIBS | sed s/-pthread//`
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
+ 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}'`"
+ AS_IF([test $do64bit = yes], [
+ case `arch` in
+ ppc)
+ AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
+ tcl_cv_cc_arch_ppc64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
+ tcl_cv_cc_arch_ppc64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
+ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
+ do64bit_ok=yes
+ ]);;
+ i386)
+ AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
+ tcl_cv_cc_arch_x86_64, [
+ hold_cflags=$CFLAGS
+ CFLAGS="$CFLAGS -arch x86_64"
+ AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
+ tcl_cv_cc_arch_x86_64=no)
+ CFLAGS=$hold_cflags])
+ AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
+ CFLAGS="$CFLAGS -arch x86_64"
+ do64bit_ok=yes
+ ]);;
+ *)
+ AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
+ esac
+ ], [
+ # Check for combined 32-bit and 64-bit fat build
+ AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
+ fat_32_64=yes])
+ ])
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
+ AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_single_module = yes], [
+ SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
+ ])
+ # TEA specific: link shlib with current and 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:
+ AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
+ LDFLAGS="$LDFLAGS -prebind"])
+ LDFLAGS="$LDFLAGS -headerpad_max_install_names"
+ AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
+ tcl_cv_ld_search_paths_first, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
+ tcl_cv_ld_search_paths_first=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
+ ])
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [__private_extern__],
+ [Compiler support for module scope symbols])
+ tcl_cv_cc_visibility_hidden=yes
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
+ # TEA specific: for combined 32 & 64 bit fat builds of Tk
+ # extensions, verify that 64-bit build is possible.
+ AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
+ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
+ tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
+ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
+ done
+ CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
+ LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
+ AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
+ tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="$hold_'$v'"'
+ done])
+ ])
+ # remove 64-bit arch flags from CFLAGS et al. if configuration
+ # does not support 64-bit.
+ AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
+ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
+ for v in CFLAGS CPPFLAGS LDFLAGS; do
+ eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
+ done])
+ ])
+ ;;
+ OS/390-*)
+ CFLAGS_OPTIMIZE="" # Optimizer is buggy
+ AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h
+ [Should OS/390 do the right thing with sockets?])
+ ;;
+ OSF1-V*)
+ # Digital OSF/1
+ SHLIB_CFLAGS=""
+ AS_IF([test "$SHARED_BUILD" = 1], [
+ SHLIB_LD='ld -shared -expect_unresolved "*"'
+ ], [
+ SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+ ])
+ SHLIB_SUFFIX=".so"
+ AS_IF([test $doRpath = yes], [
+ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
+ AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
+ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
+ # see pthread_intro(3) for pthread support on osf1, k.furukawa
+ AS_IF([test "${TCL_THREADS}" = 1], [
+ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
+ CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
+ LIBS=`echo $LIBS | sed s/-lpthreads//`
+ AS_IF([test "$GCC" = yes], [
+ LIBS="$LIBS -lpthread -lmach -lexc"
+ ], [
+ CFLAGS="$CFLAGS -pthread"
+ LDFLAGS="$LDFLAGS -pthread"
+ ])
+ ])
+ ;;
+ QNX-6*)
+ # QNX RTP
+ # This may work for all QNX, but it was only reported for v6.
+ SHLIB_CFLAGS="-fPIC"
+ SHLIB_LD="ld -Bshareable -x"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ SCO_SV-3.2*)
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_CFLAGS="-fPIC -melf"
+ LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
+ ], [
+ SHLIB_CFLAGS="-Kpic -belf"
+ LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
+ ])
+ SHLIB_LD="ld -G"
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ 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.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ], [
+ SHLIB_LD="/usr/ccs/bin/ld -G -z text"
+ CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ ])
+ ;;
+ SunOS-5*)
+ # Note: If _REENTRANT isn't defined, then Solaris
+ # won't define thread-safe library routines.
+
+ AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
+ [Do we really want to follow the standard? Yes we do!])
+
+ SHLIB_CFLAGS="-KPIC"
+
+ # Check to enable 64-bit flags for compiler/linker
+ AS_IF([test "$do64bit" = yes], [
+ arch=`isainfo`
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ AS_IF([test "$GCC" = yes], [
+ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
+ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
+ ], [
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64 -mcpu=v9"
+ LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
+ SHLIB_CFLAGS="-fPIC"
+ ])
+ ], [
+ do64bit_ok=yes
+ AS_IF([test "$do64bitVIS" = yes], [
+ CFLAGS="$CFLAGS -xarch=v9a"
+ LDFLAGS_ARCH="-xarch=v9a"
+ ], [
+ CFLAGS="$CFLAGS -xarch=v9"
+ LDFLAGS_ARCH="-xarch=v9"
+ ])
+ # Solaris 64 uses this as well
+ #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
+ ])
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ do64bit_ok=yes
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
+ esac
+ ], [
+ do64bit_ok=yes
+ case $system in
+ SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
+ CFLAGS="$CFLAGS -m64"
+ LDFLAGS="$LDFLAGS -m64";;
+ *)
+ CFLAGS="$CFLAGS -xarch=amd64"
+ LDFLAGS="$LDFLAGS -xarch=amd64";;
+ esac
+ ])
+ ], [AC_MSG_WARN([64bit mode not supported for $arch])])])
+ ])
+
+ SHLIB_SUFFIX=".so"
+ AS_IF([test "$GCC" = yes], [
+ SHLIB_LD='${CC} -shared'
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
+ AS_IF([test "$do64bit_ok" = yes], [
+ AS_IF([test "$arch" = "sparcv9 sparc"], [
+ # We need to specify -static-libgcc or we need to
+ # add the path to the sparv9 libgcc.
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
+ # for finding sparcv9 libgcc, get the regular libgcc
+ # path, remove so name and append 'sparcv9'
+ #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
+ #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
+ ], [AS_IF([test "$arch" = "amd64 i386"], [
+ # JH: static-libgcc is necessary for core Tcl, but may
+ # not be necessary for extensions.
+ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
+ ])])
+ ])
+ ], [
+ case $system in
+ SunOS-5.[[1-9]][[0-9]]*)
+ # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
+ SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
+ *)
+ SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
+ esac
+ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
+ LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
+ ])
+ ;;
+ UNIX_SV* | UnixWare-5*)
+ SHLIB_CFLAGS="-KPIC"
+ SHLIB_LD='${CC} -G'
+ SHLIB_LD_LIBS=""
+ SHLIB_SUFFIX=".so"
+ # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
+ # that don't grok the -Bexport option. Test that it does.
+ AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
+ hold_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
+ LDFLAGS=$hold_ldflags])
+ AS_IF([test $tcl_cv_ld_Bexport = yes], [
+ LDFLAGS="$LDFLAGS -Wl,-Bexport"
+ ])
+ CC_SEARCH_FLAGS=""
+ LD_SEARCH_FLAGS=""
+ ;;
+ esac
+
+ AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
+ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
+ ])
+
+dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
+dnl # until the end of configure, as configure's compile and link tests use
+dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
+dnl # preprocessing tests use only CPPFLAGS.
+ AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
+
+ # 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.
+
+ AS_IF([test "$GCC" = yes], [
+ case $system in
+ AIX-*) ;;
+ BSD/OS*) ;;
+ CYGWIN_*|MINGW32_*|MINGW64_*) ;;
+ IRIX*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
+ Darwin-*) ;;
+ SCO_SV-3.2*) ;;
+ windows) ;;
+ *) SHLIB_CFLAGS="-fPIC" ;;
+ esac])
+
+ AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
+ AC_DEFINE(MODULE_SCOPE, [extern],
+ [No Compiler support for module scope symbols])
+ ])
+
+ AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
+ AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
+ # TEA specific: use PACKAGE_VERSION instead of VERSION
+ UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
+
+ if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
+ AC_CACHE_CHECK(for SEH support in compiler,
+ tcl_cv_seh,
+ AC_TRY_RUN([
+#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;
+ }
+ ],
+ tcl_cv_seh=yes,
+ tcl_cv_seh=no,
+ tcl_cv_seh=no)
+ )
+ if test "$tcl_cv_seh" = "no" ; then
+ AC_DEFINE(HAVE_NO_SEH, 1,
+ [Defined when mingw does not support SEH])
+ 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.
+ #
+ AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
+ tcl_cv_eh_disposition,
+ AC_TRY_COMPILE([
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+ ],[
+ EXCEPTION_DISPOSITION x;
+ ],
+ tcl_cv_eh_disposition=yes,
+ tcl_cv_eh_disposition=no)
+ )
+ if test "$tcl_cv_eh_disposition" = "no" ; then
+ AC_DEFINE(EXCEPTION_DISPOSITION, int,
+ [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
+ 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.
+
+ AC_CACHE_CHECK(for winnt.h that ignores VOID define,
+ tcl_cv_winnt_ignore_void,
+ AC_TRY_COMPILE([
+#define VOID void
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+ ], [
+ CHAR c;
+ SHORT s;
+ LONG l;
+ ],
+ tcl_cv_winnt_ignore_void=yes,
+ tcl_cv_winnt_ignore_void=no)
+ )
+ if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
+ AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
+ [Defined when cygwin/mingw ignores VOID define in winnt.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.
+
+ AC_CACHE_CHECK(for cast to union support,
+ tcl_cv_cast_to_union,
+ AC_TRY_COMPILE([],
+ [
+ union foo { int i; double d; };
+ union foo f = (union foo) (int) 0;
+ ],
+ tcl_cv_cast_to_union=yes,
+ tcl_cv_cast_to_union=no)
+ )
+ if test "$tcl_cv_cast_to_union" = "yes"; then
+ AC_DEFINE(HAVE_CAST_TO_UNION, 1,
+ [Defined when compiler supports casting to union type.])
+ fi
+
+ AC_SUBST(CFLAGS_DEBUG)
+ AC_SUBST(CFLAGS_OPTIMIZE)
+ AC_SUBST(CFLAGS_WARNING)
+
+ AC_SUBST(STLIB_LD)
+ AC_SUBST(SHLIB_LD)
+
+ AC_SUBST(SHLIB_LD_LIBS)
+ AC_SUBST(SHLIB_CFLAGS)
+
+ AC_SUBST(LD_LIBRARY_PATH_VAR)
+
+ # These must be called after we do the basic CFLAGS checks and
+ # verify any possible 64-bit or similar switches are necessary
+ TEA_TCL_EARLY_FLAGS
+ TEA_TCL_64BIT_FLAGS
+])
+
+#--------------------------------------------------------------------
+# TEA_SERIAL_PORT
+#
+# Determine which interface to use to talk to the serial port.
+# Note that #include lines must begin in leftmost column for
+# some compilers to recognize them as preprocessor directives,
+# and some build environments have stdin not pointing at a
+# pseudo-terminal (usually /dev/null instead.)
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines only one of the following vars:
+# HAVE_SYS_MODEM_H
+# USE_TERMIOS
+# USE_TERMIO
+# USE_SGTTY
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_SERIAL_PORT], [
+ AC_CHECK_HEADERS(sys/modem.h)
+ AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
+ AC_TRY_RUN([
+#include <termios.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termio.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no ; then
+ AC_TRY_RUN([
+#include <termios.h>
+#include <errno.h>
+
+int main() {
+ struct termios t;
+ if (tcgetattr(0, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ cfsetospeed(&t, 0);
+ t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <termio.h>
+#include <errno.h>
+
+int main() {
+ struct termio t;
+ if (ioctl(0, TCGETA, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
+ return 0;
+ }
+ return 1;
+ }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
+ fi
+ if test $tcl_cv_api_serial = no; then
+ AC_TRY_RUN([
+#include <sgtty.h>
+#include <errno.h>
+
+int main() {
+ struct sgttyb t;
+ if (ioctl(0, TIOCGETP, &t) == 0
+ || errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
+ t.sg_ospeed = 0;
+ t.sg_flags |= ODDP | EVENP | RAW;
+ return 0;
+ }
+ return 1;
+}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
+ fi])
+ case $tcl_cv_api_serial in
+ termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
+ termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
+ sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_PATH_X
+#
+# Locate the X11 header files and the X11 library archive. Try
+# the ac_path_x macro first, but if it doesn't find the X stuff
+# (e.g. because there's no xmkmf program) then check through
+# a list of possible directories. Under some conditions the
+# autoconf macro will return an include directory that contains
+# no include files, so double-check its result just to be safe.
+#
+# This should be called after TEA_CONFIG_CFLAGS as setting the
+# LIBS line can confuse some configure macro magic.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets the following vars:
+# XINCLUDES
+# XLIBSW
+# PKG_LIBS (appends to)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_X], [
+ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
+ TEA_PATH_UNIX_X
+ fi
+])
+
+AC_DEFUN([TEA_PATH_UNIX_X], [
+ AC_PATH_X
+ not_really_there=""
+ if test "$no_x" = ""; then
+ if test "$x_includes" = ""; then
+ AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
+ else
+ if test ! -r $x_includes/X11/Xlib.h; then
+ not_really_there="yes"
+ fi
+ fi
+ fi
+ if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
+ AC_MSG_CHECKING([for X11 header files])
+ found_xincludes="no"
+ AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
+ if test "$found_xincludes" = "no"; then
+ dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
+ for i in $dirs ; do
+ if test -r $i/X11/Xlib.h; then
+ AC_MSG_RESULT([$i])
+ XINCLUDES=" -I$i"
+ found_xincludes="yes"
+ break
+ fi
+ done
+ fi
+ else
+ if test "$x_includes" != ""; then
+ XINCLUDES="-I$x_includes"
+ found_xincludes="yes"
+ fi
+ fi
+ if test "$found_xincludes" = "no"; then
+ AC_MSG_RESULT([couldn't find any!])
+ fi
+
+ if test "$no_x" = yes; then
+ AC_MSG_CHECKING([for X11 libraries])
+ XLIBSW=nope
+ dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
+ for i in $dirs ; do
+ if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
+ AC_MSG_RESULT([$i])
+ XLIBSW="-L$i -lX11"
+ x_libraries="$i"
+ break
+ fi
+ done
+ else
+ if test "$x_libraries" = ""; then
+ XLIBSW=-lX11
+ else
+ XLIBSW="-L$x_libraries -lX11"
+ fi
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
+ fi
+ if test "$XLIBSW" = nope ; then
+ AC_MSG_RESULT([could not find any! Using -lX11.])
+ XLIBSW=-lX11
+ fi
+ # TEA specific:
+ if test x"${XLIBSW}" != x ; then
+ PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BLOCKING_STYLE
+#
+# The statements below check for systems where POSIX-style
+# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
+# On these systems (mostly older ones), use the old BSD-style
+# FIONBIO approach instead.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# HAVE_SYS_IOCTL_H
+# HAVE_SYS_FILIO_H
+# USE_FIONBIO
+# O_NONBLOCK
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BLOCKING_STYLE], [
+ AC_CHECK_HEADERS(sys/ioctl.h)
+ AC_CHECK_HEADERS(sys/filio.h)
+ TEA_CONFIG_SYSTEM
+ AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
+ case $system in
+ OSF*)
+ AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
+ AC_MSG_RESULT([FIONBIO])
+ ;;
+ *)
+ AC_MSG_RESULT([O_NONBLOCK])
+ ;;
+ esac
+])
+
+#--------------------------------------------------------------------
+# TEA_TIME_HANDLER
+#
+# Checks how the system deals with time.h, what time structures
+# are used on the system, and what fields the structures have.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines some of the following vars:
+# USE_DELTA_FOR_TZ
+# HAVE_TM_GMTOFF
+# HAVE_TM_TZADJ
+# HAVE_TIMEZONE_VAR
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TIME_HANDLER], [
+ AC_CHECK_HEADERS(sys/time.h)
+ AC_HEADER_TIME
+ AC_STRUCT_TIMEZONE
+
+ AC_CHECK_FUNCS(gmtime_r localtime_r)
+
+ AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
+ tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
+ if test $tcl_cv_member_tm_tzadj = yes ; then
+ AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
+ fi
+
+ AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
+ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
+ tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
+ if test $tcl_cv_member_tm_gmtoff = yes ; then
+ AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
+ fi
+
+ #
+ # Its important to include time.h in this check, as some systems
+ # (like convex) have timezone functions, etc.
+ #
+ AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern long timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
+ if test $tcl_cv_timezone_long = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ else
+ #
+ # On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
+ #
+ AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
+ AC_TRY_COMPILE([#include <time.h>],
+ [extern time_t timezone;
+ timezone += 1;
+ exit (0);],
+ tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
+ if test $tcl_cv_timezone_time = yes ; then
+ AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_BUGGY_STRTOD
+#
+# Under Solaris 2.4, strtod returns the wrong value for the
+# terminating character under some conditions. Check for this
+# and if the problem exists use a substitute procedure
+# "fixstrtod" (provided by Tcl) that corrects the error.
+# Also, on Compaq's Tru64 Unix 5.0,
+# strtod(" ") returns 0.0 instead of a failure to convert.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Might defines some of the following vars:
+# strtod (=fixstrtod)
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_BUGGY_STRTOD], [
+ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
+ if test "$tcl_strtod" = 1; then
+ AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
+ AC_TRY_RUN([
+ extern double strtod();
+ int main() {
+ char *infString="Inf", *nanString="NaN", *spaceString=" ";
+ char *term;
+ double value;
+ value = strtod(infString, &term);
+ if ((term != infString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(nanString, &term);
+ if ((term != nanString) && (term[-1] == 0)) {
+ exit(1);
+ }
+ value = strtod(spaceString, &term);
+ if (term == (spaceString+1)) {
+ exit(1);
+ }
+ exit(0);
+ }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
+ tcl_cv_strtod_buggy=buggy)])
+ if test "$tcl_cv_strtod_buggy" = buggy; then
+ AC_LIBOBJ([fixstrtod])
+ USE_COMPAT=1
+ AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
+ fi
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_EARLY_FLAGS
+#
+# Check for what flags are needed to be passed so the correct OS
+# features are available.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# _ISOC99_SOURCE
+# _LARGEFILE64_SOURCE
+# _LARGEFILE_SOURCE64
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_EARLY_FLAG],[
+ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
+ AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
+ AC_TRY_COMPILE([[#define ]$1[ 1
+]$2], $3,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
+ [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
+ if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
+ AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+ tcl_flags="$tcl_flags $1"
+ fi
+])
+
+AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
+ AC_MSG_CHECKING([for required early compiler flags])
+ tcl_flags=""
+ TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
+ [char *p = (char *)strtoll; char *q = (char *)strtoull;])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
+ [struct stat64 buf; int i = stat64("/", &buf);])
+ TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
+ [char *p = (char *)open64;])
+ if test "x${tcl_flags}" = "x" ; then
+ AC_MSG_RESULT([none])
+ else
+ AC_MSG_RESULT([${tcl_flags}])
+ fi
+])
+
+#--------------------------------------------------------------------
+# TEA_TCL_64BIT_FLAGS
+#
+# Check for what is defined in the way of 64-bit features.
+#
+# Arguments:
+# None
+#
+# Results:
+#
+# Might define the following vars:
+# TCL_WIDE_INT_IS_LONG
+# TCL_WIDE_INT_TYPE
+# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_STAT64
+# HAVE_TYPE_OFF64_T
+#--------------------------------------------------------------------
+
+AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
+ AC_MSG_CHECKING([for 64-bit integer type])
+ AC_CACHE_VAL(tcl_cv_type_64bit,[
+ tcl_cv_type_64bit=none
+ # See if the compiler knows natively about __int64
+ AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
+ tcl_type_64bit=__int64, tcl_type_64bit="long long")
+ # See if we should use long anyway Note that we substitute in the
+ # type that is our current guess for a 64-bit type inside this check
+ # program, so it should be modified only carefully...
+ AC_TRY_COMPILE(,[switch (0) {
+ case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
+ }],tcl_cv_type_64bit=${tcl_type_64bit})])
+ if test "${tcl_cv_type_64bit}" = none ; then
+ AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
+ AC_MSG_RESULT([using long])
+ elif test "${tcl_cv_type_64bit}" = "__int64" \
+ -a "${TEA_PLATFORM}" = "windows" ; then
+ # TEA specific: We actually want to use the default tcl.h checks in
+ # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
+ AC_MSG_RESULT([using Tcl header defaults])
+ else
+ AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
+ [What type should be used to define wide integers?])
+ AC_MSG_RESULT([${tcl_cv_type_64bit}])
+
+ # Now check for auxiliary declarations
+ AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 p;],
+ tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
+ if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
+ fi
+
+ AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
+ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
+],
+ tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
+ if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
+ AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
+ fi
+
+ AC_CHECK_FUNCS(open64 lseek64)
+ AC_MSG_CHECKING([for off64_t])
+ AC_CACHE_VAL(tcl_cv_type_off64_t,[
+ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
+],
+ tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
+ dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
+ dnl functions lseek64 and open64 are defined.
+ if test "x${tcl_cv_type_off64_t}" = "xyes" && \
+ test "x${ac_cv_func_lseek64}" = "xyes" && \
+ test "x${ac_cv_func_open64}" = "xyes" ; then
+ AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+])
+
+##
+## Here ends the standard Tcl configuration bits and starts the
+## TEA specific functions
+##
+
+#------------------------------------------------------------------------
+# TEA_INIT --
+#
+# Init various Tcl Extension Architecture (TEA) variables.
+# This should be the first called TEA_* macro.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Defines and substs the following vars:
+# CYGPATH
+# EXEEXT
+# Defines only:
+# TEA_VERSION
+# TEA_INITED
+# TEA_PLATFORM (windows or unix)
+#
+# "cygpath" is used on windows to generate native path names for include
+# files. These variables should only be used with the compiler and linker
+# since they generate native path names.
+#
+# EXEEXT
+# Select the executable extension based on the host type. This
+# is a lightweight replacement for AC_EXEEXT that doesn't require
+# a compiler.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INIT], [
+ TEA_VERSION="3.13"
+
+ AC_MSG_CHECKING([TEA configuration])
+ if test x"${PACKAGE_NAME}" = x ; then
+ AC_MSG_ERROR([
+The PACKAGE_NAME variable must be defined by your TEA configure.ac])
+ fi
+ AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
+
+ # 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_*|*MINGW64_*)
+ AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
+ 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
+
+ AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
+
+ AC_SUBST(EXEEXT)
+ AC_SUBST(CYGPATH)
+
+ # This package name must be replaced statically for AC_SUBST to work
+ AC_SUBST(PKG_LIB_FILE)
+ # Substitute STUB_LIB_FILE in case package creates a stub library too.
+ AC_SUBST(PKG_STUB_LIB_FILE)
+
+ # We AC_SUBST these here to ensure they are subst'ed,
+ # in case the user doesn't call TEA_ADD_...
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+ AC_SUBST(PKG_TCL_SOURCES)
+ AC_SUBST(PKG_HEADERS)
+ AC_SUBST(PKG_INCLUDES)
+ AC_SUBST(PKG_LIBS)
+ AC_SUBST(PKG_CFLAGS)
+
+ # Configure the installer.
+ TEA_INSTALLER
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_SOURCES
+# PKG_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ case $i in
+ [\$]*)
+ # allow $-var names
+ PKG_SOURCES="$PKG_SOURCES $i"
+ PKG_OBJECTS="$PKG_OBJECTS $i"
+ ;;
+ *)
+ # check for existence - allows for generic/win/unix VPATH
+ # To add more dirs here (like 'src'), you have to update VPATH
+ # in Makefile.in as well
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find source file '$i'])
+ fi
+ PKG_SOURCES="$PKG_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_OBJECTS="$PKG_OBJECTS $j"
+ ;;
+ esac
+ done
+ AC_SUBST(PKG_SOURCES)
+ AC_SUBST(PKG_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_STUB_SOURCES --
+#
+# Specify one or more source files. Users should check for
+# the right platform before adding to their list.
+# It is not important to specify the directory, as long as it is
+# in the generic, win or unix subdirectory of $(srcdir).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_STUB_SOURCES
+# PKG_STUB_OBJECTS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_STUB_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence - allows for generic/win/unix VPATH
+ if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
+ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
+ -a ! -f "${srcdir}/macosx/$i" \
+ ; then
+ AC_MSG_ERROR([could not find stub source file '$i'])
+ fi
+ PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
+ # this assumes it is in a VPATH dir
+ i=`basename $i`
+ # handle user calling this before or after TEA_SETUP_COMPILER
+ if test x"${OBJEXT}" != x ; then
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
+ else
+ j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
+ fi
+ PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
+ done
+ AC_SUBST(PKG_STUB_SOURCES)
+ AC_SUBST(PKG_STUB_OBJECTS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_TCL_SOURCES --
+#
+# Specify one or more Tcl source files. These should be platform
+# independent runtime files.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_TCL_SOURCES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_TCL_SOURCES], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
+ fi
+ PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
+ done
+ AC_SUBST(PKG_TCL_SOURCES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_HEADERS --
+#
+# Specify one or more source headers. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_HEADERS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_HEADERS], [
+ vars="$@"
+ for i in $vars; do
+ # check for existence, be strict because it is installed
+ if test ! -f "${srcdir}/$i" ; then
+ AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
+ fi
+ PKG_HEADERS="$PKG_HEADERS $i"
+ done
+ AC_SUBST(PKG_HEADERS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_INCLUDES --
+#
+# Specify one or more include dirs. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_INCLUDES
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_INCLUDES], [
+ vars="$@"
+ for i in $vars; do
+ PKG_INCLUDES="$PKG_INCLUDES $i"
+ done
+ AC_SUBST(PKG_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_LIBS --
+#
+# Specify one or more libraries. Users should check for
+# the right platform before adding to their list. For Windows,
+# libraries provided in "foo.lib" format will be converted to
+# "-lfoo" when using GCC (mingw).
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_LIBS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_LIBS], [
+ vars="$@"
+ for i in $vars; do
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
+ # Convert foo.lib to -lfoo for GCC. No-op if not *.lib
+ i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
+ fi
+ PKG_LIBS="$PKG_LIBS $i"
+ done
+ AC_SUBST(PKG_LIBS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CFLAGS --
+#
+# Specify one or more CFLAGS. Users should check for
+# the right platform before adding to their list.
+#
+# Arguments:
+# one or more file names
+#
+# Results:
+#
+# Defines and substs the following vars:
+# PKG_CFLAGS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CFLAGS], [
+ PKG_CFLAGS="$PKG_CFLAGS $@"
+ AC_SUBST(PKG_CFLAGS)
+])
+
+#------------------------------------------------------------------------
+# TEA_ADD_CLEANFILES --
+#
+# Specify one or more CLEANFILES.
+#
+# Arguments:
+# one or more file names to clean target
+#
+# Results:
+#
+# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ADD_CLEANFILES], [
+ CLEANFILES="$CLEANFILES $@"
+])
+
+#------------------------------------------------------------------------
+# TEA_PREFIX --
+#
+# Handle the --prefix=... option by defaulting to what Tcl gave
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# If --prefix or --exec-prefix was not specified, $prefix and
+# $exec_prefix will be set to the values given to Tcl when it was
+# configured.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_PREFIX], [
+ if test "${prefix}" = "NONE"; then
+ prefix_default=yes
+ if test x"${TCL_PREFIX}" != x; then
+ AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
+ prefix=${TCL_PREFIX}
+ else
+ AC_MSG_NOTICE([--prefix defaulting to /usr/local])
+ prefix=/usr/local
+ fi
+ fi
+ if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
+ -o x"${exec_prefix_default}" = x"yes" ; then
+ if test x"${TCL_EXEC_PREFIX}" != x; then
+ AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
+ exec_prefix=${TCL_EXEC_PREFIX}
+ else
+ AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
+ exec_prefix=$prefix
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER_CC --
+#
+# Do compiler checks the way we want. This is just a replacement
+# for AC_PROG_CC in TEA configure.ac files to make them cleaner.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER_CC], [
+ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
+ # in this macro, they need to go into TEA_SETUP_COMPILER instead.
+
+ AC_PROG_CC
+ AC_PROG_CPP
+
+ #--------------------------------------------------------------------
+ # Checks to see if the make program sets the $MAKE variable.
+ #--------------------------------------------------------------------
+
+ AC_PROG_MAKE_SET
+
+ #--------------------------------------------------------------------
+ # Find ranlib
+ #--------------------------------------------------------------------
+
+ AC_CHECK_TOOL(RANLIB, ranlib)
+
+ #--------------------------------------------------------------------
+ # Determines the correct binary file extension (.o, .obj, .exe etc.)
+ #--------------------------------------------------------------------
+
+ AC_OBJEXT
+ AC_EXEEXT
+])
+
+#------------------------------------------------------------------------
+# TEA_SETUP_COMPILER --
+#
+# Do compiler checks that use the compiler. This must go after
+# TEA_SETUP_COMPILER_CC, which does the actual compiler check.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Sets up CC var and other standard bits we need to make executables.
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_SETUP_COMPILER], [
+ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
+ AC_REQUIRE([TEA_SETUP_COMPILER_CC])
+
+ #------------------------------------------------------------------------
+ # If we're using GCC, see if the compiler understands -pipe. If so, use it.
+ # It makes compiling go faster. (This is only a performance feature.)
+ #------------------------------------------------------------------------
+
+ if test -z "$no_pipe" -a -n "$GCC"; then
+ AC_CACHE_CHECK([if the compiler understands -pipe],
+ tcl_cv_cc_pipe, [
+ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
+ AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
+ CFLAGS=$hold_cflags])
+ if test $tcl_cv_cc_pipe = yes; then
+ CFLAGS="$CFLAGS -pipe"
+ fi
+ fi
+
+ #--------------------------------------------------------------------
+ # Common compiler flag setup
+ #--------------------------------------------------------------------
+
+ AC_C_BIGENDIAN
+])
+
+#------------------------------------------------------------------------
+# TEA_MAKE_LIB --
+#
+# Generate a line that can be used to build a shared/unshared library
+# in a platform independent manner.
+#
+# Arguments:
+# none
+#
+# Requires:
+#
+# Results:
+#
+# Defines the following vars:
+# CFLAGS - Done late here to note disturb other AC macros
+# MAKE_LIB - Command to execute to build the Tcl library;
+# differs depending on whether or not Tcl is being
+# compiled as a shared library.
+# MAKE_SHARED_LIB Makefile rule for building a shared library
+# MAKE_STATIC_LIB Makefile rule for building a static library
+# MAKE_STUB_LIB Makefile rule for building a stub library
+# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
+# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_MAKE_LIB], [
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
+ MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
+ MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
+ AC_EGREP_CPP([manifest needed], [
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+print("manifest needed")
+#endif
+ ], [
+ # 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}"
+ TEA_ADD_CLEANFILES([*.manifest])
+ ])
+ 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
+
+ AC_SUBST(MAKE_LIB)
+ AC_SUBST(MAKE_SHARED_LIB)
+ AC_SUBST(MAKE_STATIC_LIB)
+ AC_SUBST(MAKE_STUB_LIB)
+ AC_SUBST(RANLIB_STUB)
+ AC_SUBST(VC_MANIFEST_EMBED_DLL)
+ AC_SUBST(VC_MANIFEST_EMBED_EXE)
+])
+
+#------------------------------------------------------------------------
+# TEA_LIB_SPEC --
+#
+# Compute the name of an existing object library located in libdir
+# from the given base name and produce the appropriate linker flags.
+#
+# Arguments:
+# basename The base name of the library without version
+# numbers, extensions, or "lib" prefixes.
+# extra_dir Extra directory in which to search for the
+# library. This location is used first, then
+# $prefix/$exec-prefix, then some defaults.
+#
+# Requires:
+# TEA_INIT and TEA_PREFIX must be called first.
+#
+# Results:
+#
+# Defines the following vars:
+# ${basename}_LIB_NAME The computed library name.
+# ${basename}_LIB_SPEC The computed linker flags.
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LIB_SPEC], [
+ AC_MSG_CHECKING([for $1 library])
+
+ # Look in exec-prefix for the library (defined by TEA_PREFIX).
+
+ tea_lib_name_dir="${exec_prefix}/lib"
+
+ # Or in a user-specified location.
+
+ if test x"$2" != x ; then
+ tea_extra_lib_dir=$2
+ else
+ tea_extra_lib_dir=NONE
+ fi
+
+ for i in \
+ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
+ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
+ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
+ if test -f "$i" ; then
+ tea_lib_name_dir=`dirname $i`
+ $1_LIB_NAME=`basename $i`
+ $1_LIB_PATH_NAME=$i
+ break
+ fi
+ done
+
+ if test "${TEA_PLATFORM}" = "windows"; then
+ $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
+ else
+ # Strip off the leading "lib" and trailing ".a" or ".so"
+
+ tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
+ $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
+ fi
+
+ if test "x${$1_LIB_NAME}" = x ; then
+ AC_MSG_ERROR([not found])
+ else
+ AC_MSG_RESULT([${$1_LIB_SPEC}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TCL_HEADERS --
+#
+# Locate the private Tcl include files
+#
+# Arguments:
+#
+# Requires:
+# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TCL_TOP_DIR_NATIVE
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
+ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
+ AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
+ AC_MSG_CHECKING([for Tcl private include files])
+
+ TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
+ TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
+
+ # Check to see if tcl<Plat>Port.h isn't already with the public headers
+ # Don't look for tclInt.h because that resides with tcl.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tclh}/tclWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
+ else
+ TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TCL_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ if test -d "${TCL_BIN_DIR}/Headers" -a \
+ -d "${TCL_BIN_DIR}/PrivateHeaders"; then
+ TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
+ else
+ TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TCL_INCLUDES}"
+ else
+ if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
+ fi
+ result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TCL_TOP_DIR_NATIVE)
+
+ AC_SUBST(TCL_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TCL_HEADERS --
+#
+# Locate the installed public Tcl header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tclinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TCL_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
+ AC_MSG_CHECKING([for Tcl public headers])
+
+ AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tclh, [
+ # Use the value from --with-tclinclude, if it was given
+
+ if test x"${with_tclinclude}" != x ; then
+ if test -f "${with_tclinclude}/tcl.h" ; then
+ ac_cv_c_tclh=${with_tclinclude}
+ else
+ AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tcl was built as a framework, attempt to use
+ # the framework's Headers directory
+ case ${TCL_DEFS} in
+ *TCL_FRAMEWORK*)
+ list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tcl is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TCL_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TCL_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tcl.h" ; then
+ ac_cv_c_tclh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tclh}" = x ; then
+ AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tclh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
+
+ TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TCL_INCLUDES)
+])
+
+#------------------------------------------------------------------------
+# TEA_PRIVATE_TK_HEADERS --
+#
+# Locate the private Tk include files
+#
+# Arguments:
+#
+# Requires:
+# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has
+# already been called.
+#
+# Results:
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
+ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
+ AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
+ AC_MSG_CHECKING([for Tk private include files])
+
+ TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
+ TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
+
+ # Check to see if tk<Plat>Port.h isn't already with the public headers
+ # Don't look for tkInt.h because that resides with tk.h in the core
+ # sources, but the <plat>Port headers are in a different directory
+ if test "${TEA_PLATFORM}" = "windows" -a \
+ -f "${ac_cv_c_tkh}/tkWinPort.h"; then
+ result="private headers found with public headers"
+ elif test "${TEA_PLATFORM}" = "unix" -a \
+ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then
+ result="private headers found with public headers"
+ else
+ TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
+ TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
+ if test "${TEA_PLATFORM}" = "windows"; then
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
+ else
+ TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
+ fi
+ # Overwrite the previous TK_INCLUDES as this should capture both
+ # public and private headers in the same set.
+ # We want to ensure these are substituted so as not to require
+ # any *_NATIVE vars be defined in the Makefile
+ TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
+ # Detect and add ttk subdir
+ if test -d "${TK_SRC_DIR}/generic/ttk"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
+ fi
+ if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
+ TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
+ fi
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers and PrivateHeaders directories
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ if test -d "${TK_BIN_DIR}/Headers" -a \
+ -d "${TK_BIN_DIR}/PrivateHeaders"; then
+ TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
+ else
+ TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
+ fi
+ ;;
+ esac
+ result="Using ${TK_INCLUDES}"
+ else
+ if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
+ AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
+ fi
+ result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
+ fi
+ fi
+
+ AC_SUBST(TK_TOP_DIR_NATIVE)
+ AC_SUBST(TK_XLIB_DIR_NATIVE)
+
+ AC_SUBST(TK_INCLUDES)
+ AC_MSG_RESULT([${result}])
+])
+
+#------------------------------------------------------------------------
+# TEA_PUBLIC_TK_HEADERS --
+#
+# Locate the installed public Tk header files
+#
+# Arguments:
+# None.
+#
+# Requires:
+# CYGPATH must be set
+#
+# Results:
+#
+# Adds a --with-tkinclude switch to configure.
+# Result is cached.
+#
+# Substitutes the following vars:
+# TK_INCLUDES
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
+ AC_MSG_CHECKING([for Tk public headers])
+
+ AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval})
+
+ AC_CACHE_VAL(ac_cv_c_tkh, [
+ # Use the value from --with-tkinclude, if it was given
+
+ if test x"${with_tkinclude}" != x ; then
+ if test -f "${with_tkinclude}/tk.h" ; then
+ ac_cv_c_tkh=${with_tkinclude}
+ else
+ AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
+ fi
+ else
+ list=""
+ if test "`uname -s`" = "Darwin"; then
+ # If Tk was built as a framework, attempt to use
+ # the framework's Headers directory.
+ case ${TK_DEFS} in
+ *TK_FRAMEWORK*)
+ list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
+ ;;
+ esac
+ fi
+
+ # Look in the source dir only if Tk is not installed,
+ # and in that situation, look there before installed locations.
+ if test -f "${TK_BIN_DIR}/Makefile" ; then
+ list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
+ fi
+
+ # Check order: pkg --prefix location, Tk's --prefix location,
+ # relative to directory of tkConfig.sh, Tcl's --prefix location,
+ # relative to directory of tclConfig.sh.
+
+ eval "temp_includedir=${includedir}"
+ list="$list \
+ `ls -d ${temp_includedir} 2>/dev/null` \
+ `ls -d ${TK_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \
+ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \
+ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
+ if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
+ list="$list /usr/local/include /usr/include"
+ if test x"${TK_INCLUDE_SPEC}" != x ; then
+ d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
+ list="$list `ls -d ${d} 2>/dev/null`"
+ fi
+ fi
+ for i in $list ; do
+ if test -f "$i/tk.h" ; then
+ ac_cv_c_tkh=$i
+ break
+ fi
+ done
+ fi
+ ])
+
+ # Print a message based on how we determined the include path
+
+ if test x"${ac_cv_c_tkh}" = x ; then
+ AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude])
+ else
+ AC_MSG_RESULT([${ac_cv_c_tkh}])
+ fi
+
+ # Convert to a native path and substitute into the output files.
+
+ INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
+
+ TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+
+ AC_SUBST(TK_INCLUDES)
+
+ if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
+ # On Windows and Aqua, we need the X compat headers
+ AC_MSG_CHECKING([for X11 header files])
+ if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
+ INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
+ TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
+ AC_SUBST(TK_XINCLUDES)
+ fi
+ AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_PATH_CONFIG --
+#
+# Locate the ${1}Config.sh file and perform a sanity check on
+# the ${1} compile flags. These are used by packages like
+# [incr Tk] that load *Config.sh files from more than Tcl and Tk.
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-$1=...
+#
+# Defines the following vars:
+# $1_BIN_DIR Full path to the directory containing
+# the $1Config.sh file
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CONFIG], [
+ #
+ # Ok, lets find the $1 configuration
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-$1
+ #
+
+ if test x"${no_$1}" = x ; then
+ # we reset no_$1 in case something fails here
+ no_$1=true
+ AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
+ AC_MSG_CHECKING([for $1 configuration])
+ AC_CACHE_VAL(ac_cv_c_$1config,[
+
+ # First check to see if --with-$1 was specified.
+ if test x"${with_$1config}" != x ; then
+ case ${with_$1config} in
+ */$1Config.sh )
+ if test -f ${with_$1config}; then
+ AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
+ with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
+ fi;;
+ esac
+ if test -f "${with_$1config}/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
+ else
+ AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
+ fi
+ fi
+
+ # then check for a private $1 installation
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in \
+ ../$1 \
+ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../$1 \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ../../../$1 \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../$1 \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
+ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ if test -f "$i/unix/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i/unix; pwd)`
+ break
+ fi
+ done
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_$1config}" = x ; then
+ for i in `ls -d ${libdir} 2>/dev/null` \
+ `ls -d ${exec_prefix}/lib 2>/dev/null` \
+ `ls -d ${prefix}/lib 2>/dev/null` \
+ `ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
+ `ls -d /usr/pkg/lib 2>/dev/null` \
+ `ls -d /usr/lib 2>/dev/null` \
+ `ls -d /usr/lib64 2>/dev/null` \
+ ; do
+ if test -f "$i/$1Config.sh" ; then
+ ac_cv_c_$1config=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_$1config}" = x ; then
+ $1_BIN_DIR="# no $1 configs found"
+ AC_MSG_WARN([Cannot find $1 configuration definitions])
+ exit 0
+ else
+ no_$1=
+ $1_BIN_DIR=${ac_cv_c_$1config}
+ AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG --
+#
+# Load the $1Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1_BIN_DIR
+#
+# Results:
+#
+# Substitutes the following vars:
+# $1_SRC_DIR
+# $1_LIB_FILE
+# $1_LIB_SPEC
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_LOAD_CONFIG], [
+ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
+
+ if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
+ AC_MSG_RESULT([loading])
+ . "${$1_BIN_DIR}/$1Config.sh"
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+
+ #
+ # If the $1_BIN_DIR is the build directory (not the install directory),
+ # then set the common variable name to the value of the build variables.
+ # For example, the variable $1_LIB_SPEC will be set to the value
+ # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
+ # instead of $1_BUILD_LIB_SPEC since it will work with both an
+ # installed and uninstalled version of Tcl.
+ #
+
+ if test -f "${$1_BIN_DIR}/Makefile" ; then
+ AC_MSG_WARN([Found Makefile - using build library specs for $1])
+ $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+ $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+ $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+ $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+ $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+ fi
+
+ AC_SUBST($1_VERSION)
+ AC_SUBST($1_BIN_DIR)
+ AC_SUBST($1_SRC_DIR)
+
+ AC_SUBST($1_LIB_FILE)
+ AC_SUBST($1_LIB_SPEC)
+
+ AC_SUBST($1_STUB_LIB_FILE)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ # Allow the caller to prevent this auto-check by specifying any 2nd arg
+ AS_IF([test "x$2" = x], [
+ # Check both upper and lower-case variants
+ # If a dev wanted non-stubs libs, this function could take an option
+ # to not use _STUB in the paths below
+ AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
+ [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
+ [TEA_LOAD_CONFIG_LIB($1_STUB)])
+ ])
+])
+
+#------------------------------------------------------------------------
+# TEA_LOAD_CONFIG_LIB --
+#
+# Helper function to load correct library from another extension's
+# ${PACKAGE}Config.sh.
+#
+# Results:
+# Adds to LIBS the appropriate extension library
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
+ AC_MSG_CHECKING([For $1 library for LIBS])
+ # This simplifies the use of stub libraries by automatically adding
+ # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS,
+ # but this is called before CONFIG_CFLAGS. More importantly, this adds
+ # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
+ if test "x${$1_LIB_SPEC}" != "x" ; then
+ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
+ TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
+ AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
+ else
+ TEA_ADD_LIBS([${$1_LIB_SPEC}])
+ AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
+ fi
+ else
+ AC_MSG_RESULT([file not found])
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_EXPORT_CONFIG --
+#
+# Define the data to insert into the ${PACKAGE}Config.sh file
+#
+# Arguments:
+#
+# Requires the following vars to be set:
+# $1
+#
+# Results:
+# Substitutes the following vars:
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_EXPORT_CONFIG], [
+ #--------------------------------------------------------------------
+ # These are for $1Config.sh
+ #--------------------------------------------------------------------
+
+ # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
+ eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
+ if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
+ eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
+ else
+ eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
+ fi
+ $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
+ $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
+ $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
+ $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
+ $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"
+
+ AC_SUBST($1_BUILD_LIB_SPEC)
+ AC_SUBST($1_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_SPEC)
+ AC_SUBST($1_STUB_LIB_SPEC)
+ AC_SUBST($1_BUILD_STUB_LIB_PATH)
+ AC_SUBST($1_STUB_LIB_PATH)
+
+ AC_SUBST(MAJOR_VERSION)
+ AC_SUBST(MINOR_VERSION)
+ AC_SUBST(PATCHLEVEL)
+])
+
+
+#------------------------------------------------------------------------
+# TEA_PATH_CELIB --
+#
+# Locate Keuchel's celib emulation layer for targeting Win/CE
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-celib=...
+#
+# Defines the following vars:
+# CELIB_DIR Full path to the directory containing
+# the include and platform lib files
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_PATH_CELIB], [
+ # First, look for one uninstalled.
+ # the alternative search directory is invoked by --with-celib
+
+ if test x"${no_celib}" = x ; then
+ # we reset no_celib in case something fails here
+ no_celib=true
+ AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval})
+ AC_MSG_CHECKING([for Windows/CE celib directory])
+ AC_CACHE_VAL(ac_cv_c_celibconfig,[
+ # First check to see if --with-celibconfig was specified.
+ if test x"${with_celibconfig}" != x ; then
+ if test -d "${with_celibconfig}/inc" ; then
+ ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
+ else
+ AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
+ fi
+ fi
+
+ # then check for a celib library
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ for i in \
+ ../celib-palm-3.0 \
+ ../celib \
+ ../../celib-palm-3.0 \
+ ../../celib \
+ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
+ ${srcdir}/../celib-palm-3.0 \
+ ${srcdir}/../celib \
+ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
+ ; do
+ if test -d "$i/inc" ; then
+ ac_cv_c_celibconfig=`(cd $i; pwd)`
+ break
+ fi
+ done
+ fi
+ ])
+ if test x"${ac_cv_c_celibconfig}" = x ; then
+ AC_MSG_ERROR([Cannot find celib support library directory])
+ else
+ no_celib=
+ CELIB_DIR=${ac_cv_c_celibconfig}
+ CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
+ AC_MSG_RESULT([found $CELIB_DIR])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
+# TEA_INSTALLER --
+#
+# Configure the installer.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# INSTALL
+# INSTALL_DATA_DIR
+# INSTALL_DATA
+# INSTALL_PROGRAM
+# INSTALL_SCRIPT
+# INSTALL_LIBRARY
+#------------------------------------------------------------------------
+
+AC_DEFUN([TEA_INSTALLER], [
+ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
+ INSTALL_DATA_DIR='${INSTALL} -d -m 755'
+ INSTALL_DATA='${INSTALL} -m 644'
+ INSTALL_PROGRAM='${INSTALL} -m 755'
+ INSTALL_SCRIPT='${INSTALL} -m 755'
+
+ TEA_CONFIG_SYSTEM
+ case $system in
+ HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
+ *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
+ esac
+
+ AC_SUBST(INSTALL)
+ AC_SUBST(INSTALL_DATA_DIR)
+ AC_SUBST(INSTALL_DATA)
+ AC_SUBST(INSTALL_PROGRAM)
+ AC_SUBST(INSTALL_SCRIPT)
+ AC_SUBST(INSTALL_LIBRARY)
+])
+
+###
+# Tip 430 - ZipFS Modifications
+###
+#------------------------------------------------------------------------
+# SC_ZIPFS_SUPPORT
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# TCL_ZIP_FILE
+# TCL_ZIPFS_SUPPORT
+# TCL_ZIPFS_FLAG
+# ZIP_PROG
+#------------------------------------------------------------------------
+
+#------------------------------------------------------------------------
+# SC_PROG_ZIP
+# Locate a zip encoder installed on the system path, or none.
+#
+# Arguments:
+# none
+#
+# Results:
+# Substitutes the following vars:
+# ZIP_PROG
+# ZIP_PROG_OPTIONS
+# ZIP_PROG_VFSSEARCH
+# ZIP_INSTALL_OBJS
+#------------------------------------------------------------------------
+AC_DEFUN([TEA_ZIPFS_SUPPORT], [
+ AC_MSG_CHECKING([for zipfs support])
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ INSTALL_MSGS=""
+ # If our native tclsh processes the "install" command line option
+ # we can use it to mint zip files
+ AS_IF([$TCLSH_PROG install],[
+ ZIP_PROG=${TCLSH_PROG}
+ ZIP_PROG_OPTIONS="install mkzip"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
+ ])
+ if test "x$ZIP_PROG" = "x" ; then
+ AC_CACHE_VAL(ac_cv_path_zip, [
+ search_path=`echo ${PATH} | sed -e 's/:/ /g'`
+ for dir in $search_path ; do
+ for j in `ls -r $dir/zip 2> /dev/null` \
+ `ls -r $dir/zip 2> /dev/null` ; do
+ if test x"$ac_cv_path_zip" = x ; then
+ if test -f "$j" ; then
+ ac_cv_path_zip=$j
+ break
+ fi
+ fi
+ done
+ done
+ ])
+ if test -f "$ac_cv_path_zip" ; then
+ ZIP_PROG="$ac_cv_path_zip "
+ AC_MSG_RESULT([$ZIP_PROG])
+ ZIP_PROG_OPTIONS="-rq"
+ ZIP_PROG_VFSSEARCH="."
+ AC_MSG_RESULT([Found INFO Zip in environment])
+ # Use standard arguments for zip
+ fi
+ fi
+ if test "x$ZIP_PROG" = "x" ; then
+ # It is not an error if an installed version of Zip can't be located.
+ ZIP_PROG=""
+ ZIP_PROG_OPTIONS=""
+ ZIP_PROG_VFSSEARCH=""
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ else
+ # ZIPFS Support
+ eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
+ if test ${TCL_ZIP_FILE} = "" ; then
+ TCL_ZIPFS_SUPPORT=0
+ TCL_ZIPFS_FLAG=
+ INSTALL_LIBRARIES=install-libraries
+ INSTALL_MSGS=install-msgs
+ else
+ if test ${SHARED_BUILD} = 1 ; then
+ TCL_ZIPFS_SUPPORT=1
+ INSTALL_LIBRARIES=install-libraries-zipfs-shared
+ else
+ TCL_ZIPFS_SUPPORT=2
+ INSTALL_LIBRARIES=install-libraries-zipfs-static
+ fi
+ TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
+ fi
+ fi
+
+ AC_SUBST(TCL_ZIP_FILE)
+ AC_SUBST(TCL_ZIPFS_SUPPORT)
+ AC_SUBST(TCL_ZIPFS_FLAG)
+ AC_SUBST(ZIP_PROG)
+ AC_SUBST(ZIP_PROG_OPTIONS)
+ AC_SUBST(ZIP_PROG_VFSSEARCH)
+ AC_SUBST(INSTALL_LIBRARIES)
+ AC_SUBST(INSTALL_MSGS)
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/French.txt b/tcl8.6/pkgs/thread2.8.4/tests/French.txt
index ccbbab7..ccbbab7 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/French.txt
+++ b/tcl8.6/pkgs/thread2.8.4/tests/French.txt
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/all.tcl b/tcl8.6/pkgs/thread2.8.4/tests/all.tcl
index 74aca97..74aca97 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/all.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tests/all.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/store-load.tcl b/tcl8.6/pkgs/thread2.8.4/tests/store-load.tcl
index 4907349..4907349 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/store-load.tcl
+++ b/tcl8.6/pkgs/thread2.8.4/tests/store-load.tcl
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/thread.test b/tcl8.6/pkgs/thread2.8.4/tests/thread.test
index a710d30..9e7d227 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/thread.test
+++ b/tcl8.6/pkgs/thread2.8.4/tests/thread.test
@@ -253,12 +253,29 @@ test thread-11.6 {thread::send - asynchronous send} {
test thread-11.7 {thread::send - async send with event-loop wait} {
ThreadReap
+ set res {}
set tid [thread::create]
thread::send -async $tid {set x 5} five
vwait five
+ lappend res $five; set five {}
+ thread::send -async $tid {set x 5} [binary format cccc 0x66 0x69 0x76 0x65]; # five as byte array without str-rep.
+ vwait five
+ lappend res $five; set five {}
ThreadReap
- set five
-} {5}
+ set res
+} {5 5}
+
+test thread-11.7.1 {thread::send - sync send with var} {
+ ThreadReap
+ set res {}
+ set tid [thread::create]
+ thread::send $tid {set x 5} five
+ lappend res $five; set five {}
+ thread::send $tid {set x 5} [binary format cccc 0x66 0x69 0x76 0x65]; # five as byte array without str-rep.
+ lappend res $five; set five {}
+ ThreadReap
+ set res
+} {5 5}
test thread-11.8 {thread::send - send to self directly} {
thread::send [thread::id] {set x 5} five
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/tkt-84be1b5a73.test b/tcl8.6/pkgs/thread2.8.4/tests/tkt-84be1b5a73.test
index 946c6db..946c6db 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/tkt-84be1b5a73.test
+++ b/tcl8.6/pkgs/thread2.8.4/tests/tkt-84be1b5a73.test
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/tpool.test b/tcl8.6/pkgs/thread2.8.4/tests/tpool.test
index a09c863..a09c863 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/tpool.test
+++ b/tcl8.6/pkgs/thread2.8.4/tests/tpool.test
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/tsv.test b/tcl8.6/pkgs/thread2.8.4/tests/tsv.test
index d25b052..d25b052 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/tsv.test
+++ b/tcl8.6/pkgs/thread2.8.4/tests/tsv.test
diff --git a/tcl8.6/pkgs/thread2.8.2/tests/ttrace.test b/tcl8.6/pkgs/thread2.8.4/tests/ttrace.test
index a09c863..a09c863 100644
--- a/tcl8.6/pkgs/thread2.8.2/tests/ttrace.test
+++ b/tcl8.6/pkgs/thread2.8.4/tests/ttrace.test
diff --git a/tcl8.6/pkgs/thread2.8.2/unix/CONFIG b/tcl8.6/pkgs/thread2.8.4/unix/CONFIG
index cd3f23f..cd3f23f 100644
--- a/tcl8.6/pkgs/thread2.8.2/unix/CONFIG
+++ b/tcl8.6/pkgs/thread2.8.4/unix/CONFIG
diff --git a/tcl8.6/pkgs/thread2.8.2/unix/README b/tcl8.6/pkgs/thread2.8.4/unix/README
index 3b5e1db..3b5e1db 100644
--- a/tcl8.6/pkgs/thread2.8.2/unix/README
+++ b/tcl8.6/pkgs/thread2.8.4/unix/README
diff --git a/tcl8.6/pkgs/thread2.8.2/unix/threadUnix.c b/tcl8.6/pkgs/thread2.8.4/unix/threadUnix.c
index 52d1530..52d1530 100644
--- a/tcl8.6/pkgs/thread2.8.2/unix/threadUnix.c
+++ b/tcl8.6/pkgs/thread2.8.4/unix/threadUnix.c
diff --git a/tcl8.6/pkgs/thread2.8.2/win/CONFIG b/tcl8.6/pkgs/thread2.8.4/win/CONFIG
index 471d89e..471d89e 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/CONFIG
+++ b/tcl8.6/pkgs/thread2.8.4/win/CONFIG
diff --git a/tcl8.6/pkgs/thread2.8.2/win/README.txt b/tcl8.6/pkgs/thread2.8.4/win/README.txt
index 91cce56..91cce56 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/README.txt
+++ b/tcl8.6/pkgs/thread2.8.4/win/README.txt
diff --git a/tcl8.6/pkgs/thread2.8.2/win/makefile.vc b/tcl8.6/pkgs/thread2.8.4/win/makefile.vc
index a2c8615..4c1c051 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/makefile.vc
+++ b/tcl8.6/pkgs/thread2.8.4/win/makefile.vc
@@ -28,7 +28,7 @@ RCFILE = thread.rc
DOCDIR = $(ROOT)\doc\html
PRJ_DEFINES = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
-PRJ_DEFINES = $(PRJ_DEFINES) -DTCL_TIP143 -DTCL_TIP285 $(ADDOPTDEFINES)
+PRJ_DEFINES = $(PRJ_DEFINES) -DTCL_TIP143 -DTCL_TIP285 -DTCL_NO_DEPRECATED=1 $(ADDOPTDEFINES)
PRJ_LIBS = $(ADDLINKOPTS)
!include "rules-ext.vc"
diff --git a/tcl8.6/pkgs/itcl4.1.1/win/nmakehlp.c b/tcl8.6/pkgs/thread2.8.4/win/nmakehlp.c
index 025bb99..b759020 100644
--- a/tcl8.6/pkgs/itcl4.1.1/win/nmakehlp.c
+++ b/tcl8.6/pkgs/thread2.8.4/win/nmakehlp.c
@@ -14,13 +14,8 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
-#define NO_SHLWAPI_GDI
-#define NO_SHLWAPI_STREAM
-#define NO_SHLWAPI_REG
-#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
-#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>
@@ -74,7 +69,7 @@ main(
char msg[300];
DWORD dwWritten;
int chars;
- char *s;
+ const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
@@ -688,6 +683,17 @@ SubstituteFile(
return 0;
}
+BOOL FileExists(LPCTSTR szPath)
+{
+#ifndef INVALID_FILE_ATTRIBUTES
+ #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+#endif
+ DWORD pathAttr = GetFileAttributes(szPath);
+ return (pathAttr != INVALID_FILE_ATTRIBUTES &&
+ !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+
/*
* QualifyPath --
*
@@ -701,13 +707,8 @@ QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
- char szTmp[MAX_PATH + 1];
- char *p;
- GetCurrentDirectory(MAX_PATH, szCwd);
- while ((p = strchr(szPath, '/')) && *p)
- *p = '\\';
- PathCombine(szTmp, szCwd, szPath);
- PathCanonicalize(szCwd, szTmp);
+
+ GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
@@ -765,7 +766,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath)
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
- if (PathFileExists(path)) {
+ if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
diff --git a/tcl8.6/pkgs/thread2.8.2/win/pkg.vc b/tcl8.6/pkgs/thread2.8.4/win/pkg.vc
index ab44750..4a98337 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/pkg.vc
+++ b/tcl8.6/pkgs/thread2.8.4/win/pkg.vc
@@ -3,4 +3,4 @@
PACKAGE_MAJOR = 2
PACKAGE_MINOR = 8
-PACKAGE_VERSION = "2.8.2"
+PACKAGE_VERSION = "2.8.4"
diff --git a/tcl8.6/pkgs/thread2.8.4/win/rules-ext.vc b/tcl8.6/pkgs/thread2.8.4/win/rules-ext.vc
new file mode 100644
index 0000000..531e070
--- /dev/null
+++ b/tcl8.6/pkgs/thread2.8.4/win/rules-ext.vc
@@ -0,0 +1,118 @@
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
+# First locate the Tcl directory that we are working with.
+!if "$(TCLDIR)" != ""
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
+!endif # _RULES_EXT_VC \ No newline at end of file
diff --git a/tcl8.6/pkgs/thread2.8.4/win/rules.vc b/tcl8.6/pkgs/thread2.8.4/win/rules.vc
new file mode 100644
index 0000000..13b3fba
--- /dev/null
+++ b/tcl8.6/pkgs/thread2.8.4/win/rules.vc
@@ -0,0 +1,1740 @@
+#------------------------------------------------------------- -*- makefile -*-
+# rules.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Copyright (c) 2001-2003 David Gravereaux.
+# Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017 Ashok P. Nadkarni
+#------------------------------------------------------------------------------
+
+!ifndef _RULES_VC
+_RULES_VC = 1
+
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 2
+
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
+!else
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
+!endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+# any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+# as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+# we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Parse the OPTS macro value for user-specified build configuration
+# 7. Parse the STATS macro value for statistics instrumentation
+# 8. Parse the CHECKS macro for additional compilation checks
+# 9. Extract Tcl, and possibly Tk, version numbers from the headers
+# 10. Based on this selected configuration, construct the output
+# directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+# on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+# be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+# Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
+
+#----------------------------------------------------------
+# Set the proper copy method to avoid overwrite questions
+# to the user when copying files and selecting the right
+# "delete all" method.
+#----------------------------------------------------------
+
+RMDIR = rmdir /S /Q
+CPY = xcopy /i /y >NUL
+CPYDIR = xcopy /e /i /y >NUL
+COPY = copy /y >NUL
+MKDIR = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WINDIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+# when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+# this will be the root of the Tcl installation. For extensions
+# this will be the lib directory under the root.
+# TCLINSTALL - set to 1 if _TCLDIR refers to
+# headers and libraries from an installed Tcl, and 0 if built against
+# Tcl sources. Not set when building Tcl itself. Yes, not very well
+# named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+# Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR = $(ROOT)\library
+!else
+LIBDIR = $(ROOT)\lib
+!endif
+!endif
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR = $(LIBDIR)\demos
+!else
+DEMODIR = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT enclose WINDIR in a !ifndef because Windows always defines
+# WINDIR env var to point to c:\windows!
+# TBD - This is a potentially dangerous conflict, rename WINDIR to
+# something else
+WINDIR = $(ROOT)\win
+
+!ifndef RCDIR
+!if exist("$(WINDIR)\rc")
+RCDIR = $(WINDIR)\rc
+!else
+RCDIR = $(WINDIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR = $(TCLDIR:/=\)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL = 1
+_TCL_H = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL = 0
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL = 1
+TCLDIR = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR = $(_INSTALLDIR)\..
+_TCL_H = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL = 0
+TCLDIR = $(_TCLDIR)
+_TCL_H = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL = 1
+_TK_H = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL = 0
+_TK_H = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR = $(_INSTALLDIR)\..
+_TK_H = $(_TKDIR)\include\tk.h
+TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to Tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+# This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+# compiler version 1200. This is kept only for legacy reasons as it
+# does not make sense for recent Microsoft compilers. Only used for
+# output directory names.
+# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+# CFG_ENCODING - set to an character encoding.
+# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
+# see where it is used
+
+cc32 = $(CC) # built-in default.
+link32 = link
+lib32 = lib
+rc32 = $(RC) # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
+
+_HASH=^#
+_VC_MANIFEST_EMBED_EXE=
+_VC_MANIFEST_EMBED_DLL=
+VCVER=0
+!if ![echo VCVERSION=_MSC_VER > vercl.x] \
+ && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
+ && ![echo ARCH=IX86 >> vercl.x] \
+ && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
+ && ![echo ARCH=AMD64 >> vercl.x] \
+ && ![echo $(_HASH)endif >> vercl.x] \
+ && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
+!include vercl.i
+!if $(VCVERSION) < 1900
+!if ![echo VCVER= ^\> vercl.vc] \
+ && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
+!include vercl.vc
+!endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
+!endif
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
+!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
+NATIVE_ARCH=IX86
+!else
+NATIVE_ARCH=AMD64
+!endif
+
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
+!ifndef CFG_ENCODING
+CFG_ENCODING = \"cp1252\"
+!endif
+
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. This is the "master" copy and kept updated.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
+
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
+
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
+!endif
+!else # ! $(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
+!endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
+
+!endif # NMAKEHLPC
+
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
+
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
+
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
+!if [nmakehlp -c -Op]
+FPOPTS = -Op
+!endif
+
+# Strict floating point semantics - present in newer compilers in lieu of -Op
+!if [nmakehlp -c -fp:strict]
+FPOPTS = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
+!endif
+
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit. However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+OPTIMIZING = 1
+OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
+!endif
+
+# Checks for buffer overflows in local arrays
+!if [nmakehlp -c -GS]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
+!endif
+
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
+!if [nmakehlp -c -GL]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
+!endif
+!endif # [nmakehlp -c -GL]
+
+DEBUGFLAGS = $(FPOPTS)
+
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
+!if [nmakehlp -c -RTC1]
+DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
+!elseif [nmakehlp -c -GZ]
+DEBUGFLAGS = $(DEBUGFLAGS) -GZ
+!endif
+
+#----------------------------------------------------------------
+# Linker flags
+
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
+!endif
+
+LINKERFLAGS =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+########################################################################
+# 6. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO - 1 -> profile based optimization, 0 -> no
+# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
+# 0 -> link to static C runtime for static Tcl build.
+# Does not impact shared Tcl builds (STATIC_BUILD == 0)
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+# in the Tcl shell. 0 -> keep them as shared libraries
+# Does not impact shared Tcl builds.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+# 0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+# C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+# configuration (ignored for Tcl itself)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
+STATIC_BUILD = 0
+TCL_THREADS = 1
+DEBUG = 0
+SYMBOLS = 0
+PROFILE = 0
+PGO = 0
+MSVCRT = 1
+TCL_USE_STATIC_PACKAGES = 0
+USE_THREAD_ALLOC = 1
+UNCHECKED = 0
+CONFIG_CHECK = 1
+!if $(DOING_TCL)
+USE_STUBS = 0
+!else
+USE_STUBS = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
+!if [nmakehlp -f $(OPTS) "static"]
+!message *** Doing static
+STATIC_BUILD = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT = 0
+!else
+!if [nmakehlp -f $(OPTS) "msvcrt"]
+!message *** Doing msvcrt
+MSVCRT = 1
+!else
+!if !$(STATIC_BUILD)
+MSVCRT = 1
+!else
+MSVCRT = 0
+!endif
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
+!message *** Doing staticpkg
+TCL_USE_STATIC_PACKAGES = 1
+!else
+TCL_USE_STATIC_PACKAGES = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nothreads"]
+!message *** Compile explicitly for non-threaded tcl
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!else
+TCL_THREADS = 1
+USE_THREAD_ALLOC= 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "symbols"]
+!message *** Doing symbols
+DEBUG = 1
+!else
+DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pdbs"]
+!message *** Doing pdbs
+SYMBOLS = 1
+!else
+SYMBOLS = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "profile"]
+!message *** Doing profile
+PROFILE = 1
+!else
+PROFILE = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "pgi"]
+!message *** Doing profile guided optimization instrumentation
+PGO = 1
+!elseif [nmakehlp -f $(OPTS) "pgo"]
+!message *** Doing profile guided optimization
+PGO = 2
+!else
+PGO = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "loimpact"]
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
+!endif
+
+# TBD - should get rid of this option
+!if [nmakehlp -f $(OPTS) "thrdalloc"]
+!message *** Doing thrdalloc
+USE_THREAD_ALLOC = 1
+!endif
+
+!if [nmakehlp -f $(OPTS) "tclalloc"]
+USE_THREAD_ALLOC = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != "" && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 7. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+# 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+# 0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG = 0
+TCL_COMPILE_DEBUG = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG = 1
+!else
+TCL_MEM_DEBUG = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG = 1
+!else
+TCL_COMPILE_DEBUG = 0
+!endif
+
+!endif
+
+####################################################################
+# 8. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+# 0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED = 0
+WARNINGS = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS = $(LINKERFLAGS) -warn:3
+!endif
+!endif
+
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS = $(WARNINGS) -Wp64
+!endif
+
+!endif
+
+################################################################
+# 9. Extract various version numbers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_PATCH_LEVEL
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_PATCH_LEVEL
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
+!endif
+
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+ && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
+
+!include versions.vc
+
+TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if defined(_TK_H)
+TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
+
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+ || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+################################################################
+# 10. Construct output directory and file paths
+# Figure-out how to name our intermediate and output directories.
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+# t = full thread support.
+# s = static library (as opposed to an import library)
+# g = linked to the debug enabled C run-time.
+# x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
+
+SUFX = tsgx
+
+!if $(DEBUG)
+BUILDDIRTOP = Debug
+!else
+BUILDDIRTOP = Release
+!endif
+
+!if "$(MACHINE)" != "IX86"
+BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
+!endif
+!if $(VCVER) > 6
+BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
+!endif
+
+!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+SUFX = $(SUFX:g=)
+!endif
+
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
+
+!if !$(STATIC_BUILD)
+TMP_DIRFULL = $(TMP_DIRFULL:Static=)
+SUFX = $(SUFX:s=)
+EXT = dll
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!else
+TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
+EXT = lib
+!if !$(MSVCRT)
+TMP_DIRFULL = $(TMP_DIRFULL:X=)
+SUFX = $(SUFX:x=)
+!endif
+!endif
+
+!if !$(TCL_THREADS)
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
+!ifndef TMP_DIR
+TMP_DIR = $(TMP_DIRFULL)
+!ifndef OUT_DIR
+OUT_DIR = .\$(BUILDDIRTOP)
+!endif
+!else
+!ifndef OUT_DIR
+OUT_DIR = $(TMP_DIR)
+!endif
+!endif
+
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+ || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+ || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
+
+# The name of the stubs library for the project being built
+STUBPREFIX = $(PROJECT)stub
+
+# Set up paths to various Tcl executables and libraries needed by extensions
+!if $(DOING_TCL)
+
+TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe
+TCLSH = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
+
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+# When building extensions, we need to locate tclsh. Depending on version
+# of Tcl we are building against, this may or may not have a "t" suffix.
+# Try various possibilities in turn.
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist("$(TCLSH)") && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+!if !exist("$(TCLSH)")
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+
+TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
+TCL_LIBRARY = $(_TCLDIR)\lib
+TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES = -I"$(_TCLDIR)\include"
+
+!else # Building against Tcl sources
+
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
+!endif
+!if !exist($(TCLSH))
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
+TCL_LIBRARY = $(_TCLDIR)\library
+TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLTOOLSDIR = $(_TCLDIR)\tools
+TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
+!endif
+!endif
+
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
+TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
+
+!if $(DOING_TK)
+WISH = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\include"
+!else # Building against Tk sources
+WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+!endif
+TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!endif # TKINSTALL
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
+
+# Various output paths
+PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX:t=).lib
+PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX:t=).$(EXT)
+PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
+
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+# define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+
+!if $(TCL_MEM_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
+!endif
+!if $(TCL_COMPILE_DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+!endif
+!if $(TCL_THREADS)
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
+!endif
+!if $(STATIC_BUILD)
+OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
+!endif
+!if $(TCL_NO_DEPRECATED)
+OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+!endif
+
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if ! $(DOING_TCL)
+USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
+!if !$(DEBUG)
+OPTDEFINES = $(OPTDEFINES) -DNDEBUG
+!if $(OPTIMIZING)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+!endif
+!endif
+!if $(PROFILE)
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
+!endif
+!if "$(MACHINE)" == "AMD64"
+OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!endif
+!if $(VCVERSION) < 1300
+OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
+!endif
+
+# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
+COMPILERFLAGS = /D_ATL_XP_TARGETING
+
+# Following is primarily for the benefit of extensions. Tcl 8.5 builds
+# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
+# an extension, it is advisable (but not mandated) to use the same Windows
+# API as the Tcl build. This is accordingly defaulted below. A particular
+# extension can override this by pre-definining USE_WIDECHAR_API.
+!ifndef USE_WIDECHAR_API
+!if $(TCL_VERSION) > 85
+USE_WIDECHAR_API = 1
+!else
+USE_WIDECHAR_API = 0
+!endif
+!endif
+
+!if $(USE_WIDECHAR_API)
+COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
+!endif
+
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+ -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+ -DMODULE_SCOPE=extern
+!endif
+
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
+!else
+crt = -MD
+!endif
+!else
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
+!else
+crt = -MT
+!endif
+!endif
+
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
+
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
+
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
+!endif
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels.
+cwarn = $(WARNINGS)
+
+!if "$(MACHINE)" == "AMD64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
+!endif
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
+!endif
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
+!endif
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
+!endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
+
+appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
+
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package. Note: -DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
+
+# Link flags
+
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
+!else
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
+!endif
+
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
+!endif
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
+!endif
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
+!endif
+
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs = $(winlibs) bufferoverflowU.lib
+!endif
+!endif
+
+baselibs = $(winlibs) $(PRJ_LIBS)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs = $(baselibs) ucrt.lib
+!endif
+
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+ $(TCL_INCLUDES) \
+ -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+ -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
+ -DDOTVERSION=\"$(DOTVERSION)\" \
+ -DVERSION=\"$(VERSION)\" \
+ -DSUFX=\"$(SUFX:t=)\" \
+ -DPROJECT=\"$(PROJECT)\" \
+ -DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
+!endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+default-pkgindex:
+ @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+ [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
+
+default-pkgindex-tea:
+ @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@ $(DOTVERSION)
+@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@ $(PRJLIBNAME)
+<<
+
+
+default-install: default-install-binaries default-install-libraries
+
+default-install-binaries: $(PRJLIB)
+ @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
+ @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+ @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+ @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+ @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+ @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+ @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+ @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-docs-html:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+ @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+ @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+ @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+ @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+ @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+ @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+ @echo Cleaning $(TMP_DIR)\* ...
+ @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+ @echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
+ @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+ @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
+ @if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
+ @echo Cleaning $(WINDIR)\nmhlp-out.txt ...
+ @if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
+ @echo Cleaning $(WINDIR)\_junk.pch ...
+ @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
+ @echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
+ @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+ @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+ @echo Cleaning $(WINDIR)\versions.vc, version.vc ...
+ @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+ @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+
+default-hose: default-clean
+ @echo Hosing $(OUT_DIR)\* ...
+ @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+ @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+ @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+ @set TCLLIBPATH=$(OUT_DIR:\=/)
+ @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+ $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "master" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+ $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
+!else
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+ @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION COMMAVERSION
+ PRODUCTVERSION COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "Tcl extension " PROJECT
+ VALUE "OriginalFilename", PRJLIBNAME
+ VALUE "FileVersion", DOTVERSION
+ VALUE "ProductName", "Package " PROJECT " for Tcl"
+ VALUE "ProductVersion", DOTVERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
+!endif
+
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the master makefile should define explicit rules.
+
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WINDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+ $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(WINDIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+ $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
+
+!endif
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if ! $(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
+!endif
+!else # ! $(TCLINSTALL) - building against Tcl source
+!if exist("$(OUT_DIR)\tcl.nmake")
+TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
+!endif
+!endif # TCLINSTALL
+
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
+
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
+!endif
+!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
+!endif
+!endif
+
+!endif # TCLNMAKECONFIG
+
+!endif # ! $(DOING_TCL)
+
+
+#----------------------------------------------------------
+# Display stats being used.
+#----------------------------------------------------------
+
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
+!message *** Intermediate directory will be '$(TMP_DIR)'
+!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
+!message *** Suffix for binaries will be '$(SUFX)'
+!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
+
+!endif # ifdef _RULES_VC
diff --git a/tcl8.6/pkgs/thread2.8.4/win/targets.vc b/tcl8.6/pkgs/thread2.8.4/win/targets.vc
new file mode 100644
index 0000000..7f1d388
--- /dev/null
+++ b/tcl8.6/pkgs/thread2.8.4/win/targets.vc
@@ -0,0 +1,98 @@
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+ $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+ $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+ @nmakehlp -s << $** >$@
+@MACHINE@ $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+ $(LIBCMD) $**
+!else
+ $(DLLCMD) $**
+ $(_VC_MANIFEST_EMBED_DLL)
+!endif
+ -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
diff --git a/tcl8.6/pkgs/thread2.8.2/win/thread.rc b/tcl8.6/pkgs/thread2.8.4/win/thread.rc
index d59d065..d59d065 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/thread.rc
+++ b/tcl8.6/pkgs/thread2.8.4/win/thread.rc
diff --git a/tcl8.6/pkgs/thread2.8.2/win/threadWin.c b/tcl8.6/pkgs/thread2.8.4/win/threadWin.c
index c77ff9c..9730ae4 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/threadWin.c
+++ b/tcl8.6/pkgs/thread2.8.4/win/threadWin.c
@@ -15,9 +15,9 @@
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "../generic/tclThread.h"
#include <windows.h>
#include <process.h>
+#include "../generic/tclThread.h"
#if 0
/* only Windows 2000 (XP, too??) has this function */
diff --git a/tcl8.6/pkgs/thread2.8.2/win/thread_win.dsp b/tcl8.6/pkgs/thread2.8.4/win/thread_win.dsp
index 0c1e0bc..0c1e0bc 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/thread_win.dsp
+++ b/tcl8.6/pkgs/thread2.8.4/win/thread_win.dsp
diff --git a/tcl8.6/pkgs/thread2.8.2/win/thread_win.dsw b/tcl8.6/pkgs/thread2.8.4/win/thread_win.dsw
index 5599cd6..5599cd6 100644
--- a/tcl8.6/pkgs/thread2.8.2/win/thread_win.dsw
+++ b/tcl8.6/pkgs/thread2.8.4/win/thread_win.dsw
diff --git a/tcl8.6/tests/all.tcl b/tcl8.6/tests/all.tcl
index 69a16ba..e14bd9c 100644
--- a/tcl8.6/tests/all.tcl
+++ b/tcl8.6/tests/all.tcl
@@ -13,10 +13,14 @@
package prefer latest
package require Tcl 8.5-
package require tcltest 2.2
-namespace import tcltest::*
-configure {*}$argv -testdir [file dir [info script]]
+namespace import ::tcltest::*
+
+configure {*}$argv -testdir [file dirname [file dirname [file normalize [
+ info script]/...]]]
+
if {[singleProcess]} {
interp debug {} -frame 1
}
+
runAllTests
proc exit args {}
diff --git a/tcl8.6/tests/assemble.test b/tcl8.6/tests/assemble.test
index 5231048..40c132d 100644
--- a/tcl8.6/tests/assemble.test
+++ b/tcl8.6/tests/assemble.test
@@ -1584,6 +1584,12 @@ test assemble-15.7 {listIndexImm} {
}
-result c
}
+test assemble-15.8 {listIndexImm} {
+ assemble {push {a b c}; listIndexImm end+2}
+} {}
+test assemble-15.9 {listIndexImm} {
+ assemble {push {a b c}; listIndexImm -1-1}
+} {}
# assemble-16 - invokeStk
diff --git a/tcl8.6/tests/async.test b/tcl8.6/tests/async.test
index cb67cc2..e7fc45a 100644
--- a/tcl8.6/tests/async.test
+++ b/tcl8.6/tests/async.test
@@ -157,17 +157,24 @@ test async-4.1 {async interrupting bytecode sequence} -constraints {
}
} -body {
apply {{handle} {
- global aresult
- set aresult {Async event not delivered}
- testasync marklater $handle
- for {set i 0} {
- $i < 2500000 && $aresult eq "Async event not delivered"
- } {incr i} {
- nothing
- }
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ # allow plenty of time to pass in case valgrind is running
+ set start [clock seconds]
+ while {
+ [clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
+ } {
+ # be less busy
+ after 100
+ nothing
+ }
return $aresult
}} $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
test async-4.2 {async interrupting straight bytecode sequence} -constraints {
@@ -179,12 +186,20 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints {
global aresult
set aresult {Async event not delivered}
testasync marklater $handle
- for {set i 0} {
- $i < 2500000 && $aresult eq "Async event not delivered"
- } {incr i} {}
+ # allow plenty of time to pass in case valgrind is running
+ set start [clock seconds]
+ while {
+ [clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
+ } {
+ # be less busy
+ after 100
+ }
return $aresult
}} $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
@@ -201,6 +216,9 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
return $aresult
}]] $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
diff --git a/tcl8.6/tests/binary.test b/tcl8.6/tests/binary.test
index 2a306a3..8c1dedb 100644
--- a/tcl8.6/tests/binary.test
+++ b/tcl8.6/tests/binary.test
@@ -2711,6 +2711,46 @@ test binary-73.30 {binary decode base64} -body {
test binary-73.31 {binary decode base64} -body {
list [string length [set r [binary decode base64 WA==WFla]]] $r
} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.32 {binary decode base64, bug [00d04c4f12]} -body {
+ list \
+ [string length [binary decode base64 =]] \
+ [string length [binary decode base64 " ="]] \
+ [string length [binary decode base64 " ="]] \
+ [string length [binary decode base64 "\r\n\t="]] \
+} -result [lrepeat 4 0]
+test binary-73.33 {binary decode base64, bug [00d04c4f12]} -body {
+ list \
+ [string length [binary decode base64 ==]] \
+ [string length [binary decode base64 " =="]] \
+ [string length [binary decode base64 " =="]] \
+ [string length [binary decode base64 " =="]] \
+} -result [lrepeat 4 0]
+test binary-73.34 {binary decode base64, (compatibility) unfulfilled base64 (single char) in non-strict mode} -body {
+ list \
+ [expr {[binary decode base64 a] eq [binary decode base64 ""]}] \
+ [expr {[binary decode base64 abcda] eq [binary decode base64 "abcd"]}]
+} -result [lrepeat 2 1]
+test binary-73.35 {binary decode base64, bad base64 in strict mode} -body {
+ set r {}
+ foreach c {a " a" " a" " a" " a" abcda abcdabcda a= a== abcda= abcda==} {
+ lappend r \
+ [catch {binary decode base64 $c}] \
+ [catch {binary decode base64 -strict $c}]
+ }
+ set r
+} -result [lrepeat 11 0 1]
+test binary-73.36 {binary decode base64: check encoded & decoded equals original} -body {
+ set r {}
+ for {set i 0} {$i < 255 && [llength $r] < 20} {incr i} {
+ foreach c {1 2 3 4 5 6 7 8} {
+ set c [string repeat [format %c $i] $c]
+ if {[set a [binary decode base64 [set x [binary encode base64 $c]]]] ne $c} {
+ lappend r "encode & decode is wrong on string `$c` (encoded: $x): `$a` != `$c`"
+ }
+ }
+ }
+ join $r \n
+} -result {}
test binary-74.1 {binary encode uuencode} -body {
binary encode uuencode
diff --git a/tcl8.6/tests/chanio.test b/tcl8.6/tests/chanio.test
index db2475c..6408f50 100644
--- a/tcl8.6/tests/chanio.test
+++ b/tcl8.6/tests/chanio.test
@@ -13,16 +13,11 @@
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# TODO: This test is likely worthless. Confirm and remove
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
- namespace import -force ::tcltest::*
}
-::tcltest::loadTestedCommands
-catch [list package require -exact Tcltest [info patchlevel]]
-
-testConstraint testbytestring [llength [info commands testbytestring]]
-
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
@@ -35,18 +30,16 @@ namespace eval ::tcl::test::io {
variable msg
variable expected
- ::tcltest::loadTestedCommands
+ loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
+ package require tcltests
+ testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testchannel [llength [info commands testchannel]]
- testConstraint exec [llength [info commands exec]]
testConstraint openpipe 1
- testConstraint fileevent [llength [info commands fileevent]]
- testConstraint fcopy [llength [info commands fcopy]]
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-}]}]
# You need a *very* special environment to do some tests. In particular,
# many file systems do not support large-files...
@@ -5866,6 +5859,8 @@ test chan-io-47.6 {file events on shared files, deleting file events} -setup {
testfevent delete
chan close $f
} -result {{script 1} {}}
+unset path(foo)
+removeFile foo
set path(bar) [makeFile {} bar]
@@ -5961,6 +5956,9 @@ test chan-io-48.3 {testing readability conditions} -setup {
} -cleanup {
chan close $f
} -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+unset path(bar)
+removeFile bar
+
test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup {
file delete $path(test1)
set c 0
diff --git a/tcl8.6/tests/cmdAH.test b/tcl8.6/tests/cmdAH.test
index e334dff..e8933d6 100644
--- a/tcl8.6/tests/cmdAH.test
+++ b/tcl8.6/tests/cmdAH.test
@@ -23,7 +23,7 @@ testConstraint testsetplatform [llength [info commands testsetplatform]]
testConstraint testvolumetype [llength [info commands testvolumetype]]
testConstraint linkDirectory [expr {
![testConstraint win] ||
- ([string index $tcl_platform(osVersion) 0] >= 5
+ ($::tcl_platform(osVersion) >= 5.0
&& [lindex [file system [temporaryDirectory]] 1] eq "NTFS")
}]
@@ -1040,7 +1040,7 @@ 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
+} -match regexp -result {could not (?:get access time|read)} -returnCodes error
if {[testConstraint unix] && [file exists /tmp]} {
removeFile touch.me /tmp
@@ -1281,7 +1281,7 @@ 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
+} -match regexp -result {could not (?:get modification time|read)} -returnCodes error
# owned
test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
@@ -1345,7 +1345,12 @@ test cmdAH-27.4 {
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]
+ try {
+ set res [file size [file join [temporaryDirectory] con.txt]]
+ } trap {POSIX ENOENT} {} {
+ set res 0
+ }
+ set res
} -result 0
catch {testsetplatform $platform}
@@ -1447,8 +1452,13 @@ test cmdAH-28.13 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {w
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)}
+ try {
+ file stat [file join [temporaryDirectory] CON.txt] stat
+ set res [lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}]
+ } trap {POSIX ENOENT} {} {
+ set res {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
+ }
+ set res
} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
unset -nocomplain stat
@@ -1498,7 +1508,12 @@ test cmdAH-29.6 {
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]
+ try {
+ set res [file type [file join [temporaryDirectory] CON.txt]]
+ } trap {POSIX ENOENT} {} {
+ set res {characterSpecial}
+ }
+ set res
} -result "characterSpecial"
# Error conditions
diff --git a/tcl8.6/tests/cmdIL.test b/tcl8.6/tests/cmdIL.test
index 23a5f96..68122dd 100644
--- a/tcl8.6/tests/cmdIL.test
+++ b/tcl8.6/tests/cmdIL.test
@@ -147,6 +147,12 @@ test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} {
{{b i g} 12345} {{d e m o} 34512}
}
} {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}}
+test cmdIL-1.41 {lsort -stride and -index} -body {
+ lsort -stride 2 -index -2 {a 2 b 1}
+} -returnCodes error -result {index "-2" cannot select an element from any list}
+test cmdIL-1.42 {lsort -stride and-index} -body {
+ lsort -stride 2 -index -1-1 {a 2 b 1}
+} -returnCodes error -result {index "-1-1" cannot select an element from any list}
# Can't think of any good tests for the MergeSort and MergeLists procedures,
# except a bunch of random lists to sort.
@@ -203,6 +209,33 @@ test cmdIL-3.4.1 {SortCompare procedure, -index option} -body {
test cmdIL-3.5 {SortCompare procedure, -index option} -body {
lsort -integer -index 2 {{20 10 13} {15}}
} -returnCodes error -result {element 2 missing from sublist "15"}
+test cmdIL-3.5.1 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index 1+3 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {element 4 missing from sublist "1 . c"}
+test cmdIL-3.5.2 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index -1-1 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {index "-1-1" cannot select an element from any list}
+test cmdIL-3.5.3 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index -2 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {index "-2" cannot select an element from any list}
+test cmdIL-3.5.4 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index end-4 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {element -2 missing from sublist "1 . c"}
+test cmdIL-3.5.5 {SortCompare procedure, -index option} {
+ lsort -index {} {a b}
+} {a b}
+test cmdIL-3.5.6 {SortCompare procedure, -index option} {
+ lsort -index {} [list a \{]
+} {a \{}
+test cmdIL-3.5.7 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index end--1 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {index "end--1" cannot select an element from any list}
+test cmdIL-3.5.8 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index end+1 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {index "end+1" cannot select an element from any list}
+test cmdIL-3.5.9 {SortCompare procedure, -index option (out of range, calculated index)} -body {
+ lsort -index end+2 {{1 . c} {2 . b} {3 . a}}
+} -returnCodes error -result {index "end+2" cannot select an element from any list}
test cmdIL-3.6 {SortCompare procedure, -index option} {
lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}}
} {{3 25 20} {2 5 25} {1 15 30}}
diff --git a/tcl8.6/tests/coroutine.test b/tcl8.6/tests/coroutine.test
index fd68567..8a5494d 100644
--- a/tcl8.6/tests/coroutine.test
+++ b/tcl8.6/tests/coroutine.test
@@ -739,6 +739,8 @@ test coroutine-7.12 {coro floor above street level #3008307} -body {
}
boom ; # does not crash: the coro floor is a good insulator
list
+} -cleanup {
+ rename boom {}; rename cc {}; rename c {}
} -result {}
test coroutine-8.0.0 {coro inject executed} -body {
diff --git a/tcl8.6/tests/env.test b/tcl8.6/tests/env.test
index 0dd4f98..e6ce44d 100644
--- a/tcl8.6/tests/env.test
+++ b/tcl8.6/tests/env.test
@@ -16,49 +16,96 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
-# Some tests require the "exec" command.
-# Skip them if exec is not defined.
-testConstraint exec [llength [info commands exec]]
+package require tcltests
+
+# [exec] is required here to see the actual environment received by child
+# processes.
+proc getenv {} {
+ global printenvScript
+ catch {exec [interpreter] $printenvScript} out
+ if {$out eq "child process exited abnormally"} {
+ set out {}
+ }
+ return $out
+}
+
+
+proc envrestore {} {
+ # Restore the environment variables at the end of the test.
+ global env
+ variable env2
+
+ foreach name [array names env] {
+ unset env($name)
+ }
+ array set env $env2
+ return
+}
+
+
+proc envprep {} {
+ # Save the current environment variables at the start of the test.
+ global env
+ variable keep
+ variable env2
+
+ set env2 [array get env]
+ foreach name [array names env] {
+ # Keep some environment variables that support operation of the tcltest
+ # package.
+ if {[string toupper $name] ni [string toupper $keep]} {
+ unset env($name)
+ }
+ }
+ return
+}
+
+
+proc encodingrestore {} {
+ variable sysenc
+ encoding system $sysenc
+ return
+}
+
+
+proc encodingswitch encoding {
+ variable sysenc
+ # Need to run [getenv] in known encoding, so save the current one here...
+ set sysenc [encoding system]
+ encoding system $encoding
+ return
+}
+
+
+proc setup1 {} {
+ global env
+ envprep
+ encodingswitch iso8859-1
+}
+
+proc setup2 {} {
+ global env
+ setup1
+ set env(NAME1) {test string}
+ set env(NAME2) {new value}
+ set env(XYZZY) {garbage}
+}
+
+
+proc cleanup1 {} {
+ encodingrestore
+ envrestore
+}
-#
-# These tests will run on any platform (and indeed crashed on the Mac). So put
-# them before you test for the existance of exec.
-#
-test env-1.1 {propagation of env values to child interpreters} -setup {
- catch {interp delete child}
- catch {unset env(test)}
-} -body {
- interp create child
- set env(test) garbage
- child eval {set env(test)}
-} -cleanup {
- interp delete child
- unset env(test)
-} -result {garbage}
-#
-# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
-# runs.
-#
-test env-1.2 {lappend to env value} -setup {
- catch {unset env(test)}
-} -body {
- set env(test) aaaaaaaaaaaaaaaa
- append env(test) bbbbbbbbbbbbbb
- unset env(test)
+variable keep {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
+ SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
+ CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
}
-test env-1.3 {reflection of env by "array names"} -setup {
- catch {interp delete child}
- catch {unset env(test)}
-} -body {
- interp create child
- child eval {set env(test) garbage}
- expr {"test" in [array names env]}
-} -cleanup {
- interp delete child
- catch {unset env(test)}
-} -result {1}
-set printenvScript [makeFile {
+variable printenvScript [makeFile [string map [list @keep@ [list $keep]] {
encoding system iso8859-1
proc lrem {listname name} {
upvar $listname list
@@ -70,7 +117,7 @@ set printenvScript [makeFile {
}
proc mangle s {
regsub -all {\[|\\|\]} $s {\\&} s
- regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar &]} s
+ regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar {&}]} s
return [subst -novariables $s]
}
proc manglechar c {
@@ -84,161 +131,154 @@ set printenvScript [makeFile {
lrem names ComSpec
lrem names ""
}
- foreach name {
- TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
- SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
- DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
- __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
- CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
- } {
+ foreach name @keep@ {
lrem names $name
}
foreach p $names {
- puts "[mangle $p]=[mangle $env($p)]"
+ puts [mangle $p]=[mangle $env($p)]
}
exit
-} printenv]
+}] printenv]
-# [exec] is required here to see the actual environment received by child
-# processes.
-proc getenv {} {
- global printenvScript tcltest
- catch {exec [interpreter] $printenvScript} out
- if {$out eq "child process exited abnormally"} {
- set out {}
- }
- return $out
-}
-# Save the current environment variables at the start of the test.
-
-set env2 [array get env]
-foreach name [array names env] {
- # Keep some environment variables that support operation of the tcltest
- # package.
- if {[string toupper $name] ni {
- TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
- SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
- DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
- SECURITYSESSIONID LANG WINDIR TERM
- CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432
- }} {
- unset env($name)
- }
+test env-1.1 {propagation of env values to child interpreters} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ set env(test) garbage
+ child eval {set env(test)}
+} -cleanup {
+ interp delete child
+ unset env(test)
+} -result {garbage}
+
+
+# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
+# runs.
+test env-1.2 {lappend to env value} -setup {
+ catch {unset env(test)}
+} -body {
+ set env(test) aaaaaaaaaaaaaaaa
+ append env(test) bbbbbbbbbbbbbb
+ unset env(test)
}
-# Need to run 'getenv' in known encoding, so save the current one here...
-set sysenc [encoding system]
-test env-2.1 {adding environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
- getenv
+test env-1.3 {reflection of env by "array names"} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ child eval {set env(test) garbage}
+ expr {"test" in [array names env]}
} -cleanup {
- encoding system $sysenc
-} -result {}
-test env-2.2 {adding environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+ interp delete child
+ catch {unset env(test)}
+} -result 1
+
+
+test env-2.1 {
+ adding environment variables
+} -constraints exec -setup setup1 -body {
+ getenv
+} -cleanup cleanup1 -result {}
+
+
+test env-2.2 {
+ adding environment variables
+} -constraints exec -setup setup1 -body {
set env(NAME1) "test string"
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string}
-test env-2.3 {adding environment variables} -setup {
- encoding system iso8859-1
+} -cleanup cleanup1 -result {NAME1=test string}
+
+
+test env-2.3 {adding environment variables} -constraints exec -setup {
+ setup1
set env(NAME1) "test string"
-} -constraints {exec} -body {
+} -body {
set env(NAME2) "more"
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string
+} -cleanup cleanup1 -result {NAME1=test string
NAME2=more}
-test env-2.4 {adding environment variables} -setup {
- encoding system iso8859-1
+
+
+test env-2.4 {
+ adding environment variables
+} -constraints exec -setup {
+ setup1
set env(NAME1) "test string"
set env(NAME2) "more"
-} -constraints {exec} -body {
+} -body {
set env(XYZZY) "garbage"
getenv
-} -cleanup {
- encoding system $sysenc
+} -cleanup { cleanup1
} -result {NAME1=test string
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 {
+
+test env-3.1 {
+ changing environment variables
+} -constraints exec -setup setup2 -body {
set result [getenv]
unset env(NAME2)
set result
} -cleanup {
- encoding system $sysenc
+ cleanup1
} -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
-} -constraints {exec} -body {
+
+test env-4.1 {
+ unsetting environment variables
+} -constraints exec -setup setup2 -body {
+ unset -nocomplain env(NAME2)
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string
+} -cleanup cleanup1 -result {NAME1=test string
XYZZY=garbage}
-test env-4.2 {unsetting environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
- unset env(NAME1)
- getenv
-} -cleanup {
- 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 {
+
+# env-4.2 is deleted
+
+test env-4.3 {
+ setting international environment variables
+} -constraints exec -setup setup1 -body {
set env(\ua7) \ub6
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {\u00a7=\u00b6}
-test env-4.4 {changing international environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+} -cleanup cleanup1 -result {\u00a7=\u00b6}
+
+
+test env-4.4 {
+ changing international environment variables
+} -constraints exec -setup setup1 -body {
set env(\ua7) \ua7
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {\u00a7=\u00a7}
-test env-4.5 {unsetting international environment variables} -setup {
- encoding system iso8859-1
+} -cleanup cleanup1 -result {\u00a7=\u00a7}
+
+
+test env-4.5 {
+ unsetting international environment variables
+} -constraints exec -setup {
+ setup1
set env(\ua7) \ua7
} -body {
set env(\ub6) \ua7
unset env(\ua7)
getenv
-} -constraints {exec} -cleanup {
- unset env(\ub6)
- encoding system $sysenc
-} -result {\u00b6=\u00a7}
+} -cleanup cleanup1 -result {\u00b6=\u00a7}
-test env-5.0 {corner cases - set a value, it should exist} -body {
+test env-5.0 {
+ corner cases - set a value, it should exist
+} -setup setup1 -body {
set env(temp) a
set env(temp)
-} -cleanup {
- unset env(temp)
-} -result {a}
-test env-5.1 {corner cases - remove one elem at a time} -setup {
- set x [array get env]
-} -body {
+} -cleanup cleanup1 -result a
+
+
+test env-5.1 {
+ corner cases - remove one elem at a time
+} -setup setup1 -body {
# When no environment variables exist, the env var will contain no
# entries. The "array names" call synchs up the C-level environ array with
# the Tcl level env array. Make sure an empty Tcl array is created.
@@ -246,9 +286,9 @@ test env-5.1 {corner cases - remove one elem at a time} -setup {
unset env($e)
}
array size env
-} -cleanup {
- array set env $x
-} -result {0}
+} -cleanup cleanup1 -result 0
+
+
test env-5.2 {corner cases - unset the env array} -setup {
interp create i
} -body {
@@ -262,42 +302,54 @@ test env-5.2 {corner cases - unset the env array} -setup {
} -cleanup {
interp delete i
} -result {0}
+
+
test env-5.3 {corner cases: unset the env in master should unset child} -setup {
+ setup1
interp create i
} -body {
# Variables deleted in a master interp should be deleted in child interp
# too.
- i eval { set env(THIS_SHOULD_EXIST) a}
+ i eval {set env(THIS_SHOULD_EXIST) a}
set result [set env(THIS_SHOULD_EXIST)]
unset env(THIS_SHOULD_EXIST)
lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
} -cleanup {
+ cleanup1
interp delete i
} -result {a 1}
+
+
test env-5.4 {corner cases - unset the env array} -setup {
+ setup1
interp create i
} -body {
# The info exists command should be in synch with the env array.
# Know Bug: 1737
- i eval { set env(THIS_SHOULD_EXIST) a}
+ i eval {set env(THIS_SHOULD_EXIST) a}
set result [info exists env(THIS_SHOULD_EXIST)]
lappend result [set env(THIS_SHOULD_EXIST)]
lappend result [info exists env(THIS_SHOULD_EXIST)]
} -cleanup {
+ cleanup1
interp delete i
} -result {1 a 1}
-test env-5.5 {corner cases - cannot have null entries on Windows} -constraints win -body {
+
+
+test env-5.5 {
+ corner cases - cannot have null entries on Windows
+} -constraints win -body {
set env() a
catch {set env()}
-} -result 1
+} -cleanup cleanup1 -result 1
-test env-6.1 {corner cases - add lots of env variables} -body {
+test env-6.1 {corner cases - add lots of env variables} -setup setup1 -body {
set size [array size env]
for {set i 0} {$i < 100} {incr i} {
set env(BOGUS$i) $i
}
expr {[array size env] - $size}
-} -result 100
+} -cleanup cleanup1 -result 100
test env-7.1 {[219226]: whole env array should not be unset by read} -body {
set n [array size env]
@@ -310,16 +362,20 @@ test env-7.1 {[219226]: whole env array should not be unset by read} -body {
return $n
} -result 0
-test env-7.2 {[219226]: links to env elements should not be removed by read} -body {
+test env-7.2 {
+ [219226]: links to env elements should not be removed by read
+} -setup setup1 -body {
apply {{} {
set ::env(test7_2) ok
upvar env(test7_2) elem
set ::env(PATH)
return $elem
}}
-} -result ok
+} -cleanup cleanup1 -result ok
-test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy trace} -body {
+test env-7.3 {
+ [9b4702]: testing existence of env(some_thing) should not destroy trace
+} -setup setup1 -body {
apply {{} {
catch {unset ::env(test7_3)}
proc foo args {
@@ -330,16 +386,25 @@ test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy
set ::env(not_yet_existent) "Now I'm here";
return [info exists ::env(test7_3)]
}}
-} -result 1
+} -cleanup cleanup1 -result 1
-# Restore the environment variables at the end of the test.
+test env-8.0 {
+ memory usage - valgrind does not report reachable memory
+} -body {
+ set res [set env(__DUMMY__) {i'm with dummy}]
+ unset env(__DUMMY__)
+ return $res
+} -result {i'm with dummy}
+
-foreach name [array names env] {
- unset env($name)
-}
-array set env $env2
# cleanup
+rename getenv {}
+rename envrestore {}
+rename envprep {}
+rename encodingrestore {}
+rename encodingswitch {}
+
removeFile $printenvScript
::tcltest::cleanupTests
return
diff --git a/tcl8.6/tests/exec.test b/tcl8.6/tests/exec.test
index 5f3a0cb..6570e57 100644
--- a/tcl8.6/tests/exec.test
+++ b/tcl8.6/tests/exec.test
@@ -11,9 +11,14 @@
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# There is no point in running Valgrind on cases where [exec] forks but then
+# fails and the child process doesn't go through full cleanup.
+
package require tcltest 2
namespace import -force ::tcltest::*
+package require tcltests
+
# All tests require the "exec" command.
# Skip them if exec is not defined.
testConstraint exec [llength [info commands exec]]
@@ -300,7 +305,6 @@ test exec-6.3 {redirecting stderr through a pipeline} {exec stdio} {
# I/O redirection: combinations.
set path(gorp.file2) [makeFile {} gorp.file2]
-file delete $path(gorp.file2)
test exec-7.1 {multiple I/O redirections} {exec} {
exec << "command input" > $path(gorp.file2) [interpreter] $path(cat) < $path(gorp.file)
@@ -326,11 +330,11 @@ test exec-8.2 {long input and output} {exec} {
# Commands that return errors.
-test exec-9.1 {commands returning errors} {exec} {
+test exec-9.1 {commands returning errors} {exec notValgrind} {
set x [catch {exec gorp456} msg]
list $x [string tolower $msg] [string tolower $errorCode]
} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
-test exec-9.2 {commands returning errors} {exec} {
+test exec-9.2 {commands returning errors} {exec notValgrind} {
string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
@@ -340,7 +344,7 @@ test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
} -returnCodes error -result {foo bar
child process exited abnormally}
-test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
+test exec-9.5 {commands returning errors} -constraints {exec stdio notValgrind} -body {
exec gorp456 | [interpreter] echo a b c
} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
test exec-9.6 {commands returning errors} -constraints {exec} -body {
@@ -429,13 +433,13 @@ test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
exec cat >@ $f
} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
close $f
-test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
+test exec-10.20 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec ~non_existent_user/foo/bar
} -returnCodes error -result {user "non_existent_user" doesn't exist}
-test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
+test exec-10.21 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec [interpreter] true | ~xyzzy_bad_user/x | false
} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
-test exec-10.22 {errors in exec invocation} -constraints exec -body {
+test exec-10.22 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec echo test > ~non_existent_user/foo/bar
} -returnCodes error -result {user "non_existent_user" doesn't exist}
# Commands in background.
@@ -511,7 +515,7 @@ test exec-13.1 {setting errorCode variable} {exec} {
test exec-13.2 {setting errorCode variable} {exec} {
list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
-test exec-13.3 {setting errorCode variable} {exec} {
+test exec-13.3 {setting errorCode variable} {exec notValgrind} {
set x [catch {exec _weird_cmd_} msg]
list $x [string tolower $msg] [lindex $errorCode 0] \
[string tolower [lrange $errorCode 2 end]]
@@ -549,7 +553,7 @@ test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
test exec-14.3 {unknown switch} -constraints {exec} -body {
exec -gorp
} -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --}
-test exec-14.4 {-- switch} -constraints {exec} -body {
+test exec-14.4 {-- switch} -constraints {exec notValgrind} -body {
exec -- -gorp
} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
test exec-14.5 {-ignorestderr switch} {exec} {
@@ -663,7 +667,7 @@ test exec-18.2 {exec cat deals with weird file names} -body {
# Note that this test cannot be adapted to work on Windows; that platform has
# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
# that there is a POSIX shell...
-test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
+test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix notValgrind} -setup {
set tmpfile [makeFile {0} tmpfile.exec-19.1]
} -body {
# Note that we have to allow for the current contents of the temporary
@@ -676,7 +680,7 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
{for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
exec /bin/sh -c \
{for a in d e f; do sleep 1; echo $a >&2; done} 2>>$tmpfile &
- # The above four shell invokations take about 3 seconds to finish, so allow
+ # The above four shell invocations take about 3 seconds to finish, so allow
# 5s (in case the machine is busy)
after 5000
# Check that no bytes have got lost through mixups with overlapping
diff --git a/tcl8.6/tests/expr.test b/tcl8.6/tests/expr.test
index 5843b49..a265ac6 100644
--- a/tcl8.6/tests/expr.test
+++ b/tcl8.6/tests/expr.test
@@ -5838,6 +5838,15 @@ test expr-32.5 {Bug 1585704} {
test expr-32.6 {Bug 1585704} {
expr -(1<<32)%(1<<63)
} [expr (1<<63)-(1<<32)]
+test expr-32.7 {bignum regression} {
+ expr {0%(1<<63)}
+} 0
+test expr-32.8 {bignum regression} {
+ expr {0%-(1<<63)}
+} 0
+test expr-32.9 {bignum regression} {
+ expr {0%-(1+(1<<63))}
+} 0
test expr-33.1 {parse largest long value} longIs32bit {
set max_long_str 2147483647
@@ -7187,6 +7196,15 @@ test expr-51.1 {test round-to-even on input} {
expr 6.9294956446009195e15
} 6929495644600920.0
+test expr-52.1 {
+ comparison with empty string does not generate string representation
+} {
+ set a [list one two three]
+ list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [
+ string match {*no string representation*} [
+ ::tcl::unsupported::representation $a]]
+} {0 0 1 1}
+
# cleanup
diff --git a/tcl8.6/tests/fCmd.test b/tcl8.6/tests/fCmd.test
index c8264b2..11ab79e 100644
--- a/tcl8.6/tests/fCmd.test
+++ b/tcl8.6/tests/fCmd.test
@@ -65,11 +65,10 @@ if {[testConstraint unix]} {
# Also used in winFCmd...
if {[testConstraint win]} {
- set major [string index $tcl_platform(osVersion) 0]
- if {[testConstraint nt] && $major > 4} {
- if {$major > 5} {
+ if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} {
+ if {$::tcl_platform(osVersion) >= 6.0} {
testConstraint winVista 1
- } elseif {$major == 5} {
+ } else {
testConstraint win2000orXP 1
}
}
@@ -78,7 +77,7 @@ if {[testConstraint win]} {
testConstraint darwin9 [expr {
[testConstraint unix]
&& $tcl_platform(os) eq "Darwin"
- && [package vsatisfies 1.$tcl_platform(osVersion) 1.9]
+ && [package vsatisfies 1.$::tcl_platform(osVersion) 1.9]
}]
testConstraint notDarwin9 [expr {![testConstraint darwin9]}]
@@ -2309,7 +2308,7 @@ test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup {
if {
[testConstraint win] &&
- ([string index $tcl_platform(osVersion) 0] < 5
+ ($::tcl_platform(osVersion) < 5.0
|| [lindex [file system [temporaryDirectory]] 1] ne "NTFS")
} then {
testConstraint linkDirectory 0
diff --git a/tcl8.6/tests/fileName.test b/tcl8.6/tests/fileName.test
index ce89623..7b51da1 100644
--- a/tcl8.6/tests/fileName.test
+++ b/tcl8.6/tests/fileName.test
@@ -23,7 +23,7 @@ testConstraint testtranslatefilename [llength [info commands testtranslatefilena
testConstraint linkDirectory 1
testConstraint symbolicLinkFile 1
if {[testConstraint win]} {
- if {[string index $tcl_platform(osVersion) 0] < 5 \
+ if {$::tcl_platform(osVersion) < 5.0 \
|| [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} {
testConstraint linkDirectory 0
}
@@ -778,6 +778,8 @@ test filename-11.16 {Tcl_GlobCmd} {
} {globTest}
set globname "globTest"
set horribleglobname "glob\[\{Test"
+set tildeglobname "./~test.txt"
+
test filename-11.17 {Tcl_GlobCmd} {unix} {
lsort [glob -directory $globname *]
} [lsort [list [file join $globname a1] [file join $globname a2]\
@@ -917,11 +919,12 @@ test filename-11.21.1 {Tcl_GlobCmd} -body {
} -result {{[tcl].testremains}}
# Get rid of file/dir if it exists, since it will have been left behind by a
# previous failed run.
-if {[file exists $horribleglobname]} {
- file delete -force $horribleglobname
-}
+file delete -force $horribleglobname
file rename globTest $horribleglobname
set globname $horribleglobname
+file delete -force $tildeglobname
+close [open $tildeglobname w]
+
test filename-11.22 {Tcl_GlobCmd} {unix} {
lsort [glob -dir $globname *]
} [lsort [list [file join $globname a1] [file join $globname a2]\
@@ -1040,7 +1043,9 @@ test filename-11.41 {Tcl_GlobCmd} -body {
test filename-11.42 {Tcl_GlobCmd} -body {
set res [list]
foreach f [glob -dir [pwd] *] {
- lappend res [file tail $f]
+ set f [file tail $f]
+ regsub {^./} $f {} f; # until glob bug [2511011fff] don't fixed (tilde expansion prevention).
+ lappend res $f
}
list $res [glob *]
} -match compareWords -result equal
@@ -1080,8 +1085,9 @@ test filename-11.49 {Tcl_GlobCmd} -returnCodes error -body {
} -result {bad argument to "-types": abcde}
file rename $horribleglobname globTest
+file delete -force $tildeglobname
set globname globTest
-unset horribleglobname
+unset horribleglobname tildeglobname
test filename-12.1 {simple globbing} {unixOrPc} {
glob {}
diff --git a/tcl8.6/tests/fileSystem.test b/tcl8.6/tests/fileSystem.test
index b805780..f778112 100644
--- a/tcl8.6/tests/fileSystem.test
+++ b/tcl8.6/tests/fileSystem.test
@@ -264,6 +264,12 @@ removeDirectory dir.dir
test filesystem-1.30 {normalisation of nonexistent user} -body {
file normalize ~noonewiththisname
} -returnCodes error -result {user "noonewiththisname" doesn't exist}
+test filesystem-1.30.1 {normalisation of existing user} -body {
+ catch {file normalize ~$::tcl_platform(user)}
+} -result {0}
+test filesystem-1.30.2 {normalisation of nonexistent user specified as user@domain} -body {
+ file normalize ~nonexistentuser@nonexistentdomain
+} -returnCodes error -result {user "nonexistentuser@nonexistentdomain" doesn't exist}
test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
testsetplatform unix
file normalize /foo/../bar
diff --git a/tcl8.6/tests/foreach.test b/tcl8.6/tests/foreach.test
index 6fd5476..84af4bd 100644
--- a/tcl8.6/tests/foreach.test
+++ b/tcl8.6/tests/foreach.test
@@ -212,14 +212,16 @@ test foreach-6.4 {break tests} {
set msg
} {wrong # args: should be "break"}
# Check for bug #406709
-test foreach-6.5 {break tests} {
+test foreach-6.5 {break tests} -body {
proc a {} {
set a 1
foreach b b {list [concat a; break]; incr a}
incr a
}
a
-} {2}
+} -cleanup {
+ rename a {}
+} -result {2}
# Test for incorrect "double evaluation" semantics
test foreach-7.1 {delayed substitution of body} {
diff --git a/tcl8.6/tests/format.test b/tcl8.6/tests/format.test
index 2795ac2..88013cf 100644
--- a/tcl8.6/tests/format.test
+++ b/tcl8.6/tests/format.test
@@ -585,6 +585,20 @@ test format-19.3 {Bug 2830354} {
string length [format %340f 0]
} 340
+test format-19.4.1 {Bug d498578df4: width overflow should cause limit exceeded} \
+-constraints {longIs32bit} -body {
+ # in case of overflow into negative, it produces width -2 (and limit exceeded),
+ # in case of width will be unsigned, it will be outside limit (2GB for 32bit)...
+ # and it don't throw an error in case the bug is not fixed (and probably no segfault).
+ format %[expr {0xffffffff - 1}]g 0
+} -returnCodes error -result "max size for a Tcl value exceeded"
+
+test format-19.4.2 {Bug d498578df4: width overflow should cause limit exceeded} -body {
+ # limit should exceeds in any case,
+ # and it don't throw an error in case the bug is not fixed (and probably no segfault).
+ format %[expr {0xffffffffffffffff - 1}]g 0
+} -returnCodes error -result "max size for a Tcl value exceeded"
+
# Note that this test may fail in future versions
test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
set x [dict create a b c d]
diff --git a/tcl8.6/tests/http.test b/tcl8.6/tests/http.test
index 5a00cd5..242dceb 100644
--- a/tcl8.6/tests/http.test
+++ b/tcl8.6/tests/http.test
@@ -86,7 +86,7 @@ if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} {
test http-1.1 {http::config} {
http::config -useragent UserAgent
http::config
-} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"]
+} [list -accept */* -pipeline 1 -postfresh 0 -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -repost 0 -urlencoding utf-8 -useragent UserAgent -zip 1]
test http-1.2 {http::config} {
http::config -proxyfilter
} http::ProxyRequired
@@ -101,10 +101,10 @@ test http-1.4 {http::config} {
set x [http::config]
http::config {*}$savedconf
set x
-} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}}
+} {-accept */* -pipeline 1 -postfresh 0 -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -repost 0 -urlencoding iso8859-1 -useragent {Tcl Test Suite} -zip 1}
test http-1.5 {http::config} -returnCodes error -body {
http::config -proxyhost {} -junk 8080
-} -result {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent}
+} -result {Unknown option -junk, must be: -accept, -pipeline, -postfresh, -proxyfilter, -proxyhost, -proxyport, -repost, -urlencoding, -useragent, -zip}
test http-1.6 {http::config} -setup {
set oldenc [http::config -urlencoding]
} -body {
diff --git a/tcl8.6/tests/http11.test b/tcl8.6/tests/http11.test
index c9ded0b..1e30802 100644
--- a/tcl8.6/tests/http11.test
+++ b/tcl8.6/tests/http11.test
@@ -515,10 +515,7 @@ proc handler {var sock token} {
set chunk [read $sock]
append data $chunk
#::http::Log "handler read [string length $chunk] ([chan configure $sock -buffersize])"
- if {[eof $sock]} {
- #::http::Log "handler eof $sock"
- chan event $sock readable {}
- }
+ return [string length $chunk]
}
test http11-3.0 "-handler,close,identity" -setup {
@@ -666,6 +663,13 @@ test http11-4.3 "normal post request, check channel query length" -setup {
# -------------------------------------------------------------------------
+# Eliminate valgrind "still reachable" reports on outstanding "Detached"
+# structures in the detached list which stem from PipeClose2Proc not waiting
+# around for background processes to complete, meaning that previous calls to
+# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
+after 10
+exec [info nameofexecutable] << {}
+
foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
if {[llength [info proc $p]]} {rename $p {}}
}
diff --git a/tcl8.6/tests/httpPipeline.test b/tcl8.6/tests/httpPipeline.test
new file mode 100644
index 0000000..8de79b9
--- /dev/null
+++ b/tcl8.6/tests/httpPipeline.test
@@ -0,0 +1,866 @@
+# httpPipeline.test
+#
+# Test HTTP/1.1 concurrent requests including
+# queueing, pipelining and retries.
+#
+# Copyright (C) 2018 Keith Nash <kjnash@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+package require http 2.8
+
+set sourcedir [file normalize [file dirname [info script]]]
+source [file join $sourcedir httpTest.tcl]
+source [file join $sourcedir httpTestScript.tcl]
+
+# ------------------------------------------------------------------------------
+# (1) Define the test scripts that will be used to generate logs for analysis -
+# and also define the "correct" results.
+# ------------------------------------------------------------------------------
+
+proc ReturnTestScriptAndResult {ca cb delay te} {
+
+ switch -- $ca {
+ 1 {set start {
+ START
+ KEEPALIVE 0
+ PIPELINE 0
+ }}
+
+ 2 {set start {
+ START
+ KEEPALIVE 0
+ PIPELINE 1
+ }}
+
+ 3 {set start {
+ START
+ KEEPALIVE 1
+ PIPELINE 0
+ }}
+
+ 4 {set start {
+ START
+ KEEPALIVE 1
+ PIPELINE 1
+ }}
+
+ default {
+ return -code error {no matching script}
+ }
+ }
+
+ set middle "
+ [list DELAY $delay]
+ "
+
+ switch -- $cb {
+ 1 {set end {
+ GET a
+ GET b
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 ? ? ?}
+ set resLong {1 2 3 4}
+ }
+
+ 2 {set end {
+ GET a
+ HEAD b
+ GET c
+ HEAD a
+ HEAD c
+ STOP
+ }
+ set resShort {1 ? ? ? ?}
+ set resLong {1 2 3 4 5}
+ }
+
+ 3 {set end {
+ HEAD a
+ GET b
+ HEAD c
+ HEAD b
+ GET a
+ GET b
+ STOP
+ }
+ set resShort {1 ? ? ? ? ?}
+ set resLong {1 2 3 4 5 6}
+ }
+
+ 4 {set end {
+ GET a
+ GET b
+ GET c
+ GET a
+ POST b address=home code=brief paid=yes
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 ? ? ? 5 ? ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 5 {set end {
+ POST a address=home code=brief paid=yes
+ POST b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ POST b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ POST b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 2 3 4 5 6 7 8 9}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 6 {set end {
+ POST a address=home code=brief paid=yes
+ GET b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ GET a address=home code=brief paid=yes
+ GET b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ HEAD b address=home code=brief paid=yes
+ GET c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 ? 3 ? ? 6 7 ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 7 {set end {
+ GET b address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ GET a address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ GET b address=home code=brief paid=yes
+ HEAD b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ GET c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 2 ? 4 ? ? 7 8 ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 8 {set end {
+ # Telling the server to close the connection.
+ GET a
+ GET b close=y
+ GET c
+ GET a
+ GET b
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 ? 3 ? ? ? ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 9 {set end {
+ # Telling the server to close the connection.
+ GET a
+ POST b close=y address=home code=brief paid=yes
+ GET c
+ GET a
+ GET b
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 2 3 ? ? ? ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 10 {set end {
+ # Telling the server to close the connection.
+ GET a
+ GET b close=y
+ POST c address=home code=brief paid=yes
+ GET a
+ GET b
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 ? 3 ? ? ? ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 11 {set end {
+ # Telling the server to close the connection twice.
+ GET a
+ GET b close=y
+ GET c
+ GET a
+ GET b close=y
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 ? 3 ? ? 6 ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 12 {set end {
+ # Telling the server to delay before sending the response.
+ GET a
+ GET b delay=1
+ GET c
+ GET a
+ GET b
+ STOP
+ }
+ set resShort {1 ? ? ? ?}
+ set resLong {1 2 3 4 5}
+ }
+
+ 13 {set end {
+ # Making the server close the connection (time out).
+ GET a
+ WAIT 2000
+ GET b
+ GET c
+ GET a
+ GET b
+ STOP
+ }
+ set resShort {1 2 ? ? ?}
+ set resLong {1 2 3 4 5}
+ }
+
+ 14 {set end {
+ # Making the server close the connection (time out) twice.
+ GET a
+ WAIT 2000
+ GET b
+ GET c
+ GET a
+ WAIT 2000
+ GET b
+ GET c
+ GET a
+ GET b
+ GET c
+ STOP
+ }
+ set resShort {1 2 ? ? 5 ? ? ? ?}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 15 {set end {
+ POST a address=home code=brief paid=yes
+ POST b address=home code=brief paid=yes close=y delay=1
+ POST c address=home code=brief paid=yes delay=1
+ POST a address=home code=brief paid=yes close=y
+ WAIT 2000
+ POST b address=home code=brief paid=yes delay=1
+ POST c address=home code=brief paid=yes close=y
+ POST a address=home code=brief paid=yes
+ POST b address=home code=brief paid=yes close=y
+ POST c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 2 3 4 5 6 7 8 9}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 16 {set end {
+ POST a address=home code=brief paid=yes
+ GET b address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes close=y
+ GET a address=home code=brief paid=yes
+ GET b address=home code=brief paid=yes close=y
+ POST c address=home code=brief paid=yes
+ WAIT 2000
+ POST a address=home code=brief paid=yes
+ HEAD b address=home code=brief paid=yes close=y
+ GET c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 ? 3 4 ? 6 7 ? 9}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+ 17 {set end {
+ GET b address=home code=brief paid=yes
+ POST a address=home code=brief paid=yes
+ GET a address=home code=brief paid=yes
+ POST c address=home code=brief paid=yes close=y
+ GET b address=home code=brief paid=yes
+ HEAD b address=home code=brief paid=yes close=y
+ POST c address=home code=brief paid=yes
+ WAIT 2000
+ POST a address=home code=brief paid=yes
+ WAIT 2000
+ GET c address=home code=brief paid=yes
+ STOP
+ }
+ set resShort {1 2 3 4 5 ? 7 8 9}
+ set resLong {1 2 3 4 5 6 7 8 9}
+ }
+
+
+ 18 {set end {
+ REPOST 0
+ GET a
+ WAIT 2000
+ POST b address=home code=brief paid=yes
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 2 ? ?}
+ set resLong {1 2 3 4}
+ # resShort is overwritten below for the case ($te == 1).
+ }
+
+
+ 19 {set end {
+ REPOST 0
+ GET a
+ WAIT 2000
+ GET b address=home code=brief paid=yes
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 2 ? ?}
+ set resLong {1 2 3 4}
+ }
+
+
+ 20 {set end {
+ POSTFRESH 1
+ GET a
+ WAIT 2000
+ POST b address=home code=brief paid=yes
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 3 ?}
+ set resLong {1 3 4}
+ }
+
+
+ 21 {set end {
+ POSTFRESH 1
+ GET a
+ WAIT 2000
+ GET b address=home code=brief paid=yes
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 2 ? ?}
+ set resLong {1 2 3 4}
+ }
+
+ 22 {set end {
+ GET a
+ WAIT 2000
+ KEEPALIVE 0
+ POST b address=home code=brief paid=yes
+ KEEPALIVE 1
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 3 ?}
+ set resLong {1 3 4}
+ }
+
+
+ 23 {set end {
+ GET a
+ WAIT 2000
+ KEEPALIVE 0
+ GET b address=home code=brief paid=yes
+ KEEPALIVE 1
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 3 ?}
+ set resLong {1 3 4}
+ }
+
+ 24 {set end {
+ GET a
+ KEEPALIVE 0
+ POST b address=home code=brief paid=yes
+ KEEPALIVE 1
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 ? ?}
+ set resLong {1 3 4}
+ }
+
+
+ 25 {set end {
+ GET a
+ KEEPALIVE 0
+ GET b address=home code=brief paid=yes
+ KEEPALIVE 1
+ GET c
+ GET a
+ STOP
+ }
+ set resShort {1 ? ?}
+ set resLong {1 3 4}
+ }
+
+ default {
+ return -code error {no matching script}
+ }
+ }
+
+
+ if {$ca < 3} {
+ # Not Keep-Alive.
+ set result "Passed all sanity checks."
+
+ } elseif {$ca == 3} {
+ # Keep-Alive, not pipelined.
+ set result {}
+ append result "Passed all sanity checks.\n"
+ append result "Have overlaps including response body:\n"
+
+ } else {
+ # Keep-Alive, pipelined: ($ca == 4)
+ set result {}
+ append result "Passed all sanity checks.\n"
+ append result "Overlap-free without response body:\n"
+ append result "$resShort"
+ }
+
+ # - The special case of test *.18*-testEof needs test results to be
+ # individually written.
+ # - These test -repost 0 when there is a POST to apply it to, and the server
+ # timeout has not been detected.
+ if {($cb == 18) && ($te == 1)} {
+ if {$ca < 3} {
+ # Not Keep-Alive.
+ set result "Passed all sanity checks."
+
+ } elseif {$ca == 3 && $delay == 0} {
+ # Keep-Alive, not pipelined.
+ set result [MakeMessage {
+ |Problems with sanity checks:
+ |Wrong sequence for token ::http::2 - {A B C D X X X}
+ |- and error(s) X
+ |Wrong sequence for token ::http::3 - {A X X}
+ |- and error(s) X
+ |Wrong sequence for token ::http::4 - {A X X X}
+ |- and error(s) X
+ |
+ |Have overlaps including response body:
+ |
+ }]
+
+ } elseif {$ca == 3} {
+ # Keep-Alive, not pipelined.
+ set result [MakeMessage {
+ |Problems with sanity checks:
+ |Wrong sequence for token ::http::2 - {A B C D X X X}
+ |- and error(s) X
+ |
+ |Have overlaps including response body:
+ |
+ }]
+
+ } elseif {$delay == 0} {
+ # Keep-Alive, pipelined: ($ca == 4)
+ set result [MakeMessage {
+ |Problems with sanity checks:
+ |Wrong sequence for token ::http::2 - {A B C D X X X}
+ |- and error(s) X
+ |Wrong sequence for token ::http::3 - {A X X}
+ |- and error(s) X
+ |Wrong sequence for token ::http::4 - {A X X X}
+ |- and error(s) X
+ |
+ |Overlap-free without response body:
+ |
+ }]
+
+ } else {
+ set result [MakeMessage {
+ |Problems with sanity checks:
+ |Wrong sequence for token ::http::2 - {A B C D X X X}
+ |- and error(s) X
+ |
+ |Overlap-free without response body:
+ |
+ }]
+
+ }
+ }
+
+ return [list "$start$middle$end" $result]
+}
+
+# ------------------------------------------------------------------------------
+# Proc MakeMessage
+# ------------------------------------------------------------------------------
+# WHD's one-line command to generate multi-line strings from readable code.
+#
+# Example:
+# set blurb [MakeMessage {
+# |This command allows multi-line strings to be created with readable
+# |code, and without breaking the rules for indentation.
+# |
+# |The command shifts the entire block of text to the left, omitting
+# |the pipe character and the spaces to its left.
+# }]
+# ------------------------------------------------------------------------------
+
+proc MakeMessage {in} {
+ regsub -all -line {^\s*\|} [string trim $in] {}
+ # N.B. Implicit Return.
+}
+
+
+proc ReturnTestScript {ca cb delay te} {
+ lassign [ReturnTestScriptAndResult $ca $cb $delay $te] script result
+ return $script
+}
+
+proc ReturnTestResult {ca cb delay te} {
+ lassign [ReturnTestScriptAndResult $ca $cb $delay $te] script result
+ return $result
+}
+
+
+# ------------------------------------------------------------------------------
+# (2) Command to run a test script and use httpTest to analyse the logs.
+# ------------------------------------------------------------------------------
+
+namespace import httpTestScript::runHttpTestScript
+namespace import httpTestScript::cleanupHttpTestScript
+namespace import httpTest::cleanupHttpTest
+namespace import httpTest::logAnalyse
+namespace import httpTest::setHttpTestOptions
+
+proc RunTest {header footer delay te} {
+ set num [runHttpTestScript [ReturnTestScript $header $footer $delay $te]]
+ set skipOverlaps 0
+ set notPiped {}
+ set notIncluded {}
+
+ # --------------------------------------------------------------------------
+ # Custom code for specific tests
+ # --------------------------------------------------------------------------
+ if {$header < 3} {
+ set skipOverlaps 1
+ for {set i 1} {$i <= $num} {incr i} {
+ lappend notPiped $i
+ }
+ } elseif {$header > 2 && $footer == 18 && $te == 1} {
+ set skipOverlaps 1
+ if {$delay == 0} {
+ # Transaction 1 is conventional.
+ # Check that transactions 2,3,4 are cancelled.
+ set notPiped {1}
+ set notIncluded $notPiped
+ } else {
+ # Transaction 1 is conventional.
+ # Check that transaction 2 is cancelled.
+ # The timing of transactions 3 and 4 is uncertain.
+ set notPiped {1 3 4}
+ set notIncluded $notPiped
+ }
+ } elseif {$footer in {20 22 23 24 25}} {
+ # Transaction 2 uses its own socket.
+ set notPiped 2
+ set notIncluded $notPiped
+ } else {
+ }
+ # --------------------------------------------------------------------------
+ # End of custom code for specific tests
+ # --------------------------------------------------------------------------
+
+
+ set Results [logAnalyse $num $skipOverlaps $notIncluded $notPiped]
+ lassign $Results msg cleanE cleanF dirtyE dirtyF
+ if {$msg eq {}} {
+ set msg "Passed all sanity checks."
+ } else {
+ set msg "Problems with sanity checks:\n$msg"
+ }
+
+ if 0 {
+ puts $msg
+ puts "Overlap-free including response body:\n$cleanF"
+ puts "Have overlaps including response body:\n$dirtyF"
+ puts "Overlap-free without response body:\n$cleanE"
+ puts "Have overlaps without response body:\n$dirtyE"
+ }
+
+ if {$header < 3} {
+ # No ordering, just check that transactions all finish
+ set result $msg
+ } elseif {$header == 3} {
+ # Not pipelined - check overlaps with response body.
+ set result "$msg\nHave overlaps including response body:\n$dirtyF"
+ } else {
+ # Pipelined - check overlaps without response body. Check that the
+ # first request, the first requests after replay, and POSTs are clean.
+ set result "$msg\nOverlap-free without response body:\n$cleanE"
+ }
+ set ::nTokens $num
+ return $result
+}
+
+
+# ------------------------------------------------------------------------------
+# (3) VERBOSITY CONTROL
+# ------------------------------------------------------------------------------
+# If tests fail, run an individual test with -verbose 1 or 2 for diagnosis.
+# If still obscure, uncomment #Log and ##Log lines in the http package.
+# ------------------------------------------------------------------------------
+
+setHttpTestOptions -verbose 0
+
+# ------------------------------------------------------------------------------
+# (4) Define the base URLs used for testing. Each must have a query string.
+# ------------------------------------------------------------------------------
+# - A HTTP/1.1 server is required. It should be configured to provide
+# persistent connections when requested to do so, and to close these
+# connections if they are idle for one second.
+# - The resource must be served with status 200 in response to a valid GET or
+# POST.
+# - The value of "page" is always specified in the query-string. Different
+# resources for the three values of "page" allow testing of both chunked and
+# unchunked transfer encoding.
+# - The variables "close" and "delay" may be specified in the query-string (for
+# a GET) or the request body (for a POST).
+# - "delay" is a numerical value in seconds, and causes the server to delay
+# the response, including headers.
+# - "close", if it has the value "y", instructs the server to close the
+# connection ater the current request.
+# - Any other variables should be ignored.
+# ------------------------------------------------------------------------------
+
+namespace eval ::httpTestScript {
+ variable URL
+ array set URL {
+ a http://test-tcl-http.kerlin.org/index.html?page=privacy
+ b http://test-tcl-http.kerlin.org/index.html?page=conditions
+ c http://test-tcl-http.kerlin.org/index.html?page=welcome
+ }
+}
+
+
+# ------------------------------------------------------------------------------
+# (5) Define the tests
+# ------------------------------------------------------------------------------
+# Constraints:
+# - serverNeeded - the URLs defined at (4) must be available, and must have the
+# properties specified there.
+# - duplicate - the value of -pipeline does not matter if -keepalive 0
+# - timeout1s - tests that work correctly only if the server closes
+# persistent connections after one second.
+#
+# Server timeout of persistent connections should be 1s. Delays of 2s are
+# intended to cause timeout.
+# Servers are usually configured to use a longer timeout: this will cause the
+# tests to fail. The "2000" could be replaced with a larger number, but the
+# tests will then be inconveniently slow.
+# ------------------------------------------------------------------------------
+
+#testConstraint serverNeeded 1
+#testConstraint timeout1s 1
+#testConstraint duplicate 1
+
+# ------------------------------------------------------------------------------
+# Proc SetTestEof - to edit the command ::http::KeepSocket
+# ------------------------------------------------------------------------------
+# The usual line in command ::http::KeepSocket is " set TEST_EOF 0".
+# Whether the value set in the file is 0 or 1, change it here to the value
+# specified by the argument.
+#
+# It is worth doing all tests for both values of the argument.
+#
+# test 0 - ::http::KeepSocket is unchanged, detects server eof where possible
+# and closes the connection.
+# test 1 - ::http::KeepSocket is edited, does not detect server eof, so the
+# reaction to finding server eof can be tested without the difficulty
+# of testing in the few milliseconds of an asynchronous close event.
+# ------------------------------------------------------------------------------
+
+proc SetTestEof {test} {
+ set body [info body ::http::KeepSocket]
+ set subs " set TEST_EOF $test"
+ set count [regsub -line -all -- {^\s*set TEST_EOF .*$} $body $subs newBody]
+ if {$count != 1} {
+ return -code error {proc ::http::KeepSocket has unexpected form}
+ }
+ proc ::http::KeepSocket {token} $newBody
+ return
+}
+
+for {set header 1} {$header <= 4} {incr header} {
+ if {$header == 4} {
+ setHttpTestOptions -dotted 1
+ set match glob
+ } else {
+ setHttpTestOptions -dotted 0
+ set match exact
+ }
+
+ if {$header == 2} {
+ set cons0 {serverNeeded duplicate}
+ } else {
+ set cons0 serverNeeded
+ }
+
+ for {set footer 1} {$footer <= 25} {incr footer} {
+ foreach {delay label} {
+ 0 a
+ 1 b
+ 2 c
+ 3 d
+ 5 e
+ 8 f
+ 12 g
+ 100 h
+ 500 i
+ 2000 j
+ } {
+ foreach te {0 1} {
+ if {$te} {
+ set tag testEof
+ } else {
+ set tag normal
+ }
+ set suffix {}
+ set cons $cons0
+
+ # ------------------------------------------------------------------
+ # Custom code for individual tests
+ # ------------------------------------------------------------------
+ if {$footer in {18}} {
+ # Custom code:
+ if {($label eq "j") && ($te == 1)} {
+ continue
+ }
+ if {$te == 1} {
+ # The test (of REPOST 0) is useful if tag is "testEof"
+ # (server timeout without client reaction). The same test
+ # has a different result if tag is "normal".
+
+ set suffix " - extra test for -repost 0 - ::http::2 must be"
+ append suffix " cancelled"
+ if {($delay == 0)} {
+ append suffix ", along with ::http::3 ::http::4 if"
+ append suffix " the test creates these before ::http::2"
+ append suffix " is cancelled"
+ }
+ } else {
+ }
+ } elseif {$footer in {19}} {
+ set suffix " - extra test for -repost 0"
+ } elseif {$footer in {20 21}} {
+ set suffix " - extra test for -postfresh 1"
+ if {($footer == 20)} {
+ append suffix " - ::http::2 uses a separate socket"
+ append suffix ", other requests use a persistent connection"
+ }
+ } elseif {$footer in {22 23 24 25}} {
+ append suffix " - ::http::2 uses a separate socket"
+ append suffix ", other requests use a persistent connection"
+ } else {
+ }
+
+ if {($footer >= 13 && $footer <= 23)} {
+ # Test use WAIT and depend on server timeout before this time.
+ lappend cons timeout1s
+ }
+ # ------------------------------------------------------------------
+ # End of custom code.
+ # ------------------------------------------------------------------
+
+ set name "pipeline test header $header footer $footer delay $delay $tag$suffix"
+
+
+ # Here's the test:
+ test httpPipeline-${header}.${footer}${label}-${tag} $name \
+ -constraints $cons \
+ -setup [string map [list TE $te] {
+ # Restore default values for tests:
+ http::config -pipeline 1 -postfresh 0 -repost 1
+ http::init
+ set http::http(uid) 0
+ SetTestEof {TE}
+ }] -body [list RunTest $header $footer $delay $te] -cleanup {
+ # Restore default values for tests:
+ http::config -pipeline 1 -postfresh 0 -repost 1
+ cleanupHttpTestScript
+ SetTestEof 0
+ cleanupHttpTest
+ after 2000
+ # Wait for persistent sockets on the server to time out.
+ } -result [ReturnTestResult $header $footer $delay $te] -match $match
+
+
+ }
+
+ }
+ }
+}
+
+# ------------------------------------------------------------------------------
+# (*) Notes on tests *.18*-testEof, *.19*-testEof - these test -repost 0
+# ------------------------------------------------------------------------------
+# These tests are a bit awkward because the main test kit analyses whether all
+# requests are satisfied, with retries if necessary, and it has result analysis
+# for processing retry logs.
+# - *.18*-testEof tests that certain requests are NOT satisfied, so the analysis
+# is a one-off.
+# - Tests *.18a-testEof depend on client/server timing - the test needs to call
+# http::geturl for all requests before the POST (request 2) is cancelled.
+# We test that requests 2, 3, 4 are all cancelled.
+# - Other tests *.18*-testEof may not request 3 and 4 in time for the to be
+# added to the write queue before request 2 is completed. We simply check that
+# request 2 is cancelled.
+# - The behaviour is different if all connections are allowed to time out
+# (label "j"). This case is not needed to test -repost 0, and is omitted.
+# - Tests *.18*-normal and *.19* are conventional (-repost 0 should have no
+# effect).
+# ------------------------------------------------------------------------------
+
+
+unset header footer delay label suffix match cons name te
+namespace delete ::httpTest
+namespace delete ::httpTestScript
+
+::tcltest::cleanupTests
diff --git a/tcl8.6/tests/httpTest.tcl b/tcl8.6/tests/httpTest.tcl
new file mode 100644
index 0000000..326b361
--- /dev/null
+++ b/tcl8.6/tests/httpTest.tcl
@@ -0,0 +1,505 @@
+# httpTest.tcl
+#
+# Test HTTP/1.1 concurrent requests including
+# queueing, pipelining and retries.
+#
+# Copyright (C) 2018 Keith Nash <kjnash@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ------------------------------------------------------------------------------
+# "Package" httpTest for analysis of Log output of http requests.
+# ------------------------------------------------------------------------------
+# This is a specialised test kit for examining the presence, ordering, and
+# overlap of multiple HTTP transactions over a persistent ("Keep-Alive")
+# connection; and also for testing reconnection in accordance with RFC 7230 when
+# the connection is lost.
+#
+# This kit is probably not useful for other purposes. It depends on the
+# presence of specific Log commands in the http library, and it interprets the
+# logs that these commands create.
+# ------------------------------------------------------------------------------
+
+package require http
+
+namespace eval ::http {
+ variable TestStartTimeInMs [clock milliseconds]
+# catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"}
+}
+
+namespace eval ::httpTest {
+ variable testResults {}
+ variable testOptions
+ array set testOptions {
+ -verbose 0
+ -dotted 1
+ }
+ # -verbose - 0 quiet 1 write to stdout 2 write more
+ # -dotted - (boolean) use dots for absences in lists of transactions
+}
+
+proc httpTest::Puts {txt} {
+ variable testOptions
+ if {$testOptions(-verbose) > 0} {
+ puts stdout $txt
+ flush stdout
+ }
+ return
+}
+
+# http::Log
+#
+# A special-purpose logger used for running tests.
+# - Processes Log calls that have "^" in their arguments, and records them in
+# variable ::httpTest::testResults.
+# - Also writes them to stdout (using Puts) if ($testOptions(-verbose) > 0).
+# - Also writes Log calls that do not have "^", if ($testOptions(-verbose) > 1).
+
+proc http::Log {args} {
+ variable TestStartTimeInMs
+ set time [expr {[clock milliseconds] - $TestStartTimeInMs}]
+ set txt [list $time {*}$args]
+ if {[string first ^ $txt] != -1} {
+ ::httpTest::LogRecord $txt
+ ::httpTest::Puts $txt
+ } elseif {$::httpTest::testOptions(-verbose) > 1} {
+ ::httpTest::Puts $txt
+ }
+ return
+}
+
+
+# Called by http::Log (the "testing" version) to record logs for later analysis.
+
+proc httpTest::LogRecord {txt} {
+ variable testResults
+
+ set pos [string first ^ $txt]
+ set len [string length $txt]
+ if {$pos > $len - 3} {
+ puts stdout "Logging Error: $txt"
+ puts stdout "Fix this call to Log in http-*.tm so it has ^ then\
+ a letter then a numeral."
+ flush stdout
+ } elseif {$pos == -1} {
+ # Called by mistake.
+ } else {
+ set letter [string index $txt [incr pos]]
+ set number [string index $txt [incr pos]]
+ # Max 9 requests!
+ lappend testResults [list $letter $number]
+ }
+
+ return
+}
+
+
+# ------------------------------------------------------------------------------
+# Commands for analysing the logs recorded when calling http::geturl.
+# ------------------------------------------------------------------------------
+
+# httpTest::TestOverlaps --
+#
+# The main test for correct behaviour of pipelined and sequential
+# (non-pipelined) transactions. Other tests should be run first to detect
+# any inconsistencies in the data (e.g. absence of the elements that are
+# examined here).
+#
+# Examine the sequence $someResults for each transaction from 1 to $n,
+# ignoring any that are listed in $badTrans.
+# Determine whether the elements "B" to $term for one transaction overlap
+# elements "B" to $term for the previous and following transactions.
+#
+# Transactions in the list $badTrans are not included in "clean" or
+# "dirty", but their possible overlap with other transactions is noted.
+# Transactions in the list $notPiped are a subset of $badTrans, and
+# their possible overlap with other transactions is NOT noted.
+#
+# Arguments:
+# someResults - list of results, each of the form {letter numeral}
+# n - number of HTTP transactions
+# term - letter that indicated end of search range. "E" for testing
+# overlaps from start of request to end of response headers.
+# "F" to extend to the end of the response body.
+# msg - the cumulative message from sanity checks. Append to it only
+# to report a test failure.
+# badTrans - list of transaction numbers not to be assessed as "clean" or
+# "dirty"
+# notPiped - subset of badTrans. List of transaction numbers that cannot
+# taint another transaction by overlapping with it, because it
+# used a different socket.
+#
+# Return value: [list $msg $clean $dirty]
+# msg - warning messages: nothing will be appended to argument $msg if there
+# is an error with the test.
+# clean - list of transactions that have no overlap with other transactions
+# dirty - list of transactions that have YES overlap with other transactions
+
+proc httpTest::TestOverlaps {someResults n term msg badTrans notPiped} {
+ variable testOptions
+
+ # Check whether transactions overlap:
+ set clean {}
+ set dirty {}
+ for {set i 1} {$i <= $n} {incr i} {
+ if {$i in $badTrans} {
+ continue
+ }
+ set myStart [lsearch -exact $someResults [list B $i]]
+ set myEnd [lsearch -exact $someResults [list $term $i]]
+
+ if {($myStart == -1 || $myEnd == -1)} {
+ set res "Cannot find positions of transaction $i"
+ append msg $res \n
+ Puts $res
+ }
+
+ set overlaps {}
+ for {set j $myStart} {$j <= $myEnd} {incr j} {
+ lassign [lindex $someResults $j] letter number
+ if {$number != $i && $letter ne "A" && $number ni $notPiped} {
+ lappend overlaps $number
+ }
+ }
+
+ if {[llength $overlaps] == 0} {
+ set res "Transaction $i has no overlaps"
+ Puts $res
+ lappend clean $i
+ if {$testOptions(-dotted)} {
+ # N.B. results from different segments are concatenated.
+ lappend dirty .
+ } else {
+ }
+ } else {
+ set res "Transaction $i overlaps with [join $overlaps { }]"
+ Puts $res
+ lappend dirty $i
+ if {$testOptions(-dotted)} {
+ # N.B. results from different segments are concatenated.
+ lappend clean .
+ } else {
+ }
+ }
+ }
+ return [list $msg $clean $dirty]
+}
+
+# httpTest::PipelineNext --
+#
+# Test whether prevPair, pair are valid as consecutive elements of a pipelined
+# sequence (Start 1), (End 1), (Start 2), (End 2) ...
+# Numbers are integers increasing (by 1 if argument "any" is false), and need
+# not begin with 1.
+# The first element of the sequence has prevPair {} and is always passed as
+# valid.
+#
+# Arguments;
+# Start - string that labels the start of a segment
+# End - string that labels the end of a segment
+# prevPair - previous "pair" (list of string and number) element of a
+# sequence, or {} if argument "pair" is the first in the
+# sequence.
+# pair - current "pair" (list of string and number) element of a
+# sequence
+# any - (boolean) iff true, accept any increasing sequence of integers.
+# If false, integers must increase by 1.
+#
+# Return value - boolean, true iff the two pairs are valid consecutive elements.
+
+proc httpTest::PipelineNext {Start End prevPair pair any} {
+ if {$prevPair eq {}} {
+ return 1
+ }
+
+ lassign $prevPair letter number
+ lassign $pair newLetter newNumber
+ if {$letter eq $Start} {
+ return [expr {($newLetter eq $End) && ($newNumber == $number)}]
+ } elseif {$any} {
+ set nxt [list $Start [expr {$number + 1}]]
+ return [expr {($newLetter eq $Start) && ($newNumber > $number)}]
+ } else {
+ set nxt [list $Start [expr {$number + 1}]]
+ return [expr {($newLetter eq $Start) && ($newNumber == $number + 1)}]
+ }
+}
+
+# httpTest::TestPipeline --
+#
+# Given a sequence of "pair" elements, check that the elements whose string is
+# $Start or $End form a valid pipeline. Ignore other elements.
+#
+# Return value: {} if valid pipeline, otherwise a non-empty error message.
+
+proc httpTest::TestPipeline {someResults n Start End msg desc badTrans} {
+ set sequence {}
+ set prevPair {}
+ set ok 1
+ set any [llength $badTrans]
+ foreach pair $someResults {
+ lassign $pair letter number
+ if {($letter in [list $Start $End]) && ($number ni $badTrans)} {
+ lappend sequence $pair
+ if {![PipelineNext $Start $End $prevPair $pair $any]} {
+ set ok 0
+ break
+ }
+ set prevPair $pair
+ }
+ }
+
+ if {!$ok} {
+ set res "$desc are not pipelined: {$sequence}"
+ append msg $res \n
+ Puts $res
+ }
+ return $msg
+}
+
+# httpTest::TestSequence --
+#
+# Examine each transaction from 1 to $n, ignoring any that are listed
+# in $badTrans.
+# Check that each transaction has elements A to F, in alphabetical order.
+
+proc httpTest::TestSequence {someResults n msg badTrans} {
+ variable testOptions
+
+ for {set i 1} {$i <= $n} {incr i} {
+ if {$i in $badTrans} {
+ continue
+ }
+ set sequence {}
+ foreach pair $someResults {
+ lassign $pair letter number
+ if {$number == $i} {
+ lappend sequence $letter
+ }
+ }
+ if {$sequence eq {A B C D E F}} {
+ } else {
+ set res "Wrong sequence for token ::http::$i - {$sequence}"
+ append msg $res \n
+ Puts $res
+ if {"X" in $sequence} {
+ set res "- and error(s) X"
+ append msg $res \n
+ Puts $res
+ }
+ if {"Y" in $sequence} {
+ set res "- and warnings(s) Y"
+ append msg $res \n
+ Puts $res
+ }
+ }
+ }
+ return $msg
+}
+
+#
+# Arguments:
+# someResults - list of elements, each a list of a letter and a number
+# n - (positive integer) the number of HTTP requests
+# msg - accumulated warning messages
+# skipOverlaps - (boolean) whether to skip testing of transaction overlaps
+# badTrans - list of transaction numbers not to be assessed as "clean" or
+# "dirty" by their overlaps
+# for 1/2 includes all transactions
+# for 3/4 includes an increasing (with recursion) set that will not be included in the list because they are already handled.
+# notPiped - subset of badTrans. List of transaction numbers that cannot
+# taint another transaction by overlapping with it, because it
+# used a different socket.
+#
+# Return value: [list $msg $cleanE $cleanF $dirtyE $dirtyF]
+# msg - warning messages: nothing will be appended to argument $msg if there
+# is no error with the test.
+# cleanE - list of transactions that have no overlap with other transactions
+# (not considering response body)
+# dirtyE - list of transactions that have YES overlap with other transactions
+# (not considering response body)
+# cleanF - list of transactions that have no overlap with other transactions
+# (including response body)
+# dirtyF - list of transactions that have YES overlap with other transactions
+# (including response body)
+
+proc httpTest::MostAnalysis {someResults n msg skipOverlaps badTrans notPiped} {
+ variable testOptions
+
+ # Check that stages for "good" transactions are all present and correct:
+ set msg [TestSequence $someResults $n $msg $badTrans]
+
+ # Check that requests are pipelined:
+ set msg [TestPipeline $someResults $n B C $msg Requests $notPiped]
+
+ # Check that responses are pipelined:
+ set msg [TestPipeline $someResults $n D F $msg Responses $notPiped]
+
+ if {$skipOverlaps} {
+ set cleanE {}
+ set dirtyE {}
+ set cleanF {}
+ set dirtyF {}
+ } else {
+ Puts "Overlaps including response body (test for non-pipelined case)"
+ lassign [TestOverlaps $someResults $n F $msg $badTrans $notPiped] msg cleanF dirtyF
+
+ Puts "Overlaps without response body (test for pipelined case)"
+ lassign [TestOverlaps $someResults $n E $msg $badTrans $notPiped] msg cleanE dirtyE
+ }
+
+ return [list $msg $cleanE $cleanF $dirtyE $dirtyF]
+}
+
+# httpTest::ProcessRetries --
+#
+# Command to examine results for socket-changing records [PQR],
+# divide the results into segments for each connection, and analyse each segment
+# individually.
+# (Could add $sock to the logging to simplify this, but never mind.)
+#
+# In each segment, identify any transactions that are not included, and
+# any that are aborted, to assist subsequent testing.
+#
+# Prepend A records (socket-independent) to each segment for transactions that
+# were scheduled (by A) but not completed (by F). Pass each segment to
+# MostAnalysis for processing.
+
+proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPiped} {
+ variable testOptions
+
+ set nextRetry [lsearch -glob -index 0 $someResults {[PQR]}]
+ if {$nextRetry == -1} {
+ return [MostAnalysis $someResults $n $msg $skipOverlaps $notIncluded $notPiped]
+ }
+ set badTrans $notIncluded
+ set tryCount 0
+ set try $nextRetry
+ incr tryCount
+ lassign [lindex $someResults $try] letter number
+ Puts "Processing retry [lindex $someResults $try]"
+ set beforeTry [lrange $someResults 0 $try-1]
+ Puts [join $beforeTry \n]
+ set afterTry [lrange $someResults $try+1 end]
+
+ set dummyTry {}
+ for {set i 1} {$i <= $n} {incr i} {
+ set first [lsearch -exact $beforeTry [list A $i]]
+ set last [lsearch -exact $beforeTry [list F $i]]
+ if {$first == -1} {
+ set res "Transaction $i was not started in connection number $tryCount"
+ # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
+ # append msg $res \n
+ Puts $res
+ if {$i ni $badTrans} {
+ lappend badTrans $i
+ } else {
+ }
+ } elseif {$last == -1} {
+ set res "Transaction $i was started but unfinished in connection number $tryCount"
+ # So lappend it to badTrans and don't include it in the call below of MostAnalysis.
+ # append msg $res \n
+ Puts $res
+ lappend badTrans $i
+ lappend dummyTry [list A $i]
+ } else {
+ set res "Transaction $i was started and finished in connection number $tryCount"
+ # So include it in the call below of MostAnalysis.
+ # So lappend it to notIncluded and don't include it in the recursive call of
+ # ProcessRetries which handles the later connections.
+ # append msg $res \n
+ Puts $res
+ lappend notIncluded $i
+ }
+ }
+
+ # Analyse the part of the results before the first replay:
+ set HeadResults [MostAnalysis $beforeTry $n $msg $skipOverlaps $badTrans $notPiped]
+ lassign $HeadResults msg cleanE1 cleanF1 dirtyE1 dirtyF1
+
+ # Pass the rest of the results to be processed recursively.
+ set afterTry [concat $dummyTry $afterTry]
+ set TailResults [ProcessRetries $afterTry $n $msg $skipOverlaps $notIncluded $notPiped]
+ lassign $TailResults msg cleanE2 cleanF2 dirtyE2 dirtyF2
+
+ set cleanE [concat $cleanE1 $cleanE2]
+ set cleanF [concat $cleanF1 $cleanF2]
+ set dirtyE [concat $dirtyE1 $dirtyE2]
+ set dirtyF [concat $dirtyF1 $dirtyF2]
+ return [list $msg $cleanE $cleanF $dirtyE $dirtyF]
+}
+
+# httpTest::logAnalyse --
+#
+# The main command called to analyse logs for a single test.
+#
+# Arguments:
+# n - (positive integer) the number of HTTP requests
+# skipOverlaps - (boolean) whether to skip testing of transaction overlaps
+# notIncluded - list of transaction numbers not to be assessed as "clean" or
+# "dirty" by their overlaps
+# notPiped - subset of notIncluded. List of transaction numbers that cannot
+# taint another transaction by overlapping with it, because it
+# used a different socket.
+#
+# Return value: [list $msg $cleanE $cleanF $dirtyE $dirtyF]
+# msg - warning messages: {} if there is no error with the test.
+# cleanE - list of transactions that have no overlap with other transactions
+# (not considering response body)
+# dirtyE - list of transactions that have YES overlap with other transactions
+# (not considering response body)
+# cleanF - list of transactions that have no overlap with other transactions
+# (including response body)
+# dirtyF - list of transactions that have YES overlap with other transactions
+# (including response body)
+
+proc httpTest::logAnalyse {n skipOverlaps notIncluded notPiped} {
+ variable testResults
+ variable testOptions
+
+ # Check that each data item has the correct form {letter numeral}.
+ set ii 0
+ set ok 1
+ foreach pair $testResults {
+ lassign $pair letter number
+ if { [string match {[A-Z]} $letter]
+ && [string match {[0-9]} $number]
+ } {
+ # OK
+ } else {
+ set ok 0
+ set res "Error: testResults has bad element {$pair} at position $ii"
+ append msg $res \n
+ Puts $res
+ }
+ incr ii
+ }
+
+ if {!$ok} {
+ return $msg
+ }
+ set msg {}
+
+ Puts [join $testResults \n]
+ ProcessRetries $testResults $n $msg $skipOverlaps $notIncluded $notPiped
+ # N.B. Implicit Return.
+}
+
+proc httpTest::cleanupHttpTest {} {
+ variable testResults
+ set testResults {}
+ return
+}
+
+proc httpTest::setHttpTestOptions {key args} {
+ variable testOptions
+ if {$key ni {-dotted -verbose}} {
+ return -code error {valid options are -dotted, -verbose}
+ }
+ set testOptions($key) {*}$args
+}
+
+namespace eval httpTest {
+ namespace export cleanupHttpTest logAnalyse setHttpTestOptions
+}
diff --git a/tcl8.6/tests/httpTestScript.tcl b/tcl8.6/tests/httpTestScript.tcl
new file mode 100644
index 0000000..a40449a
--- /dev/null
+++ b/tcl8.6/tests/httpTestScript.tcl
@@ -0,0 +1,509 @@
+# httpTestScript.tcl
+#
+# Test HTTP/1.1 concurrent requests including
+# queueing, pipelining and retries.
+#
+# Copyright (C) 2018 Keith Nash <kjnash@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# ------------------------------------------------------------------------------
+# "Package" httpTestScript for executing test scripts written in a convenient
+# shorthand.
+# ------------------------------------------------------------------------------
+
+# ------------------------------------------------------------------------------
+# Documentation for "package" httpTestScript.
+# ------------------------------------------------------------------------------
+# To use the package:
+# (a) define URLs as the values of elements in the array ::httpTestScript
+# (b) define a script in terms of the commands
+# START STOP DELAY KEEPALIVE WAIT PIPELINE GET HEAD POST
+# referring to URLs by the name of the corresponding array element. The
+# script can include any other Tcl commands, and evaluates in the
+# httpTestScript namespace.
+# (c) Use the command httpTestScript::runHttpTestScript to evaluate the script.
+# (d) For tcltest tests, wrap the runHttpTestScript call in a suitable "test"
+# command.
+# ------------------------------------------------------------------------------
+# START
+# Must be the first command of the script.
+#
+# STOP
+# Must be present in the script to avoid waiting for client timeout.
+# Usually the last command, but can be elsewhere to end a script prematurely.
+# Subsequent httpTestScript commands will have no effect.
+#
+# DELAY ms
+# If there are no WAIT commands, this sets the delay in ms between subsequent
+# calls to http::geturl. Default 500ms.
+#
+# KEEPALIVE
+# Set the value passed to http::geturl for the -keepalive option. The command
+# applies to subsequent requests in the script. Default 1.
+#
+# WAIT ms
+# Pause for a time in ms before sending subsequent requests.
+#
+# PIPELINE boolean
+# Set the value of -pipeline using http::config. The last PIPELINE command
+# in the script applies to every request. Default 1.
+#
+# POSTFRESH boolean
+# Set the value of -postfresh using http::config. The last POSTFRESH command
+# in the script applies to every request. Default 0.
+#
+# REPOST boolean
+# Set the value of -repost using http::config. The last REPOST command
+# in the script applies to every request. Default 1 for httpTestScript.
+# (Default value in http is 0).
+#
+# GET uriCode ?arg ...?
+# Send a HTTP request using the GET method.
+# Arguments:
+# uriCode - the code for the base URI - the value must be stored in
+# ::httpTestScript::URL($uriCode).
+# args - strings that will be joined by "&" and appended to the query
+# string with a preceding "&".
+#
+# HEAD uriCode ?arg ...?
+# Send a HTTP request using the HEAD method.
+# Arguments: as for GET
+#
+# POST uriCode ?arg ...?
+# Send a HTTP request using the POST method.
+# Arguments:
+# uriCode - the code for the base URI - the value must be stored in
+# ::httpTestScript::URL($uriCode).
+# args - strings that will be joined by "&" and used as the request body.
+# ------------------------------------------------------------------------------
+
+namespace eval ::httpTestScript {
+ namespace export runHttpTestScript cleanupHttpTestScript
+}
+
+# httpTestScript::START --
+# Initialise, and create a long-stop timeout.
+
+proc httpTestScript::START {} {
+ variable CountRequestedSoFar
+ variable RequestsWhenStopped
+ variable KeepAlive
+ variable Delay
+ variable TimeOutCode
+ variable TimeOutDone
+ variable StartDone
+ variable StopDone
+ variable CountFinishedSoFar
+ variable RequestList
+ variable RequestsMade
+ variable ExtraTime
+ variable ActualKeepAlive
+
+ if {[info exists StartDone] && ($StartDone == 1)} {
+ set msg {START has been called twice without an intervening STOP}
+ return -code error $msg
+ }
+
+ set StartDone 1
+ set StopDone 0
+ set TimeOutDone 0
+ set CountFinishedSoFar 0
+ set CountRequestedSoFar 0
+ set RequestList {}
+ set RequestsMade {}
+ set ExtraTime 0
+ set ActualKeepAlive 1
+
+ # Undefined until a STOP command:
+ unset -nocomplain RequestsWhenStopped
+
+ # Default values:
+ set KeepAlive 1
+ set Delay 500
+
+ # Default values for tests:
+ KEEPALIVE 1
+ PIPELINE 1
+ POSTFRESH 0
+ REPOST 1
+
+ set TimeOutCode [after 30000 httpTestScript::TimeOutNow]
+# set TimeOutCode [after 4000 httpTestScript::TimeOutNow]
+ return
+}
+
+# httpTestScript::STOP --
+# Do not process any more commands. The commands will be executed but will
+# silently do nothing.
+
+proc httpTestScript::STOP {} {
+ variable CountRequestedSoFar
+ variable CountFinishedSoFar
+ variable RequestsWhenStopped
+ variable TimeOutCode
+ variable StartDone
+ variable StopDone
+ variable RequestsMade
+
+ if {$StopDone} {
+ # Don't do anything on a second call.
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ set StopDone 1
+ set StartDone 0
+ set RequestsWhenStopped $CountRequestedSoFar
+ unset -nocomplain StartDone
+
+ if {$CountFinishedSoFar == $RequestsWhenStopped} {
+ if {[info exists TimeOutCode]} {
+ after cancel $TimeOutCode
+ }
+ set ::httpTestScript::FOREVER 0
+ }
+ return
+}
+
+# httpTestScript::DELAY --
+# If there are no WAIT commands, this sets the delay in ms between subsequent
+# calls to http::geturl. Default 500ms.
+
+proc httpTestScript::DELAY {t} {
+ variable StartDone
+ variable StopDone
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ variable Delay
+
+ set Delay $t
+ return
+}
+
+# httpTestScript::KEEPALIVE --
+# Set the value passed to http::geturl for the -keepalive option. Default 1.
+
+proc httpTestScript::KEEPALIVE {b} {
+ variable StartDone
+ variable StopDone
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ variable KeepAlive
+ set KeepAlive $b
+ return
+}
+
+# httpTestScript::WAIT --
+# Pause for a time in ms before processing any more commands.
+
+proc httpTestScript::WAIT {t} {
+ variable StartDone
+ variable StopDone
+ variable ExtraTime
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ if {(![string is integer -strict $t]) || $t < 0} {
+ return -code error {argument to WAIT must be a non-negative integer}
+ }
+
+ incr ExtraTime $t
+
+ return
+}
+
+# httpTestScript::PIPELINE --
+# Pass a value to http::config -pipeline.
+
+proc httpTestScript::PIPELINE {b} {
+ variable StartDone
+ variable StopDone
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ ::http::config -pipeline $b
+ ##::http::Log http(-pipeline) is now [::http::config -pipeline]
+ return
+}
+
+# httpTestScript::POSTFRESH --
+# Pass a value to http::config -postfresh.
+
+proc httpTestScript::POSTFRESH {b} {
+ variable StartDone
+ variable StopDone
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ ::http::config -postfresh $b
+ ##::http::Log http(-postfresh) is now [::http::config -postfresh]
+ return
+}
+
+# httpTestScript::REPOST --
+# Pass a value to http::config -repost.
+
+proc httpTestScript::REPOST {b} {
+ variable StartDone
+ variable StopDone
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ ::http::config -repost $b
+ ##::http::Log http(-repost) is now [::http::config -repost]
+ return
+}
+
+# httpTestScript::GET --
+# Send a HTTP request using the GET method.
+# Arguments:
+# uriCode - the code for the base URI - the value must be stored in
+# ::httpTestScript::URL($uriCode).
+# args - strings that will each be preceded by "&" and appended to the query
+# string.
+
+proc httpTestScript::GET {uriCode args} {
+ variable RequestList
+ lappend RequestList GET
+ RequestAfter $uriCode 0 {} {*}$args
+ return
+}
+
+# httpTestScript::HEAD --
+# Send a HTTP request using the HEAD method.
+# Arguments: as for GET
+
+proc httpTestScript::HEAD {uriCode args} {
+ variable RequestList
+ lappend RequestList HEAD
+ RequestAfter $uriCode 1 {} {*}$args
+ return
+}
+
+# httpTestScript::POST --
+# Send a HTTP request using the POST method.
+# Arguments:
+# uriCode - the code for the base URI - the value must be stored in
+# ::httpTestScript::URL($uriCode).
+# args - strings that will be joined by "&" and used as the request body.
+
+proc httpTestScript::POST {uriCode args} {
+ variable RequestList
+ lappend RequestList POST
+ RequestAfter $uriCode 0 {use} {*}$args
+ return
+}
+
+
+proc httpTestScript::RequestAfter {uriCode validate query args} {
+ variable CountRequestedSoFar
+ variable Delay
+ variable ExtraTime
+ variable StartDone
+ variable StopDone
+ variable KeepAlive
+
+ if {$StopDone} {
+ return
+ }
+
+ if {![info exists StartDone]} {
+ return -code error {initialise the script by calling command START}
+ }
+
+ incr CountRequestedSoFar
+ set idelay [expr {($CountRequestedSoFar - 1) * $Delay + 10 + $ExtraTime}]
+
+ # Could pass values of -pipeline, -postfresh, -repost if it were
+ # useful to change these mid-script.
+ after $idelay [list httpTestScript::Requester $uriCode $KeepAlive $validate $query {*}$args]
+ return
+}
+
+proc httpTestScript::Requester {uriCode keepAlive validate query args} {
+ variable URL
+
+ ::http::config -accept {*/*}
+
+ set absUrl $URL($uriCode)
+ if {$query eq {}} {
+ if {$args ne {}} {
+ append absUrl & [join $args &]
+ }
+ set queryArgs {}
+ } elseif {$validate} {
+ return -code error {cannot have both -validate (HEAD) and -query (POST)}
+ } else {
+ set queryArgs [list -query [join $args &]]
+ }
+
+ if {[catch {
+ ::http::geturl $absUrl \
+ -validate $validate \
+ -timeout 10000 \
+ {*}$queryArgs \
+ -keepalive $keepAlive \
+ -command ::httpTestScript::WhenFinished
+ } token]} {
+ set msg $token
+ catch {puts stdout "Error: $msg"}
+ return
+ } else {
+ # Request will begin.
+ }
+
+ return
+
+}
+
+proc httpTestScript::TimeOutNow {} {
+ variable TimeOutDone
+
+ set TimeOutDone 1
+ set ::httpTestScript::FOREVER 0
+ return
+}
+
+proc httpTestScript::WhenFinished {hToken} {
+ variable CountFinishedSoFar
+ variable RequestsWhenStopped
+ variable TimeOutCode
+ variable StopDone
+ variable RequestList
+ variable RequestsMade
+ variable ActualKeepAlive
+
+ upvar #0 $hToken state
+
+ if {[catch {
+ if { [info exists state(transfer)]
+ && ($state(transfer) eq "chunked")
+ } {
+ set Trans chunked
+ } else {
+ set Trans unchunked
+ }
+
+ if { [info exists ::httpTest::testOptions(-verbose)]
+ && ($::httpTest::testOptions(-verbose) > 0)
+ } {
+ puts "Token $hToken
+Response $state(http)
+Status $state(status)
+Method $state(method)
+Transfer $Trans
+Size $state(currentsize)
+URL $state(url)
+"
+ }
+
+ if {!$state(-keepalive)} {
+ set ActualKeepAlive 0
+ }
+
+ if {[info exists state(method)]} {
+ lappend RequestsMade $state(method)
+ } else {
+ lappend RequestsMade UNKNOWN
+ }
+ set tk [namespace tail $hToken]
+
+ if { ($state(http) != {HTTP/1.1 200 OK})
+ || ($state(status) != {ok})
+ || (($state(currentsize) == 0) && ($state(method) ne "HEAD"))
+ } {
+ ::http::Log ^X$tk unexpected result Response $state(http) Status $state(status) Size $state(currentsize) - token $hToken
+ }
+ } err]} {
+ ::http::Log ^X$tk httpTestScript::WhenFinished failed with error status: $err - token $hToken
+ }
+
+ incr CountFinishedSoFar
+ if {$StopDone && ($CountFinishedSoFar == $RequestsWhenStopped)} {
+ if {[info exists TimeOutCode]} {
+ after cancel $TimeOutCode
+ }
+ if {$RequestsMade ne $RequestList && $ActualKeepAlive} {
+ ::http::Log ^X$tk unexpected result - Script asked for "{$RequestList}" but got "{$RequestsMade}" - token $hToken
+ }
+ set ::httpTestScript::FOREVER 0
+ }
+
+ return
+}
+
+
+proc httpTestScript::runHttpTestScript {scr} {
+ variable TimeOutDone
+ variable RequestsWhenStopped
+
+ after idle [list namespace eval ::httpTestScript $scr]
+ vwait ::httpTestScript::FOREVER
+ # N.B. does not automatically execute in this namespace, unlike some other events.
+ # Release when all requests have been served or have timed out.
+
+ if {$TimeOutDone} {
+ return -code error {test script timed out}
+ }
+
+ return $RequestsWhenStopped
+}
+
+
+proc httpTestScript::cleanupHttpTestScript {} {
+ variable TimeOutDone
+ variable RequestsWhenStopped
+
+ if {![info exists RequestsWhenStopped]} {
+ return -code error {Cleanup Failed: RequestsWhenStopped is undefined}
+ }
+
+ for {set i 1} {$i <= $RequestsWhenStopped} {incr i} {
+ http::cleanup ::http::$i
+ }
+
+ return
+}
diff --git a/tcl8.6/tests/info.test b/tcl8.6/tests/info.test
index 42f5a96..1b52cf5 100644
--- a/tcl8.6/tests/info.test
+++ b/tcl8.6/tests/info.test
@@ -2398,7 +2398,7 @@ test info-33.35 {{*}, literal, simple, bytecompiled} -body {
# -------------------------------------------------------------------------
unset -nocomplain res
-test info-39.1 {Bug 4b61afd660} -setup {
+test info-39.2 {Bug 4b61afd660} -setup {
proc probe {} {
return [dict get [info frame -1] line]
}
diff --git a/tcl8.6/tests/io.test b/tcl8.6/tests/io.test
index 197fc36..996e125 100644
--- a/tcl8.6/tests/io.test
+++ b/tcl8.6/tests/io.test
@@ -15,14 +15,8 @@
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
- namespace import -force ::tcltest::*
}
-::tcltest::loadTestedCommands
-catch [list package require -exact Tcltest [info patchlevel]]
-
-testConstraint testbytestring [llength [info commands testbytestring]]
-
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
@@ -35,15 +29,16 @@ namespace eval ::tcl::test::io {
variable msg
variable expected
+ loadTestedCommands
+ catch [list package require -exact Tcltest [info patchlevel]]
+ package require tcltests
+
+testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint exec [llength [info commands exec]]
testConstraint openpipe 1
-testConstraint fileevent [llength [info commands fileevent]]
-testConstraint fcopy [llength [info commands fcopy]]
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
@@ -6163,6 +6158,8 @@ test io-47.6 {file events on shared files, deleting file events} {testfevent fil
close $f
set x
} {{script 1} {}}
+unset path(foo)
+removeFile foo
set path(bar) [makeFile {} bar]
@@ -6265,6 +6262,9 @@ test io-48.3 {testing readability conditions} {stdio unix nonBlockFiles openpipe
close $f
list $x $l
} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+unset path(bar)
+removeFile bar
+
test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {fileevent} {
file delete $path(test1)
set f [open $path(test1) w]
diff --git a/tcl8.6/tests/ioCmd.test b/tcl8.6/tests/ioCmd.test
index cd89a02..948671e 100644
--- a/tcl8.6/tests/ioCmd.test
+++ b/tcl8.6/tests/ioCmd.test
@@ -21,10 +21,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
::tcltest::loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
+package require tcltests
+
# Custom constraints used in this file
-testConstraint fcopy [llength [info commands fcopy]]
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
#----------------------------------------------------------------------
@@ -384,7 +384,6 @@ test iocmd-10.5 {fblocked command} {
set path(test4) [makeFile {} test4]
set path(test5) [makeFile {} test5]
-file delete $path(test5)
test iocmd-11.1 {I/O to command pipelines} {unixOrPc unixExecs} {
set f [open $path(test4) w]
close $f
@@ -396,7 +395,7 @@ test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
-test iocmd-11.4 {I/O to command pipelines} unixOrPc {
+test iocmd-11.4 {I/O to command pipelines} {notValgrind unixOrPc} {
list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
@@ -2058,6 +2057,8 @@ test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body {
lappend res [catch {interp eval $idb [list close $chan]} msg] $msg
set res
+} -cleanup {
+ interp delete $idb
} -constraints {testchannel} \
-result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
@@ -2100,6 +2101,8 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m
set res
}]
set res
+} -cleanup {
+ interp delete $idb
} -constraints {testchannel} -result {Owner lost}
test iocmd-32.2 {delete interp of reflected chan} {
@@ -3778,7 +3781,6 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
# Use constraints to skip this test while valgrinding so this expected leak
# doesn't prevent a finding of "leak-free".
#
-testConstraint notValgrind [expr {![testConstraint valgrind]}]
test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
#puts <<$tcltest::mainThread>>main
@@ -3831,13 +3833,21 @@ test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -mat
rename track {}
# cleanup
+
+
+# Eliminate valgrind "still reachable" reports on outstanding "Detached"
+# structures in the detached list which stem from PipeClose2Proc not waiting
+# around for background processes to complete, meaning that previous calls to
+# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
+after 10
+exec [info nameofexecutable] << {}
+
+
foreach file [list test1 test2 test3 test4] {
removeFile $file
}
# delay long enough for background processes to finish
after 500
-foreach file [list test5] {
- removeFile $file
-}
+removeFile test5
cleanupTests
return
diff --git a/tcl8.6/tests/ioTrans.test b/tcl8.6/tests/ioTrans.test
index e179eab..85e427a 100644
--- a/tcl8.6/tests/ioTrans.test
+++ b/tcl8.6/tests/ioTrans.test
@@ -1200,6 +1200,7 @@ test iortrans-11.0 {origin interpreter of moved transform gone} -setup {
# without invoking the transform handler.
} -cleanup {
tempdone
+ interp delete $idb
} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
test iortrans-11.1 {origin interpreter of moved transform destroyed during access} -setup {
set ida [interp create]; #puts <<$ida>>
@@ -1239,6 +1240,7 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces
set res
}]
} -cleanup {
+ interp delete $idb
tempdone
} -result {Owner lost}
test iortrans-11.2 {delete interp of reflected transform} -setup {
diff --git a/tcl8.6/tests/iogt.test b/tcl8.6/tests/iogt.test
index 1ed89f7..269a0ba 100644
--- a/tcl8.6/tests/iogt.test
+++ b/tcl8.6/tests/iogt.test
@@ -608,7 +608,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
variable copy 1
}
} -constraints {testchannel knownBug} -body {
- # This test to check the validity of aquired Tcl_Channel references is not
+ # This test to check the validity of acquired Tcl_Channel references is not
# possible because even a backgrounded fcopy will immediately start to
# copy data, without waiting for the event loop. This is done only in case
# of an underflow on the read size!. So stacking transforms after the
diff --git a/tcl8.6/tests/join.test b/tcl8.6/tests/join.test
index 4abe233..4aeb093 100644
--- a/tcl8.6/tests/join.test
+++ b/tcl8.6/tests/join.test
@@ -45,6 +45,11 @@ test join-3.1 {joinString is binary ok} {
test join-3.2 {join is binary ok} {
string length [join "a\0b a\0b a\0b"]
} 11
+
+test join-4.1 {shimmer segfault prevention} {
+ set l {0 0}
+ join $l $l
+} {00 00}
# cleanup
::tcltest::cleanupTests
diff --git a/tcl8.6/tests/lindex.test b/tcl8.6/tests/lindex.test
index b86e2e0..e513b62 100644
--- a/tcl8.6/tests/lindex.test
+++ b/tcl8.6/tests/lindex.test
@@ -79,6 +79,15 @@ test lindex-3.7 {indexes don't shimmer wide ints} {
set x [expr {(wide(1)<<31) - 2}]
list $x [lindex {1 2 3} $x] [incr x] [incr x]
} {2147483646 {} 2147483647 2147483648}
+test lindex-3.8 {compiled with static indices out of range, negative} {
+ list [lindex {a b c} -1] [lindex {a b c} -2] [lindex {a b c} -3]
+} [lrepeat 3 {}]
+test lindex-3.9 {compiled with calculated indices out of range, negative constant} {
+ list [lindex {a b c} -1-1] [lindex {a b c} -2+0] [lindex {a b c} -2+1]
+} [lrepeat 3 {}]
+test lindex-3.10 {compiled with calculated indices out of range, after end} {
+ list [lindex {a b c} end+1] [lindex {a b c} end+2] [lindex {a b c} end+3]
+} [lrepeat 3 {}]
# Indices relative to end
diff --git a/tcl8.6/tests/list.test b/tcl8.6/tests/list.test
index dff5d50..2686bd7 100644
--- a/tcl8.6/tests/list.test
+++ b/tcl8.6/tests/list.test
@@ -128,6 +128,24 @@ test list-3.1 {SetListFromAny and lrange/concat results} {
test list-4.1 {Bug 3173086} {
string is list "{[list \\\\\}]}"
} 1
+test list-4.2 {Bug 35a8f1c04a, check correct str-rep} {
+ set result {}
+ foreach i {
+ {#"} {#"""} {#"""""""""""""""}
+ "#\"{" "#\"\"\"{" "#\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\{"
+ "#\"}" "#\"\"\"}" "#\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\}"
+ } {
+ set list [list $i]
+ set list [string trim " $list "]
+ if {[llength $list] > 1 || $i ne [lindex $list 0]} {
+ lappend result "wrong string-representation of list by '$i', length: [llength $list], list: '$list'"
+ }
+ }
+ set result [join $result \n]
+} {}
+test list-4.3 {Bug 35a8f1c04a, check correct string length} {
+ string length [list #""]
+} 5
# cleanup
::tcltest::cleanupTests
diff --git a/tcl8.6/tests/lrange.test b/tcl8.6/tests/lrange.test
index 17a757e..ba10354 100644
--- a/tcl8.6/tests/lrange.test
+++ b/tcl8.6/tests/lrange.test
@@ -90,6 +90,24 @@ test lrange-3.1 {Bug 3588366: end-offsets before start} {
lrange $l 0 end-5
}} {1 2 3 4 5}
} {}
+
+test lrange-3.2 {compiled with static indices out of range, negative} {
+ list [lrange {a b c} -1 -2] [lrange {a b c} -2 -1] [lrange {a b c} -3 -2] [lrange {a b c} -2 -3]
+} [lrepeat 4 {}]
+test lrange-3.3 {compiled with calculated indices out of range, negative constant} {
+ list [lrange {a b c} 0-1 -1-1] [lrange {a b c} -2+0 0-1] [lrange {a b c} -2-1 -2+1] [lrange {a b c} -2+1 -2-1]
+} [lrepeat 4 {}]
+test lrange-3.4 {compiled with calculated indices out of range, after end} {
+ list [lrange {a b c} end+1 end+2] [lrange {a b c} end+2 end+1] [lrange {a b c} end+2 end+3] [lrange {a b c} end+3 end+2]
+} [lrepeat 4 {}]
+
+test lrange-3.5 {compiled with calculated indices, start out of range (negative)} {
+ list [lrange {a b c} -1 1] [lrange {a b c} -1+0 end-1] [lrange {a b c} -2 1] [lrange {a b c} -2+0 0+1]
+} [lrepeat 4 {a b}]
+test lrange-3.6 {compiled with calculated indices, end out of range (after end)} {
+ list [lrange {a b c} 1 end+1] [lrange {a b c} 1+0 2+1] [lrange {a b c} 1 end+1] [lrange {a b c} end-1 3+1]
+} [lrepeat 4 {b c}]
+
# cleanup
::tcltest::cleanupTests
diff --git a/tcl8.6/tests/lreplace.test b/tcl8.6/tests/lreplace.test
index d7f8226..fd2f7f8 100644
--- a/tcl8.6/tests/lreplace.test
+++ b/tcl8.6/tests/lreplace.test
@@ -98,12 +98,18 @@ 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} {
+test lreplace-1.27 {lreplace command} -body {
lreplace x 1 1
-} x
-test lreplace-1.28 {lreplace command} {
+} -result x
+test lreplace-1.28 {lreplace command} -body {
lreplace x 1 1 y
-} {x y}
+} -result {x y}
+test lreplace-1.29 {lreplace command} -body {
+ lreplace x 1 1 [error foo]
+} -returnCodes 1 -result {foo}
+test lreplace-1.30 {lreplace command} -body {
+ lreplace {not {}alist} 0 0 [error foo]
+} -returnCodes 1 -result {foo}
test lreplace-2.1 {lreplace errors} {
list [catch lreplace msg] $msg
@@ -122,10 +128,10 @@ test lreplace-2.5 {lreplace errors} {
} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
test lreplace-2.6 {lreplace errors} {
list [catch {lreplace x 3 2} msg] $msg
-} {1 {list doesn't contain element 3}}
+} {0 x}
test lreplace-2.7 {lreplace errors} {
list [catch {lreplace x 2 2} msg] $msg
-} {1 {list doesn't contain element 2}}
+} {0 x}
test lreplace-3.1 {lreplace won't modify shared argument objects} {
proc p {} {
diff --git a/tcl8.6/tests/lsearch.test b/tcl8.6/tests/lsearch.test
index f36e987..5e8a1f8 100644
--- a/tcl8.6/tests/lsearch.test
+++ b/tcl8.6/tests/lsearch.test
@@ -418,6 +418,34 @@ test lsearch-17.6 {lsearch -index option, basic functionality} {
test lsearch-17.7 {lsearch -index option, basic functionality} {
lsearch -all -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
} {0 1}
+test lsearch-17.8 {lsearch -index option, empty argument} {
+ lsearch -index {} a a
+} 0
+test lsearch-17.9 {lsearch -index option, empty argument} {
+ lsearch -index {} a a
+} [lsearch a a]
+test lsearch-17.10 {lsearch -index option, empty argument} {
+ lsearch -index {} [list \{] \{
+} 0
+test lsearch-17.11 {lsearch -index option, empty argument} {
+ lsearch -index {} [list \{] \{
+} [lsearch [list \{] \{]
+test lsearch-17.12 {lsearch -index option, encoding aliasing} -body {
+ lsearch -index -2 a a
+} -returnCodes error -result {index "-2" cannot select an element from any list}
+test lsearch-17.13 {lsearch -index option, encoding aliasing} -body {
+ lsearch -index -1-1 a a
+} -returnCodes error -result {index "-1-1" cannot select an element from any list}
+test lsearch-17.14 {lsearch -index option, encoding aliasing} -body {
+ lsearch -index end--1 a a
+} -returnCodes error -result {index "end--1" cannot select an element from any list}
+test lsearch-17.15 {lsearch -index option, encoding aliasing} -body {
+ lsearch -index end+1 a a
+} -returnCodes error -result {index "end+1" cannot select an element from any list}
+test lsearch-17.16 {lsearch -index option, encoding aliasing} -body {
+ lsearch -index end+2 a a
+} -returnCodes error -result {index "end+2" cannot select an element from any list}
+
test lsearch-18.1 {lsearch -index option, list as index basic functionality} {
lsearch -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
@@ -435,21 +463,27 @@ test lsearch-18.5 {lsearch -index option, list as index basic functionality} {
lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
} {0 1}
-test lsearch-19.1 {lsearch -sunindices option} {
+test lsearch-19.1 {lsearch -subindices option} {
lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
} {1 0 0}
-test lsearch-19.2 {lsearch -sunindices option} {
+test lsearch-19.2 {lsearch -subindices option} {
lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
} {0 2 0}
-test lsearch-19.3 {lsearch -sunindices option} {
+test lsearch-19.3 {lsearch -subindices option} {
lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b*
} {0 1 1}
-test lsearch-19.4 {lsearch -sunindices option} {
+test lsearch-19.4 {lsearch -subindices option} {
lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
} {0 0 1}
-test lsearch-19.5 {lsearch -sunindices option} {
+test lsearch-19.5 {lsearch -subindices option} {
lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
} {{0 0 0} {1 0 0}}
+test lsearch-19.7 {lsearch -subindices option} {
+ lsearch -subindices -index end {{1 a}} a
+} {0 1}
+test lsearch-19.8 {lsearch -subindices option} {
+ lsearch -subindices -all -index end {{1 a}} a
+} {{0 1}}
test lsearch-20.1 {lsearch -index option, index larger than sublists} -body {
lsearch -index 2 {{a c} {a b} {a a}} a
diff --git a/tcl8.6/tests/macOSXFCmd.test b/tcl8.6/tests/macOSXFCmd.test
index 071f11b..f1758f5 100644
--- a/tcl8.6/tests/macOSXFCmd.test
+++ b/tcl8.6/tests/macOSXFCmd.test
@@ -99,7 +99,7 @@ test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} {
[catch {file attributes foo.test -hidden} msg] $msg \
[file delete -force -- foo.test]
} {0 {} 0 1 {}}
-test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot nonPortable} {
catch {file delete -force -- foo.test}
close [open foo.test w]
catch {
@@ -151,16 +151,16 @@ test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} {
file attributes dir.test -hidden 1
}
set res [list \
- [catch {glob *.test} msg] $msg \
- [catch {glob -types FOOT *.test} msg] $msg \
- [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \
- [catch {glob -types FOOTT *.test} msg] $msg \
- [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \
- [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \
- [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \
- [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \
- [catch {glob -types hidden *.test} msg] $msg \
- [catch {glob -types {hidden FOOT} *.test} msg] $msg \
+ [catch {lsort [glob *.test]} msg] $msg \
+ [catch {lsort [glob -types FOOT *.test]} msg] $msg \
+ [catch {lsort [glob -types {{macintosh type FOOT}} *.test]} msg] $msg \
+ [catch {lsort [glob -types FOOTT *.test]} msg] $msg \
+ [catch {lsort [glob -types {{macintosh type FOOTT}} *.test]} msg] $msg \
+ [catch {lsort [glob -types {{macintosh type {}}} *.test]} msg] $msg \
+ [catch {lsort [glob -types {{macintosh creator FOOC}} *.test]} msg] $msg \
+ [catch {lsort [glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test]} msg] $msg \
+ [catch {lsort [glob -types hidden *.test]} msg] $msg \
+ [catch {lsort [glob -types {hidden FOOT} *.test]} msg] $msg \
]
cd ..
file delete -force globtest
diff --git a/tcl8.6/tests/main.test b/tcl8.6/tests/main.test
index 351fd4f..b0edb84 100644
--- a/tcl8.6/tests/main.test
+++ b/tcl8.6/tests/main.test
@@ -1210,8 +1210,6 @@ namespace eval ::tcl::test::main {
Bug 1775878
} -constraints {
exec Tcltest
- } -setup {
- catch {set f [open "|[list [interpreter]]" w+]}
} -body {
exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
set f [open result]
diff --git a/tcl8.6/tests/namespace.test b/tcl8.6/tests/namespace.test
index ff8cd7d..1d26512 100644
--- a/tcl8.6/tests/namespace.test
+++ b/tcl8.6/tests/namespace.test
@@ -196,6 +196,19 @@ test namespace-7.7 {Bug 1655305} -setup {
interp delete slave
} -result {}
+test namespace-7.8 {Bug ba1419303b4c} -setup {
+ namespace eval ns1 {
+ namespace ensemble create
+ }
+
+ trace add command ns1 delete {
+ namespace delete ns1
+ }
+} -body {
+ # No segmentation fault given --enable-symbols=mem.
+ namespace delete ns1
+} -result {}
+
test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
catch {interp delete test_interp}
interp create test_interp
@@ -1784,7 +1797,7 @@ test namespace-42.7 {ensembles: nested} -body {
list [ns x0 z] [ns x1] [ns x2] [ns x3]
} -cleanup {
namespace delete ns
-} -result {{1 ::ns::x0::z} 1 2 3}
+} -result {{1 z} 1 2 3}
test namespace-42.8 {
ensembles: [Bug 1670091], panic due to pointer to a deallocated List
struct.
@@ -1951,7 +1964,7 @@ test namespace-44.5 {ensemble: errors} -setup {
foobar foobarcon
} -cleanup {
rename foobar {}
-} -returnCodes error -result {invalid command name "::foobarconfigure"}
+} -returnCodes error -result {invalid command name "foobarconfigure"}
test namespace-44.6 {ensemble: errors} -returnCodes error -body {
namespace ensemble create gorp
} -result {wrong # args: should be "namespace ensemble create ?option value ...?"}
@@ -2115,7 +2128,7 @@ test namespace-47.1 {ensemble: unknown handler} {
lappend result [catch {ns c d e} msg] $msg
lappend result [catch {ns Magic foo bar spong wibble} msg] $msg
list $result [lsort [info commands ::ns::*]] $log [namespace delete ns]
-} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running ::ns::a b c} {running ::ns::a b c} {making b} {running ::ns::b c d} {making c} {running ::ns::c d e} {unknown Magic - args = foo bar spong wibble}} {}}
+} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running a b c} {running a b c} {making b} {running b c d} {making c} {running c d e} {unknown Magic - args = foo bar spong wibble}} {}}
test namespace-47.2 {ensemble: unknown handler} {
namespace eval ns {
namespace export {[a-z]*}
@@ -3214,7 +3227,7 @@ test namespace-53.10 {ensembles: nested rewrite} -setup {
1 {wrong # args: should be "ns z1 x a1"}\
1 {wrong # args: should be "ns z2 x a1 a2"}\
1 {wrong # args: should be "ns z2 x a1 a2"}\
- 1 {wrong # args: should be "::ns::x::z0"}\
+ 1 {wrong # args: should be "z0"}\
0 {1 v}\
1 {wrong # args: should be "ns v x z2 a2"}\
0 {2 v v2}}
@@ -3298,6 +3311,18 @@ test namespace-56.3 {bug f97d4ee020: mutually-entangled deletion} {
}
}
} {::testing::abc::def ::testing::abc::ghi}
+
+test namespace-56.4 {bug 16fe1b5807: names starting with ":"} {
+namespace eval : {
+ namespace ensemble create
+ namespace export *
+ proc p1 {} {
+ return 16fe1b5807
+ }
+}
+
+: p1
+} 16fe1b5807
# cleanup
catch {rename cmd1 {}}
diff --git a/tcl8.6/tests/oo.test b/tcl8.6/tests/oo.test
index 61a5e01..db5c14f 100644
--- a/tcl8.6/tests/oo.test
+++ b/tcl8.6/tests/oo.test
@@ -13,6 +13,13 @@ if {"::tcltest" in [namespace children]} {
namespace import -force ::tcltest::*
}
+
+# The foundational objects oo::object and oo::class are sensitive to reference
+# counting errors and are deallocated only when an interp is deleted, so in
+# this test suite, interp creation and interp deletion are often used in
+# leaktests in order to leverage this sensitivity.
+
+
testConstraint memory [llength [info commands memory]]
if {[testConstraint memory]} {
proc getbytes {} {
@@ -47,7 +54,7 @@ test oo-0.2 {basic test of OO's ability to clean up its initial state} {
} {}
test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
leaktest {
- [oo::object new] destroy
+ [oo::object new] destroy
}
} -constraints memory -result 0
test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
@@ -57,7 +64,13 @@ test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
foo destroy
}
} -constraints memory -result 0
-test oo-0.5 {testing literal leak on interp delete} memory {
+test oo-0.5.1 {testing object foundation cleanup} memory {
+ leaktest {
+ interp create foo
+ interp delete foo
+ }
+} 0
+test oo-0.5.2 {testing literal leak on interp delete} memory {
leaktest {
interp create foo
foo eval {oo::object new}
@@ -128,6 +141,13 @@ test oo-1.3 {basic test of OO functionality: no classes} {
test oo-1.4 {basic test of OO functionality} -body {
oo::object create {}
} -returnCodes 1 -result {object name must not be empty}
+test oo-1.4.1 {fully-qualified nested name} -body {
+ oo::object create ::one::two::three
+} -result {::one::two::three}
+test oo-1.4.2 {automatic command name has same name as namespace} -body {
+ set obj [oo::object new]
+ expr {[info object namespace $obj] == $obj}
+} -result 1
test oo-1.5 {basic test of OO functionality} -body {
oo::object doesnotexist
} -returnCodes 1 -result {unknown method "doesnotexist": must be create, destroy or new}
@@ -258,7 +278,21 @@ test oo-1.18 {OO: create object in NS with same name as global cmd} -setup {
rename test-oo-1.18 {}
A destroy
} -result ::C
-test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup {
+test oo-1.18.1 {no memory leak: superclass} -setup {
+} -constraints memory -body {
+
+ leaktest {
+ interp create t
+ t eval {
+ oo::class create A {
+ superclass oo::class
+ }
+ }
+ interp delete t
+ }
+} -cleanup {
+} -result 0
+test oo-1.18.2 {Bug 75b8433707: memory leak in oo-1.18} -setup {
proc test-oo-1.18 {} return
} -constraints memory -body {
leaktest {
@@ -271,7 +305,7 @@ test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup {
} -cleanup {
rename test-oo-1.18 {}
} -result 0
-test oo-1.18.2 {Bug 21c144f0f5} -setup {
+test oo-1.18.3 {Bug 21c144f0f5} -setup {
interp create slave
} -body {
slave eval {
@@ -1482,6 +1516,87 @@ test oo-11.4 {OO: cleanup} {
lappend result [bar0 destroy] [oo::object create foo] [foo destroy] \
[oo::object create bar2] [bar2 destroy]
} {1 {can't create object "foo": command already exists with that name} destroyed {} ::foo {} ::bar2 {}}
+test oo-11.5 {OO: cleanup} {
+ oo::class create obj1
+
+ trace add command obj1 delete {apply {{name1 name2 action} {
+ set namespace [info object namespace $name1]
+ namespace delete $namespace
+ }}}
+
+ rename obj1 {}
+ # No segmentation fault
+ return done
+} done
+
+test oo-11.6.1 {
+ OO: cleanup of when an class is mixed into itself
+} -constraints memory -body {
+ leaktest {
+ interp create interp1
+ oo::class create obj1
+ ::oo::define obj1 {self mixin [uplevel 1 {namespace which obj1}]}
+ rename obj1 {}
+ interp delete interp1
+ }
+} -result 0 -cleanup {
+}
+
+test oo-11.6.2 {
+ OO: cleanup ReleaseClassContents() where class is mixed into one of its
+ instances
+} -constraints memory -body {
+ leaktest {
+ interp create interp1
+ interp1 eval {
+ oo::class create obj1
+ ::oo::copy obj1 obj2
+ rename obj2 {}
+ rename obj1 {}
+ }
+ interp delete interp1
+ }
+} -result 0 -cleanup {
+}
+
+test oo-11.6.3 {
+ OO: cleanup ReleaseClassContents() where class is mixed into one of its
+ instances
+} -constraints memory -body {
+ leaktest {
+ interp create interp1
+ interp1 eval {
+ oo::class create obj1
+ ::oo::define obj1 {self mixin [uplevel 1 {namespace which obj1}]}
+
+ ::oo::copy obj1 obj2
+ rename obj2 {}
+ rename obj1 {}
+ }
+ interp delete interp1
+ }
+} -result 0 -cleanup {
+}
+
+test oo-11.6.4 {
+ OO: cleanup ReleaseClassContents() where class is mixed into one of its
+ instances
+} -body {
+ oo::class create obj1
+ ::oo::define obj1 {self mixin [uplevel 1 {namespace which obj1}]}
+
+ ::oo::copy obj1 obj2
+ ::oo::objdefine obj2 {mixin [uplevel 1 {namespace which obj2}]}
+
+ ::oo::copy obj2 obj3
+ rename obj3 {}
+ rename obj2 {}
+
+ # No segmentation fault
+ return done
+} -result done -cleanup {
+ rename obj1 {}
+}
test oo-12.1 {OO: filters} {
oo::class create Aclass
@@ -1668,13 +1783,13 @@ test oo-13.2 {OO: changing an object's class} -body {
oo::objdefine foo class oo::class
} -cleanup {
foo destroy
-} -returnCodes 1 -result {may not change a non-class object into a class object}
+} -result {}
test oo-13.3 {OO: changing an object's class} -body {
oo::class create foo
oo::objdefine foo class oo::object
} -cleanup {
foo destroy
-} -returnCodes 1 -result {may not change a class object into a non-class object}
+} -result {}
test oo-13.4 {OO: changing an object's class} -body {
oo::class create foo {
method m {} {
@@ -1689,6 +1804,106 @@ test oo-13.4 {OO: changing an object's class} -body {
foo destroy
bar destroy
} -result {::foo ::foo ::foo ::bar}
+test oo-13.5 {OO: changing an object's class: non-class to class} -setup {
+ oo::object create fooObj
+} -body {
+ oo::objdefine fooObj {
+ class oo::class
+ }
+ oo::define fooObj {
+ method x {} {expr 1+2+3}
+ }
+ [fooObj new] x
+} -cleanup {
+ fooObj destroy
+} -result 6
+test oo-13.6 {OO: changing an object's class: class to non-class} -setup {
+ oo::class create foo
+ unset -nocomplain ::result
+} -body {
+ set result dangling
+ oo::define foo {
+ method x {} {expr 1+2+3}
+ }
+ oo::class create boo {
+ superclass foo
+ destructor {set ::result "ok"}
+ }
+ boo new
+ foo create bar
+ oo::objdefine foo {
+ class oo::object
+ }
+ list $result [catch {bar x} msg] $msg
+} -cleanup {
+ catch {bar destroy}
+ foo destroy
+} -result {ok 1 {invalid command name "bar"}}
+test oo-13.7 {OO: changing an object's class} -setup {
+ oo::class create foo
+ oo::class create bar
+ unset -nocomplain result
+} -body {
+ oo::define bar method x {} {return ok}
+ oo::define foo {
+ method x {} {expr 1+2+3}
+ self mixin foo
+ }
+ lappend result [foo x]
+ oo::objdefine foo class bar
+ lappend result [foo x]
+} -cleanup {
+ foo destroy
+ bar destroy
+} -result {6 ok}
+test oo-13.8 {OO: changing an object's class to itself} -setup {
+ oo::class create foo
+} -body {
+ oo::define foo {
+ method x {} {expr 1+2+3}
+ }
+ oo::objdefine foo class foo
+} -cleanup {
+ foo destroy
+} -returnCodes error -result {may not change classes into an instance of themselves}
+test oo-13.9 {OO: changing an object's class: roots are special} -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ oo::objdefine oo::object {
+ class oo::class
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {may not modify the class of the root object class}
+test oo-13.10 {OO: changing an object's class: roots are special} -setup {
+ set i [interp create]
+} -body {
+ $i eval {
+ oo::objdefine oo::class {
+ class oo::object
+ }
+ }
+} -cleanup {
+ interp delete $i
+} -returnCodes error -result {may not modify the class of the class of classes}
+test oo-13.11 {OO: changing an object's class in a tricky place} -setup {
+ oo::class create cls
+ unset -nocomplain result
+} -body {
+ set result gorp
+ list [catch {
+ oo::define cls {
+ method x {} {return}
+ self class oo::object
+ ::set ::result ok
+ method y {} {return}; # I'm sorry, Dave. I'm afraid I can't do that.
+ }
+ } msg] $msg $result
+} -cleanup {
+ cls destroy
+} -result {1 {attempt to misuse API} ok}
# todo: changing a class subtype (metaclass) to another class subtype
test oo-14.1 {OO: mixins} {
@@ -2026,7 +2241,20 @@ test oo-15.12 {OO: object cloning with target NS} -setup {
Super destroy
catch {namespace delete ::existing}
} -result {::existing refers to an existing namespace}
-test oo-15.13 {OO: object cloning with target NS} -setup {
+test oo-15.13.1 {
+ OO: object cloning with target NS
+ Valgrind will report a leak if the reference count of the namespace isn't
+ properly incremented.
+} -setup {
+ oo::class create Cls {}
+} -body {
+ oo::copy Cls Cls2 ::dupens
+ return done
+} -cleanup {
+ Cls destroy
+ Cls2 destroy
+} -result done
+test oo-15.13.2 {OO: object cloning with target NS} -setup {
oo::class create Super
oo::class create Cls {superclass Super}
} -body {
@@ -3621,99 +3849,110 @@ test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup {
cls destroy
} -result {0 {}}
-oo::class create SampleSlot {
- superclass oo::Slot
- constructor {} {
- variable contents {a b c} ops {}
- }
- method contents {} {variable contents; return $contents}
- method ops {} {variable ops; return $ops}
- method Get {} {
- variable contents
- variable ops
- lappend ops [info level] Get
- return $contents
- }
- method Set {lst} {
- variable contents $lst
- variable ops
- lappend ops [info level] Set $lst
- return
+proc SampleSlotSetup script {
+ set script0 {
+ oo::class create SampleSlot {
+ superclass oo::Slot
+ constructor {} {
+ variable contents {a b c} ops {}
+ }
+ method contents {} {variable contents; return $contents}
+ method ops {} {variable ops; return $ops}
+ method Get {} {
+ variable contents
+ variable ops
+ lappend ops [info level] Get
+ return $contents
+ }
+ method Set {lst} {
+ variable contents $lst
+ variable ops
+ lappend ops [info level] Set $lst
+ return
+ }
+ }
+ }
+ append script0 \n$script
+}
+
+proc SampleSlotCleanup script {
+ set script0 {
+ SampleSlot destroy
}
+ append script \n$script0
}
-test oo-32.1 {TIP 380: slots - class test} -setup {
+test oo-32.1 {TIP 380: slots - class test} -setup [SampleSlotSetup {
SampleSlot create sampleSlot
-} -body {
+}] -body {
list [info level] [sampleSlot contents] [sampleSlot ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename sampleSlot {}
-} -result {0 {a b c} {}}
-test oo-32.2 {TIP 380: slots - class test} -setup {
+}] -result {0 {a b c} {}}
+test oo-32.2 {TIP 380: slots - class test} -setup [SampleSlotSetup {
SampleSlot create sampleSlot
-} -body {
+}] -body {
list [info level] [sampleSlot -clear] \
[sampleSlot contents] [sampleSlot ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename sampleSlot {}
-} -result {0 {} {} {1 Set {}}}
-test oo-32.3 {TIP 380: slots - class test} -setup {
+}] -result {0 {} {} {1 Set {}}}
+test oo-32.3 {TIP 380: slots - class test} -setup [SampleSlotSetup {
SampleSlot create sampleSlot
-} -body {
+}] -body {
list [info level] [sampleSlot -append g h i] \
[sampleSlot contents] [sampleSlot ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename sampleSlot {}
-} -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}}
-test oo-32.4 {TIP 380: slots - class test} -setup {
+}] -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}}
+test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup {
SampleSlot create sampleSlot
-} -body {
+}] -body {
list [info level] [sampleSlot -set d e f] \
[sampleSlot contents] [sampleSlot ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename sampleSlot {}
-} -result {0 {} {d e f} {1 Set {d e f}}}
-test oo-32.5 {TIP 380: slots - class test} -setup {
+}] -result {0 {} {d e f} {1 Set {d e f}}}
+test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup {
SampleSlot create sampleSlot
-} -body {
+}] -body {
list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \
[sampleSlot contents] [sampleSlot ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename sampleSlot {}
-} -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}}
+}] -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}}
-test oo-33.1 {TIP 380: slots - defaulting} -setup {
+test oo-33.1 {TIP 380: slots - defaulting} -setup [SampleSlotSetup {
set s [SampleSlot new]
-} -body {
+}] -body {
list [$s x y] [$s contents]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename $s {}
-} -result {{} {a b c x y}}
-test oo-33.2 {TIP 380: slots - defaulting} -setup {
+}] -result {{} {a b c x y}}
+test oo-33.2 {TIP 380: slots - defaulting} -setup [SampleSlotSetup {
set s [SampleSlot new]
-} -body {
+}] -body {
list [$s destroy; $s unknown] [$s contents]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename $s {}
-} -result {{} {a b c destroy unknown}}
-test oo-33.3 {TIP 380: slots - defaulting} -setup {
+}] -result {{} {a b c destroy unknown}}
+test oo-33.3 {TIP 380: slots - defaulting} -setup [SampleSlotSetup {
set s [SampleSlot new]
-} -body {
+}] -body {
oo::objdefine $s forward --default-operation my -set
list [$s destroy; $s unknown] [$s contents] [$s ops]
-} -cleanup {
+} -cleanup [SampleSlotCleanup {
rename $s {}
-} -result {{} unknown {1 Set destroy 1 Set unknown}}
-test oo-33.4 {TIP 380: slots - errors} -setup {
+}] -result {{} unknown {1 Set destroy 1 Set unknown}}
+test oo-33.4 {TIP 380: slots - errors} -setup [SampleSlotSetup {
set s [SampleSlot new]
-} -body {
+}] -body {
# Method names beginning with "-" are special to slots
$s -grill q
-} -returnCodes error -cleanup {
+} -returnCodes error -cleanup [SampleSlotCleanup {
rename $s {}
-} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops}
-
-SampleSlot destroy
+}] -result \
+ {unknown method "-grill": must be -append, -clear, -set, contents or ops}
test oo-34.1 {TIP 380: slots - presence} -setup {
set obj [oo::object new]
@@ -3833,10 +4072,35 @@ test oo-35.5 {Bug 1a56550e96: introspectors must traverse mixin links correctly}
} -cleanup {
base destroy
} -result {{c d e} {c d e}}
+
+
+test oo-35.6 {
+ Bug : teardown of an object that is a class that is an instance of itself
+} -setup {
+ oo::class create obj
+
+ oo::copy obj obj1 obj1
+ oo::objdefine obj1 {
+ mixin obj1 obj
+ }
+ oo::copy obj1 obj2
+ oo::objdefine obj2 {
+ mixin obj2 obj1
+ }
+} -body {
+ rename obj2 {}
+ rename obj1 {}
+ # doesn't crash
+ return done
+} -cleanup {
+ rename obj {}
+} -result done
+
+
cleanupTests
return
# Local Variables:
-# mode: tcl
+# MODE: Tcl
# End:
diff --git a/tcl8.6/tests/package.test b/tcl8.6/tests/package.test
index 74415ae..bc73003 100644
--- a/tcl8.6/tests/package.test
+++ b/tcl8.6/tests/package.test
@@ -608,6 +608,18 @@ test pkg-3.53 {Tcl_PkgRequire procedure, picking best stable version} {
package require t
set x
} {1.1}
+test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup {
+ package forget t
+} -body {
+ coroutine coro1 apply {{} {
+ package ifneeded t 2.1 {
+ yield
+ package provide t 2.1
+ }
+ package require t 2.1
+ }}
+ list [catch {coro1} msg] $msg
+} -match glob -result {0 2.1}
test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body {
diff --git a/tcl8.6/tests/pkgIndex.tcl b/tcl8.6/tests/pkgIndex.tcl
new file mode 100644
index 0000000..854b943
--- /dev/null
+++ b/tcl8.6/tests/pkgIndex.tcl
@@ -0,0 +1,6 @@
+#! /usr/bin/env tclsh
+
+package ifneeded tcltests 0.1 "
+ source [list $dir/tcltests.tcl]
+ package provide tcltests 0.1
+"
diff --git a/tcl8.6/tests/platform.test b/tcl8.6/tests/platform.test
index 8ee0ec7..e5a4c90 100644
--- a/tcl8.6/tests/platform.test
+++ b/tcl8.6/tests/platform.test
@@ -10,6 +10,7 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require tcltest 2
+package require tcltests
namespace eval ::tcl::test::platform {
namespace import ::tcltest::testConstraint
@@ -67,7 +68,10 @@ test platform-3.1 {CPU ID on Windows/UNIX} \
# format of string it produces consists of two non-empty words separated by a
# hyphen.
package require platform
-test platform-4.1 {format of platform::identify result} -match regexp -body {
+test platform-4.1 {format of platform::identify result} -constraints notValgrind -match regexp -body {
+ # [identify] may attempt to [exec] dpkg-architecture, which may not exist,
+ # in which case fork will not be followed by exec, and valgrind will issue
+ # "still reachable" reports.
platform::identify
} -result {^([^-]+-)+[^-]+$}
test platform-4.2 {format of platform::generic result} -match regexp -body {
diff --git a/tcl8.6/tests/proc.test b/tcl8.6/tests/proc.test
index e06720e..8b25b0a 100644
--- a/tcl8.6/tests/proc.test
+++ b/tcl8.6/tests/proc.test
@@ -110,6 +110,14 @@ test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple name
proc p {b:a b::a} {
}
} -returnCodes error -result {formal parameter "b::a" is not a simple name}
+test proc-1.9 {Tcl_ProcObjCmd, arguments via canonical list (string-representation bug [631b4c45df])} -body {
+ set v 2
+ binary scan AB cc a b
+ proc p [list [list a $a] [list b $b] [list v [expr {$v + 2}]]] {expr {$a + $b + $v}}
+ p
+} -result [expr {65+66+4}] -cleanup {
+ rename p {}
+}
test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} -setup {
catch {namespace delete {*}[namespace children :: test_ns_*]}
@@ -383,6 +391,14 @@ test proc-7.4 {Proc struct outlives its interp: Bug 3532959} {
interp delete slave
unset lambda
} {}
+
+test proc-7.5 {[631b4c45df] Crash in argument processing} {
+ binary scan A c val
+ proc foo [list [list from $val]] {}
+ rename foo {}
+ unset -nocomplain val
+} {}
+
# cleanup
catch {rename p ""}
diff --git a/tcl8.6/tests/registry.test b/tcl8.6/tests/registry.test
index 2072559..539ba2d 100644
--- a/tcl8.6/tests/registry.test
+++ b/tcl8.6/tests/registry.test
@@ -19,7 +19,7 @@ testConstraint reg 0
if {[testConstraint win]} {
if {![catch {
::tcltest::loadTestedCommands
- set ::regver [package require registry 1.3.2]
+ set ::regver [package require registry 1.3.3]
}]} {
testConstraint reg 1
}
@@ -33,7 +33,7 @@ testConstraint english [expr {
test registry-1.0 {check if we are testing the right dll} {win reg} {
set ::regver
-} {1.3.2}
+} {1.3.3}
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 ...?"}}
@@ -283,7 +283,7 @@ test registry-4.7 {GetKeyNames: Unicode} {win reg english} {
registry delete HKEY_CURRENT_USER\\TclFoobar
set result
} "baz\u00c7bar blat"
-test registry-4.8 {GetKeyNames: Unicode} {win reg nt} {
+test registry-4.8 {GetKeyNames: Unicode} {win reg} {
registry delete HKEY_CURRENT_USER\\TclFoobar
registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u30b7bar
registry set HKEY_CURRENT_USER\\TclFoobar\\blat
@@ -487,7 +487,7 @@ test registry-6.17 {GetValue: Unicode value names} {win reg} {
registry delete HKEY_CURRENT_USER\\TclFoobar
set result
} foobar
-test registry-6.18 {GetValue: values with Unicode strings} {win reg nt} {
+test registry-6.18 {GetValue: values with Unicode strings} {win reg} {
registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u30b7r baz} multi_sz
set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
registry delete HKEY_CURRENT_USER\\TclFoobar
@@ -505,7 +505,7 @@ test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {
registry delete HKEY_CURRENT_USER\\TclFoobar
set result
} "foo ba r baz"
-test registry-6.21 {GetValue: very long value names and values} {pcOnly reg} {
+test registry-6.21 {GetValue: very long value names and values} {win reg} {
registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz
set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]]
registry delete HKEY_CURRENT_USER\\TclFoobar
@@ -604,7 +604,7 @@ test registry-9.3 {ParseKeyName: bad keys} -constraints {win reg} -body {
test registry-9.4 {ParseKeyName: bad keys} -constraints {win reg} -body {
registry values \\\\\\
} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
-test registry-9.5 {ParseKeyName: bad keys} -constraints {win reg english nt} -body {
+test registry-9.5 {ParseKeyName: bad keys} -constraints {win reg english} -body {
registry values \\\\\\HKEY_CLASSES_ROOT
} -returnCodes error -result {unable to open key: The network address is invalid.}
test registry-9.6 {ParseKeyName: bad keys} -constraints {win reg} -body {
diff --git a/tcl8.6/tests/safe.test b/tcl8.6/tests/safe.test
index e43ce12..11ad2a9 100644
--- a/tcl8.6/tests/safe.test
+++ b/tcl8.6/tests/safe.test
@@ -180,17 +180,17 @@ test safe-6.3 {test safe interpreters knowledge of the world} {
# leaking infos, but they still do...
# high level general test
-test safe-7.1 {tests that everything works at high level} {
+test safe-7.1 {tests that everything works at high level} -body {
set i [safe::interpCreate]
# no error shall occur:
# (because the default access_path shall include 1st level sub dirs so
# package require in a slave works like in the master)
- set v [interp eval $i {package require http 1}]
+ set v [interp eval $i {package require http 2}]
# no error shall occur:
- interp eval $i {http_config}
+ interp eval $i {http::config}
safe::interpDelete $i
set v
-} 1.0
+} -match glob -result 2.*
test safe-7.2 {tests specific path and interpFind/AddToAccessPath} -body {
set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
# should not add anything (p0)
@@ -308,14 +308,10 @@ test safe-8.7 {safe source control on file} -setup {
unset log
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 {
- catch {safe::interpDelete $i}
- safe::interpCreate $i
-} -body {
- $i eval {source -rsrc Init}
-} -returnCodes error -cleanup {
- safe::interpDelete $i
-} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.8 {safe source forbids -rsrc} emptyTest {
+ # Disabled this test. It was only useful for long unsupported
+ # Mac OS 9 systems. [Bug 860a9f1945]
+} {}
test safe-8.9 {safe source and return} -setup {
set returnScript [makeFile {return "ok"} return.tcl]
catch {safe::interpDelete $i}
diff --git a/tcl8.6/tests/string.test b/tcl8.6/tests/string.test
index bbba5eb..8fc5b0e 100644
--- a/tcl8.6/tests/string.test
+++ b/tcl8.6/tests/string.test
@@ -24,6 +24,7 @@ catch [list package require -exact Tcltest [info patchlevel]]
testConstraint testobj [expr {[info commands testobj] != {}}]
testConstraint testindexobj [expr {[info commands testindexobj] != {}}]
+testConstraint tip389 [expr {[string length \U010000] == 2}]
# Used for constraining memory leak tests
testConstraint memory [llength [info commands memory]]
@@ -290,6 +291,9 @@ test string-5.19 {string index, bytearray object out of bounds} {
test string-5.20 {string index, bytearray object out of bounds} {
string index [binary format I* {0x50515253 0x52}] 20
} {}
+test string-5.21 {string index, surrogates, bug [11ae2be95dac9417]} tip389 {
+ list [string index a\U100000b 1] [string index a\U100000b 2] [string index a\U100000b 3]
+} [list \U100000 {} b]
proc largest_int {} {
@@ -1191,6 +1195,9 @@ test string-11.54 {string match, failure} {
[string match *a*l*\u0000*cba* $longString] \
[string match *===* $longString]
} {0 1 1 1 0 0}
+test string-11.55 {string match, invalid binary optimization} {
+ [format string] match \u0141 [binary format c 65]
+} 0
test string-12.1 {string range} {
list [catch {string range} msg] $msg
@@ -1276,6 +1283,9 @@ test string-12.22 {string range, shimmering binary/index} {
binary scan $s a* x
string range $s $s end
} 000000001
+test string-12.23 {string range, surrogates, bug [11ae2be95dac9417]} tip389 {
+ list [string range a\U100000b 1 1] [string range a\U100000b 2 2] [string range a\U100000b 3 3]
+} [list \U100000 {} b]
test string-13.1 {string repeat} {
list [catch {string repeat} msg] $msg
@@ -1371,6 +1381,12 @@ test string-14.16 {string replace} {
test string-14.17 {string replace} {
string replace abcdefghijklmnop end end-1
} {abcdefghijklmnop}
+test string-14.18 {string replace} {
+ string replace abcdefghijklmnop 10 9 XXX
+} {abcdefghijklmnop}
+test string-14.19 {string replace} {
+ string replace {} -1 0 A
+} A
test string-15.1 {string tolower too few args} {
list [catch {string tolower} msg] $msg
@@ -1464,6 +1480,10 @@ test string-17.7 {string totitle, unicode} {
test string-17.8 {string totitle, compiled} {
lindex [string totitle [list aa bb [list cc]]] 0
} Aa
+test string-17.9 {string totitle, surrogates, bug [11ae2be95dac9417]} tip389 {
+ list [string totitle a\U118c0c 1 1] [string totitle a\U118c0c 2 2] \
+ [string totitle a\U118c0c 3 3]
+} [list a\U118a0c a\U118c0C a\U118c0C]
test string-18.1 {string trim} {
list [catch {string trim} msg] $msg
@@ -1995,6 +2015,12 @@ test string-29.4 {string cat, many args} {
list $r1 $r2
} {0 0}
+test string-30.1.1 {[Bug ba921a8d98]: string cat} {
+ string cat [set data [binary format a* hello]] [encoding convertto $data] [unset data]
+} hellohello
+test string-30.1.2 {[Bug ba921a8d98]: inplace cat by subst (compiled to "strcat" instruction)} {
+ set x "[set data [binary format a* hello]][encoding convertto $data][unset data]"
+} hellohello
# cleanup
diff --git a/tcl8.6/tests/tailcall.test b/tcl8.6/tests/tailcall.test
index 26f3cbf..3751c35 100644
--- a/tcl8.6/tests/tailcall.test
+++ b/tcl8.6/tests/tailcall.test
@@ -688,6 +688,26 @@ if {[testConstraint testnrelevels]} {
namespace delete testnre
}
+test tailcall-14.1 {in a deleted namespace} -body {
+ namespace eval ns {
+ proc p args {
+ tailcall [namespace current] $args
+ }
+ namespace delete [namespace current]
+ p
+ }
+} -returnCodes 1 -result {namespace "::ns" not found}
+
+test tailcall-14.1-bc {{in a deleted namespace} {byte compiled}} -body {
+ namespace eval ns {
+ proc p args {
+ tailcall [namespace current] {*}$args
+ }
+ namespace delete [namespace current]
+ p
+ }
+} -returnCodes 1 -result {namespace "::ns" not found}
+
# cleanup
::tcltest::cleanupTests
diff --git a/tcl8.6/tests/tcltest.test b/tcl8.6/tests/tcltest.test
index 728a018..ca720ee 100644
--- a/tcl8.6/tests/tcltest.test
+++ b/tcl8.6/tests/tcltest.test
@@ -550,6 +550,7 @@ switch -- $::tcl_platform(platform) {
file attributes $notWriteableDir -permissions 00555
}
default {
+ # note in FAT/NTFS we won't be able to protect directory with read-only attribute...
catch {file attributes $notWriteableDir -readonly 1}
catch {testchmod 0 $notWriteableDir}
}
@@ -566,9 +567,10 @@ test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} {
# This constraint doesn't go at the top of the file so that it doesn't
# interfere with tcltest-5.5
testConstraint notFAT [expr {
- ![string match "FAT*" [lindex [file system $notWriteableDir] 1]]
+ ![regexp {^(FAT\d*|NTFS)$} [lindex [file system $notWriteableDir] 1]]
+ || $::tcl_platform(platform) eq "unix" || [llength [info commands testchmod]]
}]
-# FAT permissions are fairly hopeless; ignore this test if that FS is used
+# FAT/NTFS permissions are fairly hopeless; ignore this test if that FS is used
test tcltest-8.4 {tcltest a.tcl -tmpdir notWriteableDir} {
-constraints {unixOrPc notRoot notFAT}
-body {
@@ -906,7 +908,9 @@ removeFile load.tcl
# [interpreter]
test tcltest-13.1 {interpreter} {
+ -constraints notValgrind
-setup {
+ #to do: Why is $::tcltest::tcltest being saved and restored here?
set old $::tcltest::tcltest
set ::tcltest::tcltest tcltest
}
@@ -918,6 +922,11 @@ test tcltest-13.1 {interpreter} {
}
-result {tcltest tclsh tclsh}
-cleanup {
+ # writing ::tcltest::tcltest triggers a trace that sets up the stdio
+ # constraint, which involves a call to [exec] that might fail after
+ # "fork" and before "exec", in which case the forked process will not
+ # have a chance to clean itself up before exiting, which causes
+ # valgrind to issue numerous "still reachable" reports.
set ::tcltest::tcltest $old
}
}
@@ -1198,7 +1207,7 @@ test tcltest-21.2 {force a test command failure} {
} {1}
}
-returnCodes 1
- -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorCode, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
}
test tcltest-21.3 {test command with setup} {
@@ -1291,7 +1300,7 @@ test tcltest-21.7 {test command - bad flag} {
}
}
-returnCodes 1
- -result {bad option "-foobar": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+ -result {bad option "-foobar": must be -body, -cleanup, -constraints, -errorCode, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
}
# alternate test command format (these are the same as 21.1-21.6, with the
@@ -1311,7 +1320,7 @@ test tcltest-21.8 {force a test command failure} \
} \
-returnCodes 1 \
-cleanup {set ::tcltest::currentFailure $fail} \
- -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+ -result {bad option "1": must be -body, -cleanup, -constraints, -errorCode, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
test tcltest-21.9 {test command with setup} \
-setup {set foo 1} \
diff --git a/tcl8.6/tests/tcltests.tcl b/tcl8.6/tests/tcltests.tcl
new file mode 100644
index 0000000..74d1b40
--- /dev/null
+++ b/tcl8.6/tests/tcltests.tcl
@@ -0,0 +1,11 @@
+#! /usr/bin/env tclsh
+
+package require tcltest 2.2
+namespace import ::tcltest::*
+
+testConstraint exec [llength [info commands exec]]
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint fileevent [llength [info commands fileevent]]
+testConstraint thread [
+ expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
diff --git a/tcl8.6/tests/thread.test b/tcl8.6/tests/thread.test
index cc4c871..eaaaa41 100644
--- a/tcl8.6/tests/thread.test
+++ b/tcl8.6/tests/thread.test
@@ -11,25 +11,19 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2.2
- namespace import -force ::tcltest::*
-}
+
+# when thread::release is used, -wait is passed in order allow the thread to
+# be fully finalized, which avoids valgrind "still reachable" reports.
+
+package require tcltests
::tcltest::loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
# Some tests require the testthread command
-testConstraint testthread [expr {[info commands testthread] != {}}]
-
-# Some tests require the Thread package
-
-testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint testthread [expr {[info commands testthread] ne {}}]
-# Some tests may not work under valgrind
-
-testConstraint notValgrind [expr {![testConstraint valgrind]}]
set threadSuperKillScript {
rename catch ""
@@ -72,6 +66,17 @@ proc ThreadError {id info} {
set threadSawError($id) true; # signal main thread to exit [vwait].
}
+proc threadSuperKill id {
+ variable threadSuperKillScript
+ try {
+ thread::send $id $::threadSuperKillScript
+ } on error {tres topts} {
+ if {$tres ne {target thread died}} {
+ return -options $topts $tres
+ }
+ }
+}
+
if {[testConstraint thread]} {
thread::errorproc ThreadError
}
@@ -96,22 +101,22 @@ test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
set serverthread [thread::create -preserved]
set numthreads [llength [thread::names]]
- thread::release $serverthread
+ thread::release -wait $serverthread
set numthreads
-} {2}
+} 2
test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
thread::create {set x 5}
foreach try {0 1 2 4 5 6} {
- # Try various ways to yield
- update
- after 10
- set l [llength [thread::names]]
- if {$l == 1} {
- break
- }
+ # Try various ways to yield
+ update
+ after 10
+ set l [llength [thread::names]]
+ if {$l == 1} {
+ break
+ }
}
set l
-} {1}
+} 1
test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
thread::create {{*}{}}
update
@@ -121,13 +126,13 @@ test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
set serverthread [thread::create -preserved]
set five [thread::send $serverthread {set x 5}]
- thread::release $serverthread
+ thread::release -wait $serverthread
set five
} 5
test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
set five [thread::send $serverthread {set z}]
- thread::release $serverthread
+ thread::release -wait $serverthread
set five
} 5
@@ -159,7 +164,7 @@ test thread-3.1 {TclThreadList} {thread} {
set l2 [thread::names]
set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
foreach t $l1 {
- thread::release $t
+ thread::release -wait $t
}
list $len $c
} {1 0}
@@ -887,7 +892,7 @@ test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainE
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::cancel $serverthread]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -929,7 +934,7 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::cancel $serverthread]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1029,7 +1034,7 @@ test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode lo
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {interp cancel}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1071,7 +1076,7 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {interp cancel}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1111,7 +1116,7 @@ test thread-7.30 {cancel: send async thread cancel nested catch inside pure byte
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1153,7 +1158,7 @@ test thread-7.31 {cancel: send async thread cancel nested catch pure inside-comm
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
diff --git a/tcl8.6/tests/var.test b/tcl8.6/tests/var.test
index a9d93ac..8d86fce 100644
--- a/tcl8.6/tests/var.test
+++ b/tcl8.6/tests/var.test
@@ -776,6 +776,22 @@ test var-13.1 {Tcl_UnsetVar2, unset array with trace set on element} -setup {
}
set x "If you see this, it worked"
} -result "If you see this, it worked"
+test var-13.2 {unset array with search, bug 46a2410650} -body {
+ apply {{} {
+ array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
+ set s [array startsearch a]
+ unset a([array nextelement a $s])
+ array nextelement a $s
+ }}
+} -returnCodes error -result {couldn't find search "s-1-a"}
+test var-13.3 {unset array with search, SIGSEGV, bug 46a2410650} -body {
+ apply {{} {
+ array set a {aa 11 bb 22 cc 33 dd 44 ee 55 ff 66}
+ set s [array startsearch a]
+ unset a(ff)
+ array nextelement a $s
+ }}
+} -returnCodes error -result {couldn't find search "s-1-a"}
test var-14.1 {array names syntax} -body {
array names foo bar baz snafu
@@ -819,6 +835,18 @@ test var-17.1 {TclArraySet [Bug 1669489]} -setup {
} -cleanup {
unset -nocomplain ::a ::elements
} -result {}
+test var-17.2 {TclArraySet Dict shortcut only on pure value} -setup {
+ unset -nocomplain a d
+ set d {p 1 p 2}
+ dict get $d p
+ set foo 0
+} -body {
+ trace add variable a write "[list incr [namespace which -variable foo]];#"
+ array set a $d
+ set foo
+} -cleanup {
+ unset -nocomplain a d foo
+} -result 2
test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
set already 0
@@ -930,6 +958,28 @@ test var-20.9 {[bc1a96407a] array set compiled w/ trace} -setup {
test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body {
apply {{} {set name foo(bar); array set $name {a 1}}}
} -returnCodes error -match glob -result *
+test var-20.11 {array set don't compile bad initializer} -setup {
+ unset -nocomplain foo
+ trace add variable foo array {set foo(bar) baz;#}
+} -body {
+ catch {array set foo bad}
+ set foo(bar)
+} -cleanup {
+ unset -nocomplain foo
+} -result baz
+test var-20.12 {array set don't compile bad initializer} -setup {
+ unset -nocomplain ::foo
+ trace add variable ::foo array {set ::foo(bar) baz;#}
+} -body {
+ catch {apply {{} {
+ set value bad
+ array set ::foo $value
+
+ }}}
+ set ::foo(bar)
+} -cleanup {
+ unset -nocomplain ::foo
+} -result baz
test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
proc linenumber {} {dict get [info frame -1] line}
diff --git a/tcl8.6/tests/winDde.test b/tcl8.6/tests/winDde.test
index f04fb45..1fa7e86 100644
--- a/tcl8.6/tests/winDde.test
+++ b/tcl8.6/tests/winDde.test
@@ -20,7 +20,7 @@ testConstraint dde 0
if {[testConstraint win]} {
if {![catch {
::tcltest::loadTestedCommands
- set ::ddever [package require dde 1.4.0]
+ set ::ddever [package require dde 1.4.1]
set ::ddelib [lindex [package ifneeded dde $::ddever] 1]}]} {
testConstraint dde 1
}
@@ -104,7 +104,7 @@ proc createChildProcess {ddeServerName args} {
# -------------------------------------------------------------------------
test winDde-1.0 {check if we are testing the right dll} {win dde} {
set ::ddever
-} {1.4.0}
+} {1.4.1}
test winDde-1.1 {Settings the server's topic name} -constraints dde -body {
list [dde servername foobar] [dde servername] [dde servername self]
diff --git a/tcl8.6/tests/winFCmd.test b/tcl8.6/tests/winFCmd.test
index a808c82..5243eca 100644
--- a/tcl8.6/tests/winFCmd.test
+++ b/tcl8.6/tests/winFCmd.test
@@ -57,11 +57,10 @@ proc cleanup {args} {
}
if {[testConstraint winOnly]} {
- set major [string index $tcl_platform(osVersion) 0]
- if {[testConstraint nt] && $major > 4} {
- if {$major > 5} {
+ if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} {
+ if {$::tcl_platform(osVersion) >= 6.0} {
testConstraint winVista 1
- } elseif {$major == 5} {
+ } else {
testConstraint win2000orXP 1
}
} else {
@@ -1078,6 +1077,15 @@ test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} -setup {
} -cleanup {
file delete -force -- c:/td1
} -result {c:/td1}
+test winFCmd-12.6.2 {ConvertFileNameFormat: absolute path with drive (in temp folder)} -setup {
+ catch {file delete -force -- $::env(TEMP)/td1}
+} -constraints {win} -body {
+ createfile $::env(TEMP)/td1 {}
+ string equal [string tolower [file attributes $::env(TEMP)/td1 -longname]] \
+ [string tolower [file normalize $::env(TEMP)]/td1]
+} -cleanup {
+ file delete -force -- $::env(TEMP)/td1
+} -result 1
test winFCmd-12.7 {ConvertFileNameFormat} -body {
string tolower [file attributes //bisque/tcl/ws -longname]
} -constraints {nonPortable win} -result {//bisque/tcl/ws}
diff --git a/tcl8.6/tests/winPipe.test b/tcl8.6/tests/winPipe.test
index 9c6f94d..b3624c2 100644
--- a/tcl8.6/tests/winPipe.test
+++ b/tcl8.6/tests/winPipe.test
@@ -30,6 +30,7 @@ testConstraint cat32 [file exists $cat32]
testConstraint AllocConsole [catch {puts console1 ""}]
testConstraint RealConsole [expr {![testConstraint AllocConsole]}]
testConstraint testexcept [llength [info commands testexcept]]
+testConstraint slowTest 0
set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
@@ -41,7 +42,7 @@ append big $big
append big $big
set path(little) [makeFile {} little]
-set f [open $path(little) w]
+set f [open $path(little) w]
puts -nonewline $f "little"
close $f
@@ -308,9 +309,54 @@ test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \
lappend x [catch {close $f} msg] $msg
} {writable timeout 0 {}}
-set path(echoArgs.tcl) [makeFile {
- puts "[list $argv0 $argv]"
-} echoArgs.tcl]
+proc _testExecArgs {single args} {
+ variable path
+ if {![info exists path(echoArgs.tcl)] || ![file exists $path(echoArgs.tcl)]} {
+ set path(echoArgs.tcl) [makeFile {
+ puts "[list [file tail $argv0] {*}$argv]"
+ } echoArgs.tcl]
+ }
+ if {![info exists path(echoArgs.bat)] || ![file exists $path(echoArgs.bat)]} {
+ set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" "echoArgs.bat"]
+ }
+ set cmds [list [list [interpreter] $path(echoArgs.tcl)]]
+ if {!($single & 2)} {
+ lappend cmds [list $path(echoArgs.bat)]
+ } else {
+ if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} {
+ set path(echoArgs2.bat) [makeFile \
+ "@[file native [interpreter]] $path(echoArgs.tcl) %*" \
+ "echo(Cmd)Test Args & Batch.bat" [makeDirectory test(Dir)Check]]
+ }
+ lappend cmds [list $path(echoArgs2.bat)]
+ }
+ set broken {}
+ foreach args $args {
+ if {$single & 1} {
+ # enclose single test-arg between 1st/3rd to be sure nothing is truncated
+ # (e. g. to cover unexpected trim by nts-zero case, and args don't recombined):
+ set args [list "1st" $args "3rd"]
+ }
+ set args [list {*}$args]; # normalized canonical list
+ foreach cmd $cmds {
+ set e [linsert $args 0 [file tail $path(echoArgs.tcl)]]
+ tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] ($cmd) for\n ## $args"
+ if {[catch {
+ exec {*}$cmd {*}$args
+ } r]} {
+ set r "ERROR: $r"
+ }
+ if {$r ne $e} {
+ append broken "\[ERROR\]: exec [file extension [lindex $cmd 0]] on $args\n -- result:\n$r\n -- expected:\n$e\n"
+ }
+ if {$single & 8} {
+ # if test exe only:
+ break
+ }
+ }
+ }
+ return $broken
+}
### validate the raw output of BuildCommandLine().
###
@@ -369,65 +415,178 @@ test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} {
exec $env(COMSPEC) /c echo foo \} bar
} "foo \} bar"
+set injectList {
+ {test"whoami} {test""whoami}
+ {test"""whoami} {test""""whoami}
+
+ "test\"whoami\\" "test\"\"whoami\\"
+ "test\"\"\"whoami\\" "test\"\"\"\"whoami\\"
+
+ {test\\&\\test} {test"\\&\\test}
+ {"test\\&\\test} {"test"\\&\\"test"}
+ {test\\"&"\\test} {test"\\"&"\\test}
+ {"test\\"&"\\test} {"test"\\"&"\\"test"}
+
+ {test\"&whoami} {test"\"&whoami}
+ {test""\"&whoami} {test"""\"&whoami}
+ {test\"\&whoami} {test"\"\&whoami}
+ {test""\"\&whoami} {test"""\"\&whoami}
+
+ {test&whoami} {test|whoami}
+ {"test&whoami} {"test|whoami}
+ {test"&whoami} {test"|whoami}
+ {"test"&whoami} {"test"|whoami}
+ {""test"&whoami} {""test"|whoami}
+
+ {test&echo "} {test|echo "}
+ {"test&echo "} {"test|echo "}
+ {test"&echo "} {test"|echo "}
+ {"test"&echo "} {"test"|echo "}
+ {""test"&echo "} {""test"|echo "}
+
+ {test&echo ""} {test|echo ""}
+ {"test&echo ""} {"test|echo ""}
+ {test"&echo ""} {test"|echo ""}
+ {"test"&echo ""} {"test"|echo ""}
+ {""test"&echo ""} {""test"|echo ""}
+
+ {test>whoami} {test<whoami}
+ {"test>whoami} {"test<whoami}
+ {test">whoami} {test"<whoami}
+ {"test">whoami} {"test"<whoami}
+ {""test">whoami} {""test"<whoami}
+ {test(whoami)} {test(whoami)}
+ {test"(whoami)} {test"(whoami)}
+ {test^whoami} {test^^echo ^^^}
+ {test"^whoami} {test"^^echo ^^^}
+ {test"^echo ^^^"} {test""^echo" ^^^"}
+
+ {test%USERDOMAIN%\%USERNAME%}
+ {test" %USERDOMAIN%\%USERNAME%}
+ {test%USERDOMAIN%\\%USERNAME%}
+ {test" %USERDOMAIN%\\%USERNAME%}
+ {test%USERDOMAIN%&%USERNAME%}
+ {test" %USERDOMAIN%&%USERNAME%}
+ {test%USERDOMAIN%\&\%USERNAME%}
+ {test" %USERDOMAIN%\&\%USERNAME%}
+
+ {test%USERDOMAIN%\&\test}
+ {test" %USERDOMAIN%\&\test}
+ {test%USERDOMAIN%\\&\\test}
+ {test" %USERDOMAIN%\\&\\test}
+
+ {test%USERDOMAIN%\&\"test}
+ {test" %USERDOMAIN%\&\"test}
+ {test%USERDOMAIN%\\&\\"test}
+ {test" %USERDOMAIN%\\&\\"test}
+}
+
### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline().
###
-test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo "" bar
-} [list $path(echoArgs.tcl) [list foo {} bar]]
-test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo {} bar
-} [list $path(echoArgs.tcl) [list foo {} bar]]
-test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #1} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo "\"" bar
-} [list $path(echoArgs.tcl) [list foo "\"" bar]]
-test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #2} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo {""} bar
-} [list $path(echoArgs.tcl) [list foo {""} bar]]
-test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #3} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo "\" " bar
-} [list $path(echoArgs.tcl) [list foo "\" " bar]]
-test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #4} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo {a="b"} bar
-} [list $path(echoArgs.tcl) [list foo {a="b"} bar]]
-test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #5} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo {a = "b"} bar
-} [list $path(echoArgs.tcl) [list foo {a = "b"} bar]]
-test winpipe-8.8 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #6} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}
-} [list $path(echoArgs.tcl) [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}]]
-test winpipe-8.9 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #1} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\ bar
-} [list $path(echoArgs.tcl) [list foo \\ bar]]
-test winpipe-8.10 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #2} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\\ bar
-} [list $path(echoArgs.tcl) [list foo \\\\ bar]]
-test winpipe-8.11 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #3} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\ bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\ bar]]
-test winpipe-8.12 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #4} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\ bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\\\ bar]]
-test winpipe-8.13 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #5} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\ bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\ bar]]
-test winpipe-8.14 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #6} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\" bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\\" bar]]
-test winpipe-8.15 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #7} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\" bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\\\\" bar]]
-test winpipe-8.16 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #8} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\\" bar
-} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\\" bar]]
-test winpipe-8.17 {BuildCommandLine/parse_cmdline pass-thru: special chars #1} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \{ bar
-} [list $path(echoArgs.tcl) [list foo \{ bar]]
-test winpipe-8.18 {BuildCommandLine/parse_cmdline pass-thru: special chars #2} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo \} bar
-} [list $path(echoArgs.tcl) [list foo \} bar]]
-test winpipe-8.19 {ensure parse_cmdline isn't doing wildcard replacement} {win exec} {
- exec [interpreter] $path(echoArgs.tcl) foo * makefile.?c bar
-} [list $path(echoArgs.tcl) [list foo * makefile.?c bar]]
+test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: dumped arguments are equal original} \
+-constraints {win exec} -body {
+ _testExecArgs 0 \
+ [list foo "" bar] \
+ [list foo {} bar] \
+ [list foo "\"" bar] \
+ [list foo {""} bar] \
+ [list foo "\" " bar] \
+ [list foo {a="b"} bar] \
+ [list foo {a = "b"} bar] \
+ [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}] \
+ [list foo \\ bar] \
+ [list foo \\\\ bar] \
+ [list foo \\\ \\ bar] \
+ [list foo \\\ \\\\ bar] \
+ [list foo \\\ \\\\\\ bar] \
+ [list foo \\\ \\\" bar] \
+ [list foo \\\ \\\\\" bar] \
+ [list foo \\\ \\\\\\\" bar] \
+ [list foo \{ bar] \
+ [list foo \} bar] \
+ [list foo * makefile.?c bar]
+} -result {}
+
+test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (particular)} \
+-constraints {win exec slowTest} -body {
+ _testExecArgs 1 {*}$injectList
+} -result {}
+
+test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (jointly)} \
+-constraints {win exec} -body {
+ _testExecArgs 0 \
+ [list START {*}$injectList END] \
+ [list "START\"" {*}$injectList END] \
+ [list START {*}$injectList "\"END"] \
+ [list "START\"" {*}$injectList "\"END"]
+} -result {}
+
+test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (command/jointly args)} \
+-constraints {win exec} -body {
+ _testExecArgs 2 \
+ [list START {*}$injectList END] \
+ [list "START\"" {*}$injectList END] \
+ [list START {*}$injectList "\"END"] \
+ [list "START\"" {*}$injectList "\"END"]
+} -result {}
+
+test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (random mix)} \
+-constraints {win exec} -body {
+ set lst {}
+ set maps {
+ {\&|^<>!()%}
+ {\&|^<>!()% }
+ {"\&|^<>!()%}
+ {"\&|^<>!()% }
+ {"""""\\\\\&|^<>!()%}
+ {"""""\\\\\&|^<>!()% }
+ }
+ set i 0
+ time {
+ set args {[incr i].}
+ time {
+ set map [lindex $maps [expr {int(rand()*[llength $maps])}]]
+ # be sure arg has some prefix (avoid special handling, like |& etc)
+ set a {x}
+ while {[string length $a] < 50} {
+ append a [string index $map [expr {int(rand()*[string length $map])}]]
+ }
+ lappend args $a
+ } 20
+ lappend lst $args
+ } 10
+ _testExecArgs 0 {*}$lst
+} -result {} -cleanup {
+ unset -nocomplain lst args a map maps
+}
+
+set injectList {
+ "test\"\nwhoami" "test\"\"\nwhoami"
+ "test\"\"\"\nwhoami" "test\"\"\"\"\nwhoami"
+ "test;\n&echo \"" "\"test;\n&echo \""
+ "test\";\n&echo \"" "\"test\";\n&echo \""
+ "\"\"test\";\n&echo \""
+}
+
+test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args} \
+-constraints {win exec} -body {
+ # test exe only, because currently there is no proper way to escape a new-line char resp.
+ # to supply a new-line to the batch-files within arguments (command line is truncated).
+ _testExecArgs 8 \
+ [list START {*}$injectList END] \
+ [list "START\"" {*}$injectList END] \
+ [list START {*}$injectList "\"END"] \
+ [list "START\"" {*}$injectList "\"END"]
+} -result {}
+
+test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args (batch)} \
+-constraints {win exec knownBug} -body {
+ # this will fail if executed batch-file, because currently there is no proper way to escape a new-line char.
+ _testExecArgs 0 $injectList
+} -result {}
+
+
+rename _testExecArgs {}
# restore old values for env(TMP) and env(TEMP)
@@ -445,7 +604,9 @@ removeFile more
removeFile stdout
removeFile stderr
removeFile nothing
-removeFile echoArgs.tcl
+if {[info exists path(echoArgs.tcl)]} { removeFile echoArgs.tcl }
+if {[info exists path(echoArgs.bat)]} { removeFile echoArgs.bat }
+if {[info exists path(echoArgs2.bat)]} { removeDirectory test(Dir)Check }
::tcltest::cleanupTests
return
diff --git a/tcl8.6/tools/genStubs.tcl b/tcl8.6/tools/genStubs.tcl
index 9f2c6ca..f2f410f 100644
--- a/tcl8.6/tools/genStubs.tcl
+++ b/tcl8.6/tools/genStubs.tcl
@@ -191,12 +191,28 @@ proc genStubs::declare {args} {
regsub -all "\[ \t\n\]+" [string trim $decl] " " decl
set decl [parseDecl $decl]
- foreach platform $platformList {
- if {$decl ne ""} {
- set stubs($curName,$platform,$index) $decl
- if {![info exists stubs($curName,$platform,lastNum)] \
- || ($index > $stubs($curName,$platform,lastNum))} {
- set stubs($curName,$platform,lastNum) $index
+ if {([lindex $platformList 0] eq "deprecated")} {
+ set stubs($curName,deprecated,$index) [lindex $platformList 1]
+ set stubs($curName,generic,$index) $decl
+ if {![info exists stubs($curName,generic,lastNum)] \
+ || ($index > $stubs($curName,generic,lastNum))} {
+ set stubs($curName,generic,lastNum) $index
+ }
+ } elseif {([lindex $platformList 0] eq "nostub")} {
+ set stubs($curName,nostub,$index) [lindex $platformList 1]
+ set stubs($curName,generic,$index) $decl
+ if {![info exists stubs($curName,generic,lastNum)] \
+ || ($index > $stubs($curName,generic,lastNum))} {
+ set stubs($curName,generic,lastNum) $index
+ }
+ } else {
+ foreach platform $platformList {
+ if {$decl ne ""} {
+ set stubs($curName,$platform,$index) $decl
+ if {![info exists stubs($curName,$platform,lastNum)] \
+ || ($index > $stubs($curName,$platform,lastNum))} {
+ set stubs($curName,$platform,lastNum) $index
+ }
}
}
}
@@ -455,10 +471,17 @@ proc genStubs::parseArg {arg} {
proc genStubs::makeDecl {name decl index} {
variable scspec
+ variable stubs
+ variable libraryName
lassign $decl rtype fname args
append text "/* $index */\n"
- set line "$scspec $rtype"
+ if {[info exists stubs($name,deprecated,$index)]} {
+ append text "[string toupper $libraryName]_DEPRECATED(\"$stubs($name,deprecated,$index)\")\n"
+ set line "$rtype"
+ } else {
+ set line "$scspec $rtype"
+ }
set count [expr {2 - ([string length $line] / 8)}]
append line [string range "\t\t\t" 0 $count]
set pad [expr {24 - [string length $line]}]
@@ -569,11 +592,17 @@ proc genStubs::makeMacro {name decl index} {
proc genStubs::makeSlot {name decl index} {
lassign $decl rtype fname args
+ variable stubs
set lfname [string tolower [string index $fname 0]]
append lfname [string range $fname 1 end]
set text " "
+ if {[info exists stubs($name,deprecated,$index)]} {
+ append text "TCL_DEPRECATED_API(\"$stubs($name,deprecated,$index)\") "
+ } elseif {[info exists stubs($name,nostub,$index)]} {
+ append text "TCL_DEPRECATED_API(\"$stubs($name,nostub,$index)\") "
+ }
if {$args eq ""} {
append text $rtype " *" $lfname "; /* $index */\n"
return $text
@@ -682,7 +711,13 @@ proc genStubs::forAllStubs {name slotProc onAll textVar
for {set i 0} {$i <= $lastNum} {incr i} {
set slots [array names stubs $name,*,$i]
set emit 0
- if {[info exists stubs($name,generic,$i)]} {
+ if {[info exists stubs($name,deprecated,$i)]} {
+ append text [$slotProc $name $stubs($name,generic,$i) $i]
+ set emit 1
+ } elseif {[info exists stubs($name,nostub,$i)]} {
+ append text [$slotProc $name $stubs($name,generic,$i) $i]
+ set emit 1
+ } elseif {[info exists stubs($name,generic,$i)]} {
if {[llength $slots] > 1} {
puts stderr "conflicting generic and platform entries:\
$name $i"
diff --git a/tcl8.6/tools/uniClass.tcl b/tcl8.6/tools/uniClass.tcl
index 9b4819d..86ec931 100644
--- a/tcl8.6/tools/uniClass.tcl
+++ b/tcl8.6/tools/uniClass.tcl
@@ -20,7 +20,7 @@ proc emitRange {first last} {
set extranges 1
set numranges 0
set ranges [string trimright $ranges " \n\r\t,"]
- append ranges "\n#if TCL_UTF_MAX > 4\n ,"
+ append ranges "\n#if CHRBITS > 16\n ,"
}
append ranges [format "{0x%x, 0x%x}, " \
$first $last]
@@ -33,7 +33,7 @@ proc emitRange {first last} {
set extchars 1
set numchars 0
set chars [string trimright $chars " \n\r\t,"]
- append chars "\n#if TCL_UTF_MAX > 4\n ,"
+ append chars "\n#if CHRBITS > 16\n ,"
}
append chars [format "0x%x, " $first]
incr numchars
@@ -66,7 +66,7 @@ proc genTable {type} {
for {set i 0} {$i <= 0x10ffff} {incr i} {
if {$i == 0xd800} {
# Skip surrogates
- set i 0xdc00
+ set i 0xe000
}
if {[string is $type [format %c $i]]} {
if {$i == ($last + 1)} {
diff --git a/tcl8.6/tools/uniParse.tcl b/tcl8.6/tools/uniParse.tcl
index 8125790..c712e62 100644
--- a/tcl8.6/tools/uniParse.tcl
+++ b/tcl8.6/tools/uniParse.tcl
@@ -272,6 +272,7 @@ static const unsigned char groupMap\[\] = {"
* 100 = subtract delta for title/upper
* 101 = sub delta for upper, sub 1 for title
* 110 = sub delta for upper, add delta for lower
+ * 111 = subtract delta for upper
*
* Bits 8-31 Case delta: delta for case conversions. This should be the
* highest field so we can easily sign extend.
@@ -309,10 +310,14 @@ static const int groups\[\] = {"
}
}
} elseif {$toupper} {
- # subtract delta for upper, add delta for lower
- set case 6
set delta $toupper
- if {$tolower != $toupper} {
+ if {$tolower == $toupper} {
+ # subtract delta for upper, add delta for lower
+ set case 6
+ } elseif {!$tolower} {
+ # subtract delta for upper
+ set case 7
+ } else {
error "New case conversion type needed: $toupper $tolower $totitle"
}
} elseif {$tolower} {
diff --git a/tcl8.6/unix/Makefile.in b/tcl8.6/unix/Makefile.in
index 29c051d..aaff7ae 100644
--- a/tcl8.6/unix/Makefile.in
+++ b/tcl8.6/unix/Makefile.in
@@ -262,7 +262,9 @@ GDB = gdb
TRACE = strace
TRACE_OPTS =
VALGRIND = valgrind
-VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high --leak-check=yes --show-reachable=yes -v
+VALGRINDARGS = --tool=memcheck --num-callers=24 \
+ --leak-resolution=high --leak-check=yes --show-reachable=yes -v \
+ --suppressions=$(TOOL_DIR)/valgrind_suppress
#--------------------------------------------------------------------------
# The information below should be usable as is. The configure script won't
@@ -840,8 +842,8 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \
done;
- @echo "Installing package http 2.8.12 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.12.tm;
+ @echo "Installing package http 2.9.0 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.9.0.tm;
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/";
@for i in $(TOP_DIR)/library/opt/*.tcl ; \
do \
@@ -849,8 +851,8 @@ install-libraries: libraries
done;
@echo "Installing package msgcat 1.6.1 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.6.1.tm;
- @echo "Installing package tcltest 2.4.1 as a Tcl Module";
- @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm;
+ @echo "Installing package tcltest 2.5.0 as a Tcl Module";
+ @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.5.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;
@@ -1630,9 +1632,6 @@ tclXtTest.o: $(UNIX_DIR)/tclXtTest.c
# relocatable.
#--------------------------------------------------------------------------
-fixstrtod.o: $(COMPAT_DIR)/fixstrtod.c
- $(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/fixstrtod.c
-
opendir.o: $(COMPAT_DIR)/opendir.c
$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/opendir.c
@@ -1648,9 +1647,6 @@ strncasecmp.o: $(COMPAT_DIR)/strncasecmp.c
strstr.o: $(COMPAT_DIR)/strstr.c
$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strstr.c
-strtod.o: $(COMPAT_DIR)/strtod.c
- $(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strtod.c
-
strtol.o: $(COMPAT_DIR)/strtol.c
$(CC) -c $(STUB_CC_SWITCHES) $(COMPAT_DIR)/strtol.c
diff --git a/tcl8.6/unix/configure b/tcl8.6/unix/configure
index 3d7fbf4..34669af 100755
--- a/tcl8.6/unix/configure
+++ b/tcl8.6/unix/configure
@@ -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=".8"
+TCL_PATCH_LEVEL=".9"
VERSION=${TCL_VERSION}
EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
@@ -4840,8 +4840,6 @@ _ACEOF
#--------------------------------------------------------------------
# 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
@@ -4940,68 +4938,6 @@ 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
@@ -7575,7 +7511,7 @@ fi
fi
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -8783,7 +8719,7 @@ fi
BSD/OS*) ;;
CYGWIN_*|MINGW32_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
*) SHLIB_CFLAGS="-fPIC" ;;
@@ -9581,6 +9517,70 @@ _ACEOF
fi
+ echo "$as_me:$LINENO: checking for DIR64" >&5
+echo $ECHO_N "checking for DIR64... $ECHO_C" >&6
+if test "${tcl_cv_DIR64+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; DIR64 d = opendir64(".");
+ p = readdir64(d); rewinddir64(d); closedir64(d);
+ ;
+ 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_DIR64=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+tcl_cv_DIR64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5
+echo "${ECHO_T}$tcl_cv_DIR64" >&6
+ if test "x${tcl_cv_DIR64}" = "xyes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DIR64 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
@@ -14983,358 +14983,6 @@ esac
#--------------------------------------------------------------------
-# Check for the strtod function. This is tricky because in some
-# versions of Linux strtod mis-parses strings starting with "+".
-#--------------------------------------------------------------------
-
-
- echo "$as_me:$LINENO: checking for strtod" >&5
-echo $ECHO_N "checking for strtod... $ECHO_C" >&6
-if test "${ac_cv_func_strtod+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 strtod to an innocuous variant, in case <limits.h> declares strtod.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strtod innocuous_strtod
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strtod (); 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 strtod
-
-/* 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 strtod ();
-/* 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_strtod) || defined (__stub___strtod)
-choke me
-#else
-char (*f) () = strtod;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strtod;
- ;
- 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_strtod=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strtod=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
-echo "${ECHO_T}$ac_cv_func_strtod" >&6
-if test $ac_cv_func_strtod = yes; then
- tcl_ok=1
-else
- tcl_ok=0
-fi
-
- if test "$tcl_ok" = 1; then
- echo "$as_me:$LINENO: checking proper strtod implementation" >&5
-echo $ECHO_N "checking proper strtod implementation... $ECHO_C" >&6
-if test "${tcl_cv_strtod_unbroken+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- tcl_cv_strtod_unbroken=unknown
-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() {
- extern double strtod();
- char *term, *string = " +69";
- exit(strtod(string,&term) != 69 || term != string+4);
-}
-_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_strtod_unbroken=ok
-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_strtod_unbroken=broken
-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_strtod_unbroken" >&5
-echo "${ECHO_T}$tcl_cv_strtod_unbroken" >&6
- if test "$tcl_cv_strtod_unbroken" = "ok"; then
- tcl_ok=1
- else
- tcl_ok=0
- fi
- fi
- if test "$tcl_ok" = 0; then
- case $LIBOBJS in
- "strtod.$ac_objext" | \
- *" strtod.$ac_objext" | \
- "strtod.$ac_objext "* | \
- *" strtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;;
-esac
-
- USE_COMPAT=1
- fi
-
-
-#--------------------------------------------------------------------
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" that corrects the error.
-#--------------------------------------------------------------------
-
-
- echo "$as_me:$LINENO: checking for strtod" >&5
-echo $ECHO_N "checking for strtod... $ECHO_C" >&6
-if test "${ac_cv_func_strtod+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 strtod to an innocuous variant, in case <limits.h> declares strtod.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strtod innocuous_strtod
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strtod (); 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 strtod
-
-/* 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 strtod ();
-/* 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_strtod) || defined (__stub___strtod)
-choke me
-#else
-char (*f) () = strtod;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strtod;
- ;
- 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_strtod=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strtod=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
-echo "${ECHO_T}$ac_cv_func_strtod" >&6
-if test $ac_cv_func_strtod = yes; then
- tcl_strtod=1
-else
- tcl_strtod=0
-fi
-
- if test "$tcl_strtod" = 1; then
- echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5
-echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6
-if test "${tcl_cv_strtod_buggy+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- if test "$cross_compiling" = yes; then
- tcl_cv_strtod_buggy=buggy
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }
-_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_strtod_buggy=ok
-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_strtod_buggy=buggy
-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_strtod_buggy" >&5
-echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6
- if test "$tcl_cv_strtod_buggy" = buggy; then
- case $LIBOBJS in
- "fixstrtod.$ac_objext" | \
- *" fixstrtod.$ac_objext" | \
- "fixstrtod.$ac_objext "* | \
- *" fixstrtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;;
-esac
-
- USE_COMPAT=1
-
-cat >>confdefs.h <<\_ACEOF
-#define strtod fixstrtod
-_ACEOF
-
- fi
- fi
-
-
-#--------------------------------------------------------------------
# Check for various typedefs and provide substitutes if
# they don't exist.
#--------------------------------------------------------------------
diff --git a/tcl8.6/unix/configure.in b/tcl8.6/unix/configure.in
index bfa2ef7..61e408f 100755
--- a/tcl8.6/unix/configure.in
+++ b/tcl8.6/unix/configure.in
@@ -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=".8"
+TCL_PATCH_LEVEL=".9"
VERSION=${TCL_VERSION}
EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"}
@@ -359,26 +359,6 @@ SC_TCL_CHECK_BROKEN_FUNC(strtoul, [
])
#--------------------------------------------------------------------
-# Check for the strtod function. This is tricky because in some
-# versions of Linux strtod mis-parses strings starting with "+".
-#--------------------------------------------------------------------
-
-SC_TCL_CHECK_BROKEN_FUNC(strtod, [
- extern double strtod();
- char *term, *string = " +69";
- exit(strtod(string,&term) != 69 || term != string+4);
-])
-
-#--------------------------------------------------------------------
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" that corrects the error.
-#--------------------------------------------------------------------
-
-SC_BUGGY_STRTOD
-
-#--------------------------------------------------------------------
# Check for various typedefs and provide substitutes if
# they don't exist.
#--------------------------------------------------------------------
diff --git a/tcl8.6/unix/tcl.m4 b/tcl8.6/unix/tcl.m4
index 6ca2047..1953798 100644
--- a/tcl8.6/unix/tcl.m4
+++ b/tcl8.6/unix/tcl.m4
@@ -91,11 +91,13 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [
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/contrib/lib 2>/dev/null` \
`ls -d /usr/local/lib 2>/dev/null` \
+ `ls -d /usr/contrib/lib 2>/dev/null` \
`ls -d /usr/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
; do
if test -f "$i/tclConfig.sh" ; then
ac_cv_c_tclconfig="`(cd $i; pwd)`"
@@ -224,8 +226,11 @@ AC_DEFUN([SC_PATH_TKCONFIG], [
`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/pkg/lib 2>/dev/null` \
`ls -d /usr/lib 2>/dev/null` \
`ls -d /usr/lib64 2>/dev/null` \
+ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
+ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
; do
if test -f "$i/tkConfig.sh" ; then
ac_cv_c_tkconfig="`(cd $i; pwd)`"
@@ -1511,7 +1516,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
LDFLAGS="$LDFLAGS -pthread"
])
;;
- FreeBSD-*)
+ DragonFly-*|FreeBSD-*)
# This configuration from FreeBSD Ports.
SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared"
@@ -2007,7 +2012,7 @@ dnl # preprocessing tests use only CPPFLAGS.
BSD/OS*) ;;
CYGWIN_*|MINGW32_*) ;;
IRIX*) ;;
- NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
+ NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
Darwin-*) ;;
SCO_SV-3.2*) ;;
*) SHLIB_CFLAGS="-fPIC" ;;
@@ -2393,59 +2398,6 @@ AC_DEFUN([SC_TIME_HANDLER], [
])
#--------------------------------------------------------------------
-# SC_BUGGY_STRTOD
-#
-# Under Solaris 2.4, strtod returns the wrong value for the
-# terminating character under some conditions. Check for this
-# and if the problem exists use a substitute procedure
-# "fixstrtod" (provided by Tcl) that corrects the error.
-# Also, on Compaq's Tru64 Unix 5.0,
-# strtod(" ") returns 0.0 instead of a failure to convert.
-#
-# Arguments:
-# none
-#
-# Results:
-#
-# Might defines some of the following vars:
-# strtod (=fixstrtod)
-#
-#--------------------------------------------------------------------
-
-AC_DEFUN([SC_BUGGY_STRTOD], [
- AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
- if test "$tcl_strtod" = 1; then
- AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
- AC_TRY_RUN([
- extern double strtod();
- int main() {
- char *infString="Inf", *nanString="NaN", *spaceString=" ";
- char *term;
- double value;
- value = strtod(infString, &term);
- if ((term != infString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(nanString, &term);
- if ((term != nanString) && (term[-1] == 0)) {
- exit(1);
- }
- value = strtod(spaceString, &term);
- if (term == (spaceString+1)) {
- exit(1);
- }
- exit(0);
- }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
- tcl_cv_strtod_buggy=buggy)])
- if test "$tcl_cv_strtod_buggy" = buggy; then
- AC_LIBOBJ([fixstrtod])
- USE_COMPAT=1
- AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
- fi
- fi
-])
-
-#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
# Search for the libraries needed to link the Tcl shell.
@@ -2470,12 +2422,9 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
#--------------------------------------------------------------------
# On a few very rare systems, all of the libm.a stuff is
# already in libc.a. Set compiler flags accordingly.
- # Also, Linux requires the "ieee" library for math to work
- # right (and it must appear before "-lm").
#--------------------------------------------------------------------
AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
- AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
#--------------------------------------------------------------------
# Interactive UNIX requires -linet instead of -lsocket, plus it
@@ -2579,7 +2528,7 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
# Might define the following vars:
# TCL_WIDE_INT_IS_LONG
# TCL_WIDE_INT_TYPE
-# HAVE_STRUCT_DIRENT64
+# HAVE_STRUCT_DIRENT64, HAVE_DIR64
# HAVE_STRUCT_STAT64
# HAVE_TYPE_OFF64_T
#
@@ -2615,6 +2564,15 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [
AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
fi
+ AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64(".");
+ p = readdir64(d); rewinddir64(d); closedir64(d);],
+ tcl_cv_DIR64=yes,tcl_cv_DIR64=no)])
+ if test "x${tcl_cv_DIR64}" = "xyes" ; then
+ AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
+ fi
+
AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
diff --git a/tcl8.6/unix/tcl.spec b/tcl8.6/unix/tcl.spec
index 09920dd..cc36790 100644
--- a/tcl8.6/unix/tcl.spec
+++ b/tcl8.6/unix/tcl.spec
@@ -4,7 +4,7 @@
Name: tcl
Summary: Tcl scripting language development environment
-Version: 8.6.8
+Version: 8.6.9
Release: 2
License: BSD
Group: Development/Languages
diff --git a/tcl8.6/unix/tclConfig.h.in b/tcl8.6/unix/tclConfig.h.in
index a4ab3e5..a26a48f 100644
--- a/tcl8.6/unix/tclConfig.h.in
+++ b/tcl8.6/unix/tclConfig.h.in
@@ -31,6 +31,9 @@
/* Is the cpuid instruction usable? */
#undef HAVE_CPUID
+/* Is 'DIR64' in <sys/types.h>? */
+#undef HAVE_DIR64
+
/* Define to 1 if you have the `freeaddrinfo' function. */
#undef HAVE_FREEADDRINFO
@@ -493,9 +496,6 @@
/* Define as int if socklen_t is not available */
#undef socklen_t
-/* Do we want to use the strtod() in compat? */
-#undef strtod
-
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
diff --git a/tcl8.6/unix/tclUnixFCmd.c b/tcl8.6/unix/tclUnixFCmd.c
index a1a409e..ae20ee0 100644
--- a/tcl8.6/unix/tclUnixFCmd.c
+++ b/tcl8.6/unix/tclUnixFCmd.c
@@ -369,13 +369,13 @@ DoRenameFile(
if (errno == EINVAL && haveRealpath) {
char srcPath[MAXPATHLEN], dstPath[MAXPATHLEN];
- DIR *dirPtr;
+ TclDIR *dirPtr;
Tcl_DirEntry *dirEntPtr;
if ((Realpath((char *) src, srcPath) != NULL) /* INTL: Native. */
&& (Realpath((char *) dst, dstPath) != NULL) /* INTL: Native */
&& (strncmp(srcPath, dstPath, strlen(srcPath)) != 0)) {
- dirPtr = opendir(dst); /* INTL: Native. */
+ dirPtr = TclOSopendir(dst); /* INTL: Native. */
if (dirPtr != NULL) {
while (1) {
dirEntPtr = TclOSreaddir(dirPtr); /* INTL: Native. */
@@ -385,11 +385,11 @@ DoRenameFile(
if ((strcmp(dirEntPtr->d_name, ".") != 0) &&
(strcmp(dirEntPtr->d_name, "..") != 0)) {
errno = EEXIST;
- closedir(dirPtr);
+ TclOSclosedir(dirPtr);
return TCL_ERROR;
}
}
- closedir(dirPtr);
+ TclOSclosedir(dirPtr);
}
}
errno = EINVAL;
@@ -965,7 +965,7 @@ TraverseUnixTree(
#ifndef HAVE_FTS
int numProcessed = 0;
Tcl_DirEntry *dirEntPtr;
- DIR *dirPtr;
+ TclDIR *dirPtr;
#else
const char *paths[2] = {NULL, NULL};
FTS *fts = NULL;
@@ -990,7 +990,7 @@ TraverseUnixTree(
errorPtr);
}
#ifndef HAVE_FTS
- dirPtr = opendir(source); /* INTL: Native. */
+ dirPtr = TclOSopendir(source); /* INTL: Native. */
if (dirPtr == NULL) {
/*
* Can't read directory
@@ -1002,7 +1002,7 @@ TraverseUnixTree(
result = traverseProc(sourcePtr, targetPtr, &statBuf, DOTREE_PRED,
errorPtr);
if (result != TCL_OK) {
- closedir(dirPtr);
+ TclOSclosedir(dirPtr);
return result;
}
@@ -1052,11 +1052,11 @@ TraverseUnixTree(
* NULL-return that may a symptom of a buggy readdir.
*/
- rewinddir(dirPtr);
+ TclOSrewinddir(dirPtr);
numProcessed = 0;
}
}
- closedir(dirPtr);
+ TclOSclosedir(dirPtr);
/*
* Strip off the trailing slash we added
diff --git a/tcl8.6/unix/tclUnixFile.c b/tcl8.6/unix/tclUnixFile.c
index 7ffbf8d..5684b16 100644
--- a/tcl8.6/unix/tclUnixFile.c
+++ b/tcl8.6/unix/tclUnixFile.c
@@ -259,7 +259,7 @@ TclpMatchInDirectory(
Tcl_DecrRefCount(tailPtr);
Tcl_DecrRefCount(fileNamePtr);
} else {
- DIR *d;
+ TclDIR *d;
Tcl_DirEntry *entryPtr;
const char *dirName;
int dirLength, nativeDirLen;
@@ -309,7 +309,7 @@ TclpMatchInDirectory(
return TCL_OK;
}
- d = opendir(native); /* INTL: Native. */
+ d = TclOSopendir(native); /* INTL: Native. */
if (d == NULL) {
Tcl_DStringFree(&ds);
if (interp != NULL) {
@@ -387,7 +387,7 @@ TclpMatchInDirectory(
}
}
- closedir(d);
+ TclOSclosedir(d);
Tcl_DStringFree(&ds);
Tcl_DStringFree(&dsOrig);
Tcl_DecrRefCount(fileNamePtr);
diff --git a/tcl8.6/unix/tclUnixPort.h b/tcl8.6/unix/tclUnixPort.h
index ba56089..af0b4dc 100644
--- a/tcl8.6/unix/tclUnixPort.h
+++ b/tcl8.6/unix/tclUnixPort.h
@@ -57,12 +57,23 @@
*/
#ifdef HAVE_STRUCT_DIRENT64
-typedef struct dirent64 Tcl_DirEntry;
+typedef struct dirent64 Tcl_DirEntry;
# define TclOSreaddir readdir64
#else
-typedef struct dirent Tcl_DirEntry;
+typedef struct dirent Tcl_DirEntry;
# define TclOSreaddir readdir
#endif
+#ifdef HAVE_DIR64
+typedef DIR64 TclDIR;
+# define TclOSopendir opendir64
+# define TclOSrewinddir rewinddir64
+# define TclOSclosedir closedir64
+#else
+typedef DIR TclDIR;
+# define TclOSopendir opendir
+# define TclOSrewinddir rewinddir
+# define TclOSclosedir closedir
+#endif
#ifdef HAVE_TYPE_OFF64_T
typedef off64_t Tcl_SeekOffset;
@@ -87,8 +98,8 @@ typedef off_t Tcl_SeekOffset;
typedef unsigned short WCHAR;
__declspec(dllimport) extern __stdcall int GetModuleHandleExW(unsigned int, const char *, void *);
__declspec(dllimport) extern __stdcall int GetModuleFileNameW(void *, const char *, int);
- __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const char *, int,
- const char *, int, const char *, const char *);
+ __declspec(dllimport) extern __stdcall int WideCharToMultiByte(int, int, const void *, int,
+ char *, int, const char *, void *);
__declspec(dllimport) extern __stdcall int MultiByteToWideChar(int, int, const char *, int,
WCHAR *, int);
__declspec(dllimport) extern __stdcall void OutputDebugStringW(const WCHAR *);
diff --git a/tcl8.6/unix/tclUnixSock.c b/tcl8.6/unix/tclUnixSock.c
index e418ff0..90c72c0 100644
--- a/tcl8.6/unix/tclUnixSock.c
+++ b/tcl8.6/unix/tclUnixSock.c
@@ -1099,7 +1099,7 @@ TcpGetHandleProc(
* TcpAsyncCallback --
*
* Called by the event handler that TcpConnect sets up internally for
- * [socket -async] to get notified when the asyncronous connection
+ * [socket -async] to get notified when the asynchronous connection
* attempt has succeeded or failed.
*
* ----------------------------------------------------------------------
@@ -1132,7 +1132,7 @@ TcpAsyncCallback(
*
* Remarks:
* A single host name may resolve to more than one IP address, e.g. for
- * an IPv4/IPv6 dual stack host. For handling asyncronously connecting
+ * an IPv4/IPv6 dual stack host. For handling asynchronously connecting
* sockets in the background for such hosts, this function can act as a
* coroutine. On the first call, it sets up the control variables for the
* two nested loops over the local and remote addresses. Once the first
@@ -1140,7 +1140,7 @@ TcpAsyncCallback(
* event handler for that socket, and returns. When the callback occurs,
* control is transferred to the "reenter" label, right after the initial
* return and the loops resume as if they had never been interrupted.
- * For syncronously connecting sockets, the loops work the usual way.
+ * For synchronously connecting sockets, the loops work the usual way.
*
* ----------------------------------------------------------------------
*/
diff --git a/tcl8.6/unix/tclUnixThrd.c b/tcl8.6/unix/tclUnixThrd.c
index 9757e4e..0609230 100644
--- a/tcl8.6/unix/tclUnixThrd.c
+++ b/tcl8.6/unix/tclUnixThrd.c
@@ -316,7 +316,7 @@ TclpInitUnlock(void)
* in finalization; it is hidden during creation of the objects.
*
* This lock must be different than the initLock because the initLock is
- * held during creation of syncronization objects.
+ * held during creation of synchronization objects.
*
* Results:
* None.
@@ -407,7 +407,7 @@ Tcl_GetAllocMutex(void)
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
+ * May block the current thread. The mutex is acquired when this returns.
* Will allocate memory for a pthread_mutex_t and initialize this the
* first time this Tcl_Mutex is used.
*
@@ -511,7 +511,7 @@ TclpFinalizeMutex(
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
+ * May block the current thread. The mutex is acquired when this returns.
* Will allocate memory for a pthread_mutex_t and initialize this the
* first time this Tcl_Mutex is used.
*
@@ -653,7 +653,7 @@ TclpFinalizeCondition(
Tcl_DirEntry *
TclpReaddir(
- DIR * dir)
+ TclDIR * dir)
{
return TclOSreaddir(dir);
}
diff --git a/tcl8.6/win/Makefile.in b/tcl8.6/win/Makefile.in
index 633a9f5..9d955cd 100644
--- a/tcl8.6/win/Makefile.in
+++ b/tcl8.6/win/Makefile.in
@@ -651,8 +651,8 @@ install-libraries: libraries install-tzdata install-msgs
do \
$(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \
done;
- @echo "Installing package http 2.8.12 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.12.tm;
+ @echo "Installing package http 2.9.0 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.9.0.tm;
@echo "Installing library opt0.4 directory";
@for j in $(ROOT_DIR)/library/opt/*.tcl; \
do \
@@ -660,8 +660,8 @@ install-libraries: libraries install-tzdata install-msgs
done;
@echo "Installing package msgcat 1.6.1 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.1.tm;
- @echo "Installing package tcltest 2.4.1 as a Tcl Module";
- @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.1.tm;
+ @echo "Installing package tcltest 2.5.0 as a Tcl Module";
+ @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.5.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";
@@ -712,15 +712,15 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE)
TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
./$(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.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32)
+ package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
+ package ifneeded registry 1.3.3 [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.2 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT)
+ package ifneeded dde 1.4.1 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
+ package ifneeded registry 1.3.3 [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`
diff --git a/tcl8.6/win/configure b/tcl8.6/win/configure
index 691f42b..3024594 100755
--- a/tcl8.6/win/configure
+++ b/tcl8.6/win/configure
@@ -1311,7 +1311,7 @@ SHELL=/bin/sh
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".8"
+TCL_PATCH_LEVEL=".9"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -4372,7 +4372,7 @@ if test "$tcl_ok" = "yes"; then
ZLIB_DLL_FILE=\${ZLIB_DLL_FILE}
- if test "$do64bit" = "yes"; then
+ if test "$do64bit" != "no"; then
if test "$GCC" == "yes"; then
@@ -5132,8 +5132,8 @@ eval "TCL_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TCL_STUB_LIB_FILE}\""
eval "TCL_STUB_LIB_PATH=\"${libdir}/${TCL_STUB_LIB_FILE}\""
eval "TCL_LIB_FILE=\"${LIBPREFIX}tcl${VER}${LIBSUFFIX}\""
-eval "TCL_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` -ltcl${VER}${LIBFLAGSUFFIX}\""
-eval "TCL_LIB_SPEC=\"-L${libdir} -ltcl${VER}${LIBFLAGSUFFIX}\""
+eval "TCL_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` -ltcl${VER}${FLAGSUFFIX}\""
+eval "TCL_LIB_SPEC=\"-L${libdir} -ltcl${VER}${FLAGSUFFIX}\""
# Install time header dir can be set via --includedir
eval "TCL_INCLUDE_SPEC=\"-I${includedir}\""
diff --git a/tcl8.6/win/configure.in b/tcl8.6/win/configure.in
index 5fc17a3..511cb39 100644
--- a/tcl8.6/win/configure.in
+++ b/tcl8.6/win/configure.in
@@ -14,7 +14,7 @@ SHELL=/bin/sh
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
-TCL_PATCH_LEVEL=".8"
+TCL_PATCH_LEVEL=".9"
VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
TCL_DDE_VERSION=1.4
@@ -128,7 +128,7 @@ AS_IF([test "${enable_shared+set}" = "set"], [
])
AS_IF([test "$tcl_ok" = "yes"], [
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
- AS_IF([test "$do64bit" = "yes"], [
+ AS_IF([test "$do64bit" != "no"], [
AS_IF([test "$GCC" == "yes"],[
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a])
], [
diff --git a/tcl8.6/win/makefile.vc b/tcl8.6/win/makefile.vc
index ff31e96..0e1e1fd 100644
--- a/tcl8.6/win/makefile.vc
+++ b/tcl8.6/win/makefile.vc
@@ -384,8 +384,8 @@ test: test-core test-pkgs
test-core: setup $(TCLTEST) dlls $(CAT32)
set TCL_LIBRARY=$(ROOT:\=/)/library
$(DEBUGGER) $(TCLTEST) "$(ROOT:\=/)/tests/all.tcl" $(TESTFLAGS) -loadfile <<
- package ifneeded dde 1.4.0 [list load "$(TCLDDELIB:\=/)" dde]
- package ifneeded registry 1.3.2 [list load "$(TCLREGLIB:\=/)" registry]
+ package ifneeded dde 1.4.1 [list load "$(TCLDDELIB:\=/)" dde]
+ package ifneeded registry 1.3.3 [list load "$(TCLREGLIB:\=/)" registry]
<<
runtest: setup $(TCLTEST) dlls $(CAT32)
diff --git a/tcl8.6/win/nmakehlp.c b/tcl8.6/win/nmakehlp.c
index 025bb99..b759020 100644
--- a/tcl8.6/win/nmakehlp.c
+++ b/tcl8.6/win/nmakehlp.c
@@ -14,13 +14,8 @@
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
-#define NO_SHLWAPI_GDI
-#define NO_SHLWAPI_STREAM
-#define NO_SHLWAPI_REG
-#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
-#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>
@@ -74,7 +69,7 @@ main(
char msg[300];
DWORD dwWritten;
int chars;
- char *s;
+ const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
@@ -688,6 +683,17 @@ SubstituteFile(
return 0;
}
+BOOL FileExists(LPCTSTR szPath)
+{
+#ifndef INVALID_FILE_ATTRIBUTES
+ #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+#endif
+ DWORD pathAttr = GetFileAttributes(szPath);
+ return (pathAttr != INVALID_FILE_ATTRIBUTES &&
+ !(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+
/*
* QualifyPath --
*
@@ -701,13 +707,8 @@ QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
- char szTmp[MAX_PATH + 1];
- char *p;
- GetCurrentDirectory(MAX_PATH, szCwd);
- while ((p = strchr(szPath, '/')) && *p)
- *p = '\\';
- PathCombine(szTmp, szCwd, szPath);
- PathCanonicalize(szCwd, szTmp);
+
+ GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
@@ -765,7 +766,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath)
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
- if (PathFileExists(path)) {
+ if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
diff --git a/tcl8.6/win/rules-ext.vc b/tcl8.6/win/rules-ext.vc
index 58c70fa..531e070 100644
--- a/tcl8.6/win/rules-ext.vc
+++ b/tcl8.6/win/rules-ext.vc
@@ -35,7 +35,7 @@ macro to the name of the project makefile.
!endif
# First locate the Tcl directory that we are working with.
-!ifdef TCLDIR
+!if "$(TCLDIR)" != ""
_RULESDIR = $(TCLDIR:/=\)
diff --git a/tcl8.6/win/rules.vc b/tcl8.6/win/rules.vc
index 7fc51c1..8db4752 100644
--- a/tcl8.6/win/rules.vc
+++ b/tcl8.6/win/rules.vc
@@ -24,7 +24,7 @@ _RULES_VC = 1
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
-RULES_VERSION_MINOR = 0
+RULES_VERSION_MINOR = 2
# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
@@ -393,7 +393,7 @@ MSG = ^
!endif
-# If INSTALLDIR set to tcl installation root dir then reset to the
+# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
@@ -535,7 +535,6 @@ NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
-!message *** Using $(NMAKEHLPC)
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif
@@ -590,7 +589,6 @@ FPOPTS = $(FPOPTS) -QI0f
OPTIMIZATIONS = $(FPOPTS)
!if [nmakehlp -c -O2]
-!message *** Compiler has 'Optimizations'
OPTIMIZING = 1
OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
!else
@@ -1077,12 +1075,24 @@ TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
!if $(TCLINSTALL) # Building against an installed Tcl
+# When building extensions, we need to locate tclsh. Depending on version
+# of Tcl we are building against, this may or may not have a "t" suffix.
+# Try various possibilities in turn.
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist("$(TCLSH)") && $(TCL_THREADS)
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
+!if !exist("$(TCLSH)")
+TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
+
TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
TCL_LIBRARY = $(_TCLDIR)\lib
TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
@@ -1095,8 +1105,16 @@ TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
+!if !exist($(TCLSH))
+TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!endif
TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
+!endif
TCL_LIBRARY = $(_TCLDIR)\library
TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
@@ -1140,11 +1158,23 @@ TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
WISH = $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+!endif
TK_INCLUDES = -I"$(_TKDIR)\include"
!else # Building against Tk sources
WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+!endif
TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif # TKINSTALL
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
@@ -1179,7 +1209,7 @@ RESFILE = $(TMP_DIR)\$(PROJECT).res
# SCRIPT_INSTALL_DIR - where scripts should be installed
# INCLUDE_INSTALL_DIR - where C include files should be installed
# DEMO_INSTALL_DIR - where demos should be installed
-# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
+# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
!if $(DOING_TCL) || $(DOING_TK)
LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
@@ -1201,7 +1231,7 @@ BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
-INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
+INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include
!endif
@@ -1717,7 +1747,6 @@ TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!message *** Output directory will be '$(OUT_DIR)'
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
+!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
!endif # ifdef _RULES_VC
diff --git a/tcl8.6/win/tclAppInit.c b/tcl8.6/win/tclAppInit.c
index e06eaf5..2236da3 100644
--- a/tcl8.6/win/tclAppInit.c
+++ b/tcl8.6/win/tclAppInit.c
@@ -35,8 +35,10 @@ extern Tcl_PackageInitProc Dde_Init;
extern Tcl_PackageInitProc Dde_SafeInit;
#endif
-#ifdef TCL_BROKEN_MAINARGS
+#if defined(__GNUC__) || defined(TCL_BROKEN_MAINARGS)
int _CRT_glob = 0;
+#endif /* __GNUC__ || TCL_BROKEN_MAINARGS */
+#ifdef TCL_BROKEN_MAINARGS
static void setargv(int *argcPtr, TCHAR ***argvPtr);
#endif /* TCL_BROKEN_MAINARGS */
diff --git a/tcl8.6/win/tclWin32Dll.c b/tcl8.6/win/tclWin32Dll.c
index 84c7a97..6fc2401 100644
--- a/tcl8.6/win/tclWin32Dll.c
+++ b/tcl8.6/win/tclWin32Dll.c
@@ -33,8 +33,6 @@ static int platformId; /* Running under NT, or 95/98? */
#define cpuid __asm __emit 0fh __asm __emit 0a2h
#endif
-static Tcl_Encoding winTCharEncoding = NULL;
-
/*
* The following declaration is for the VC++ DLL entry point.
*/
@@ -49,7 +47,7 @@ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
*/
typedef struct MountPointMap {
- const TCHAR *volumeName; /* Native wide string volume name. */
+ TCHAR *volumeName; /* Native wide string volume name. */
TCHAR driveLetter; /* Drive letter corresponding to the volume
* name. */
struct MountPointMap *nextPtr;
@@ -199,8 +197,6 @@ TclWinInit(
if (platformId == VER_PLATFORM_WIN32_WINDOWS) {
Tcl_Panic("Windows 9x is not a supported platform");
}
-
- TclWinResetInterfaces();
}
/*
@@ -266,7 +262,7 @@ TclWinNoBackslash(
*
* TclpSetInterfaces --
*
- * A helper proc that initializes winTCharEncoding.
+ * A helper proc.
*
* Results:
* None.
@@ -280,8 +276,6 @@ TclWinNoBackslash(
void
TclpSetInterfaces(void)
{
- TclWinResetInterfaces();
- winTCharEncoding = Tcl_GetEncoding(NULL, "unicode");
}
/*
@@ -309,8 +303,6 @@ TclWinEncodingsCleanup(void)
{
MountPointMap *dlIter, *dlIter2;
- TclWinResetInterfaces();
-
/*
* Clean up the mount point map.
*/
@@ -344,10 +336,6 @@ TclWinEncodingsCleanup(void)
void
TclWinResetInterfaces(void)
{
- if (winTCharEncoding != NULL) {
- Tcl_FreeEncoding(winTCharEncoding);
- winTCharEncoding = NULL;
- }
}
/*
@@ -513,39 +501,32 @@ TclWinDriveLetterForVolMountPoint(
*
* Tcl_WinUtfToTChar, Tcl_WinTCharToUtf --
*
- * Convert between UTF-8 and Unicode when running Windows NT or the
- * current ANSI code page when running Windows 95.
+ * Convert between UTF-8 and Unicode when running Windows.
*
- * On Mac, Unix, and Windows 95, all strings exchanged between Tcl and
- * the OS are "char" oriented. We need only one Tcl_Encoding to convert
- * between UTF-8 and the system's native encoding. We use NULL to
- * represent that encoding.
+ * On Mac and Unix, all strings exchanged between Tcl and the OS are
+ * "char" oriented. We need only one Tcl_Encoding to convert between
+ * UTF-8 and the system's native encoding. We use NULL to represent
+ * that encoding.
*
- * On NT, some strings exchanged between Tcl and the OS are "char"
+ * On Windows, some strings exchanged between Tcl and the OS are "char"
* oriented, while others are in Unicode. We need two Tcl_Encoding APIs
* depending on whether we are targeting a "char" or Unicode interface.
*
- * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an encoding of
- * NULL should always used to convert between UTF-8 and the system's
+ * Calling Tcl_UtfToExternal() or Tcl_ExternalToUtf() with an encoding
+ * of NULL should always used to convert between UTF-8 and the system's
* "char" oriented encoding. The following two functions are used in
- * Windows-specific code to convert between UTF-8 and Unicode strings
- * (NT) or "char" strings(95). This saves you the trouble of writing the
+ * Windows-specific code to convert between UTF-8 and Unicode strings.
+ * This saves you the trouble of writing the
* following type of fragment over and over:
*
- * if (running NT) {
- * encoding <- Tcl_GetEncoding("unicode");
- * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
- * Tcl_FreeEncoding(encoding);
- * } else {
- * nativeBuffer <- UtfToExternal(NULL, utfBuffer);
- * }
- *
- * By convention, in Windows a TCHAR is a character in the ANSI code page
- * on Windows 95, a Unicode character on Windows NT. If you plan on
- * targeting a Unicode interfaces when running on NT and a "char"
- * oriented interface while running on 95, these functions should be
- * used. If you plan on targetting the same "char" oriented function on
- * both 95 and NT, use Tcl_UtfToExternal() with an encoding of NULL.
+ * encoding <- Tcl_GetEncoding("unicode");
+ * nativeBuffer <- UtfToExternal(encoding, utfBuffer);
+ * Tcl_FreeEncoding(encoding);
+ *
+ * By convention, in Windows a TCHAR is a Unicode character. If you plan
+ * on targeting a Unicode interface when running on Windows, these
+ * functions should be used. If you plan on targetting a "char" oriented
+ * function on Windows, use Tcl_UtfToExternal() with an encoding of NULL.
*
* Results:
* The result is a pointer to the string in the desired target encoding.
@@ -561,26 +542,36 @@ TclWinDriveLetterForVolMountPoint(
TCHAR *
Tcl_WinUtfToTChar(
const char *string, /* Source string in UTF-8. */
- int len, /* Source string length in bytes, or < 0 for
+ int len, /* Source string length in bytes, or -1 for
* strlen(). */
Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
* converted string is stored. */
{
- return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding,
- string, len, dsPtr);
+ Tcl_DStringInit(dsPtr);
+ if (!string) {
+ return NULL;
+ }
+ return Tcl_UtfToUniCharDString(string, len, dsPtr);
}
char *
Tcl_WinTCharToUtf(
- const TCHAR *string, /* Source string in Unicode when running NT,
- * ANSI when running 95. */
- int len, /* Source string length in bytes, or < 0 for
+ const TCHAR *string, /* Source string in Unicode. */
+ int len, /* Source string length in bytes, or -1 for
* platform-specific string length. */
Tcl_DString *dsPtr) /* Uninitialized or free DString in which the
* converted string is stored. */
{
- return Tcl_ExternalToUtfDString(winTCharEncoding,
- (const char *) string, len, dsPtr);
+ Tcl_DStringInit(dsPtr);
+ if (!string) {
+ return NULL;
+ }
+ if (len < 0) {
+ len = wcslen(string);
+ } else {
+ len /= 2;
+ }
+ return Tcl_UniCharToUtfDString(string, len, dsPtr);
}
/*
@@ -610,7 +601,7 @@ TclWinCPUID(
#if defined(HAVE_INTRIN_H) && defined(_WIN64)
- __cpuid(regsPtr, index);
+ __cpuid((int *)regsPtr, index);
status = TCL_OK;
#elif defined(__GNUC__)
diff --git a/tcl8.6/win/tclWinDde.c b/tcl8.6/win/tclWinDde.c
index ce0b413..27ddfc8 100644
--- a/tcl8.6/win/tclWinDde.c
+++ b/tcl8.6/win/tclWinDde.c
@@ -17,15 +17,7 @@
#include "tclInt.h"
#include <dde.h>
#include <ddeml.h>
-
-#ifndef UNICODE
-# undef CP_WINUNICODE
-# define CP_WINUNICODE CP_WINANSI
-# undef Tcl_WinTCharToUtf
-# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c)
-# undef Tcl_WinUtfToTChar
-# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
-#endif
+#include <tchar.h>
#if !defined(NDEBUG)
/* test POKE server Implemented for debug mode only */
@@ -34,16 +26,6 @@
#endif
/*
- * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the Dde_Init
- * declaration is in the source file itself, which is only accessed when we
- * are building a library. DO NOT MOVE BEFORE ANY #include LINES. ONLY USE
- * EXTERN TO INDICATE EXPORTED FUNCTIONS FROM NOW ON.
- */
-
-#undef TCL_STORAGE_CLASS
-#define TCL_STORAGE_CLASS DLLEXPORT
-
-/*
* The following structure is used to keep track of the interpreters
* registered by this process.
*/
@@ -69,7 +51,7 @@ typedef struct Conversation {
Tcl_Obj *returnPackagePtr; /* The result package for this conversation. */
} Conversation;
-typedef struct DdeEnumServices {
+typedef struct {
Tcl_Interp *interp;
int result;
ATOM service;
@@ -77,7 +59,7 @@ typedef struct DdeEnumServices {
HWND hwnd;
} DdeEnumServices;
-typedef struct ThreadSpecificData {
+typedef struct {
Conversation *currentConversations;
/* A list of conversations currently being
* processed. */
@@ -97,7 +79,7 @@ static DWORD ddeInstance; /* The application instance handle given to us
* by DdeInitialize. */
static int ddeIsServer = 0;
-#define TCL_DDE_VERSION "1.4.0"
+#define TCL_DDE_VERSION "1.4.1"
#define TCL_DDE_PACKAGE_NAME "dde"
#define TCL_DDE_SERVICE_NAME TEXT("TclEval")
#define TCL_DDE_EXECUTE_RESULT TEXT("$TCLEVAL$EXECUTE$RESULT")
@@ -114,7 +96,7 @@ TCL_DECLARE_MUTEX(ddeMutex)
static LRESULT CALLBACK DdeClientWindowProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
-static int DdeCreateClient(struct DdeEnumServices *es);
+static int DdeCreateClient(DdeEnumServices *es);
static BOOL CALLBACK DdeEnumWindowsCallback(HWND hwndTarget,
LPARAM lParam);
static void DdeExitProc(ClientData clientData);
@@ -135,8 +117,27 @@ static int DdeObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
-EXTERN int Dde_Init(Tcl_Interp *interp);
-EXTERN int Dde_SafeInit(Tcl_Interp *interp);
+static unsigned char *
+getByteArrayFromObj(
+ Tcl_Obj *objPtr,
+ size_t *lengthPtr
+) {
+ int length;
+
+ unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
+#if TCL_MAJOR_VERSION > 8
+ if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
+ /* 64-bit and TIP #494 situation: */
+ *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
+ } else
+#endif
+ /* 32-bit or without TIP #494 */
+ *lengthPtr = (size_t) (unsigned) length;
+ return result;
+}
+
+DLLEXPORT int Dde_Init(Tcl_Interp *interp);
+DLLEXPORT int Dde_SafeInit(Tcl_Interp *interp);
/*
*----------------------------------------------------------------------
@@ -162,13 +163,6 @@ Dde_Init(
return TCL_ERROR;
}
-#ifdef UNICODE
- if (TclWinGetPlatformId() < VER_PLATFORM_WIN32_NT) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "Win32s and Windows 9x are not supported platforms", -1));
- return TCL_ERROR;
- }
-#endif
Tcl_CreateObjCommand(interp, "dde", DdeObjCmd, NULL, NULL);
Tcl_CreateExitHandler(DdeExitProc, NULL);
return Tcl_PkgProvide(interp, TCL_DDE_PACKAGE_NAME, TCL_DDE_VERSION);
@@ -399,7 +393,7 @@ DdeSetServerName(
Tcl_DString ds;
Tcl_ListObjIndex(interp, srvPtrPtr[n], 1, &namePtr);
- Tcl_WinUtfToTChar(Tcl_GetString(namePtr), -1, &ds);
+ Tcl_WinUtfToTChar(Tcl_GetString(namePtr), -1, &ds);
if (_tcscmp(actualName, (TCHAR *)Tcl_DStringValue(&ds)) == 0) {
suffix++;
Tcl_DStringFree(&ds);
@@ -414,9 +408,9 @@ DdeSetServerName(
* We have found a unique name. Now add it to the registry.
*/
- riPtr = ckalloc(sizeof(RegisteredInterp));
+ riPtr = (RegisteredInterp *) Tcl_Alloc(sizeof(RegisteredInterp));
riPtr->interp = interp;
- riPtr->name = ckalloc((_tcslen(actualName) + 1) * sizeof(TCHAR));
+ riPtr->name = (TCHAR *) Tcl_Alloc((_tcslen(actualName) + 1) * sizeof(TCHAR));
riPtr->nextPtr = tsdPtr->interpListPtr;
riPtr->handlerPtr = handlerPtr;
if (riPtr->handlerPtr != NULL) {
@@ -517,7 +511,7 @@ DeleteProc(
prevPtr->nextPtr = searchPtr->nextPtr;
}
}
- ckfree(riPtr->name);
+ Tcl_Free((char *) riPtr->name);
if (riPtr->handlerPtr) {
Tcl_DecrRefCount(riPtr->handlerPtr);
}
@@ -555,7 +549,7 @@ ExecuteRemoteObject(
Tcl_Obj *returnPackagePtr;
int result = TCL_OK;
- if (riPtr->handlerPtr == NULL && Tcl_IsSafe(riPtr->interp)) {
+ if ((riPtr->handlerPtr == NULL) && Tcl_IsSafe(riPtr->interp)) {
Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj("permission denied: "
"a handler procedure must be defined for use in a safe "
"interp", -1));
@@ -637,7 +631,7 @@ DdeServerProc(
/* Transaction-dependent data. */
{
Tcl_DString dString;
- int len;
+ size_t len;
DWORD dlen;
TCHAR *utilString;
Tcl_Obj *ddeObjectPtr;
@@ -687,7 +681,7 @@ DdeServerProc(
for (riPtr = tsdPtr->interpListPtr; riPtr != NULL;
riPtr = riPtr->nextPtr) {
if (_tcsicmp(riPtr->name, utilString) == 0) {
- convPtr = ckalloc(sizeof(Conversation));
+ convPtr = (Conversation *) Tcl_Alloc(sizeof(Conversation));
convPtr->nextPtr = tsdPtr->currentConversations;
convPtr->returnPackagePtr = NULL;
convPtr->hConv = hConv;
@@ -717,7 +711,7 @@ DdeServerProc(
if (convPtr->returnPackagePtr != NULL) {
Tcl_DecrRefCount(convPtr->returnPackagePtr);
}
- ckfree(convPtr);
+ Tcl_Free((char *) convPtr);
break;
}
}
@@ -743,22 +737,24 @@ DdeServerProc(
}
if (convPtr != NULL) {
+ Tcl_DString dsBuf;
char *returnString;
len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE);
Tcl_DStringInit(&dString);
+ Tcl_DStringInit(&dsBuf);
Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1);
utilString = (TCHAR *) Tcl_DStringValue(&dString);
DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1,
CP_WINUNICODE);
if (_tcsicmp(utilString, TCL_DDE_EXECUTE_RESULT) == 0) {
- if (uFmt == CF_TEXT) {
- returnString =
- Tcl_GetStringFromObj(convPtr->returnPackagePtr, &len);
- } else {
- returnString = (char *)
- Tcl_GetUnicodeFromObj(convPtr->returnPackagePtr, &len);
- len = sizeof(TCHAR) * len + 1;
+ returnString =
+ Tcl_GetString(convPtr->returnPackagePtr);
+ len = convPtr->returnPackagePtr->length;
+ if (uFmt != CF_TEXT) {
+ Tcl_WinUtfToTChar(returnString, len, &dsBuf);
+ returnString = Tcl_DStringValue(&dsBuf);
+ len = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR) - 1;
}
ddeReturn = DdeCreateDataHandle(ddeInstance, (BYTE *)returnString,
(DWORD) len+1, 0, ddeItem, uFmt, 0);
@@ -768,18 +764,18 @@ DdeServerProc(
} else {
Tcl_DString ds;
Tcl_Obj *variableObjPtr;
+
Tcl_WinTCharToUtf(utilString, -1, &ds);
variableObjPtr = Tcl_GetVar2Ex(
convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL,
TCL_GLOBAL_ONLY);
if (variableObjPtr != NULL) {
- if (uFmt == CF_TEXT) {
- returnString = Tcl_GetStringFromObj(
- variableObjPtr, &len);
- } else {
- returnString = (char *) Tcl_GetUnicodeFromObj(
- variableObjPtr, &len);
- len = sizeof(TCHAR) * len + 1;
+ returnString = Tcl_GetString(variableObjPtr);
+ len = variableObjPtr->length;
+ if (uFmt != CF_TEXT) {
+ Tcl_WinUtfToTChar(returnString, len, &dsBuf);
+ returnString = Tcl_DStringValue(&dsBuf);
+ len = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR) - 1;
}
ddeReturn = DdeCreateDataHandle(ddeInstance,
(BYTE *)returnString, (DWORD) len+1, 0, ddeItem,
@@ -790,6 +786,7 @@ DdeServerProc(
Tcl_DStringFree(&ds);
}
}
+ Tcl_DStringFree(&dsBuf);
Tcl_DStringFree(&dString);
}
return ddeReturn;
@@ -814,26 +811,30 @@ DdeServerProc(
}
if (convPtr && !Tcl_IsSafe(convPtr->riPtr->interp)) {
- Tcl_DString ds;
+ Tcl_DString ds, ds2;
Tcl_Obj *variableObjPtr;
+ DWORD len2;
- len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE);
Tcl_DStringInit(&dString);
+ Tcl_DStringInit(&ds2);
+ len = DdeQueryString(ddeInstance, ddeItem, NULL, 0, CP_WINUNICODE);
Tcl_DStringSetLength(&dString, (len + 1) * sizeof(TCHAR) - 1);
utilString = (TCHAR *) Tcl_DStringValue(&dString);
DdeQueryString(ddeInstance, ddeItem, utilString, (DWORD) len + 1,
CP_WINUNICODE);
Tcl_WinTCharToUtf(utilString, -1, &ds);
- utilString = (TCHAR *) DdeAccessData(hData, &dlen);
- if (uFmt == CF_TEXT) {
- variableObjPtr = Tcl_NewStringObj((char *)utilString, -1);
- } else {
- variableObjPtr = Tcl_NewUnicodeObj(utilString, -1);
+ utilString = (TCHAR *) DdeAccessData(hData, &len2);
+ len = len2;
+ if (uFmt != CF_TEXT) {
+ Tcl_WinTCharToUtf(utilString, -1, &ds2);
+ utilString = (TCHAR *) Tcl_DStringValue(&ds2);
}
+ variableObjPtr = Tcl_NewStringObj((char *)utilString, -1);
Tcl_SetVar2Ex(convPtr->riPtr->interp, Tcl_DStringValue(&ds), NULL,
variableObjPtr, TCL_GLOBAL_ONLY);
+ Tcl_DStringFree(&ds2);
Tcl_DStringFree(&ds);
Tcl_DStringFree(&dString);
ddeReturn = (HDDEDATA) DDE_FACK;
@@ -874,8 +875,12 @@ DdeServerProc(
ddeObjectPtr = Tcl_NewStringObj(string, dlen);
} else {
/* unicode */
- dlen >>= 1;
- ddeObjectPtr = Tcl_NewUnicodeObj((Tcl_UniChar *)utilString, dlen - 1);
+ Tcl_DString dsBuf;
+
+ Tcl_WinTCharToUtf(utilString, dlen - sizeof(TCHAR), &dsBuf);
+ ddeObjectPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsBuf),
+ Tcl_DStringLength(&dsBuf));
+ Tcl_DStringFree(&dsBuf);
}
Tcl_IncrRefCount(ddeObjectPtr);
DdeUnaccessData(hData);
@@ -1040,7 +1045,7 @@ MakeDdeConnection(
static int
DdeCreateClient(
- struct DdeEnumServices *es)
+ DdeEnumServices *es)
{
WNDCLASSEX wc;
static const TCHAR *szDdeClientClassName = TEXT("TclEval client class");
@@ -1050,7 +1055,7 @@ DdeCreateClient(
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = DdeClientWindowProc;
wc.lpszClassName = szDdeClientClassName;
- wc.cbWndExtra = sizeof(struct DdeEnumServices *);
+ wc.cbWndExtra = sizeof(DdeEnumServices *);
/*
* Register and create the callback window.
@@ -1072,8 +1077,8 @@ DdeClientWindowProc(
switch (uMsg) {
case WM_CREATE: {
LPCREATESTRUCT lpcs = (LPCREATESTRUCT) lParam;
- struct DdeEnumServices *es =
- (struct DdeEnumServices *) lpcs->lpCreateParams;
+ DdeEnumServices *es =
+ (DdeEnumServices *) lpcs->lpCreateParams;
#ifdef _WIN64
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) es);
@@ -1098,18 +1103,18 @@ DdeServicesOnAck(
HWND hwndRemote = (HWND)wParam;
ATOM service = (ATOM)LOWORD(lParam);
ATOM topic = (ATOM)HIWORD(lParam);
- struct DdeEnumServices *es;
+ DdeEnumServices *es;
TCHAR sz[255];
Tcl_DString dString;
#ifdef _WIN64
- es = (struct DdeEnumServices *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ es = (DdeEnumServices *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
- es = (struct DdeEnumServices *) GetWindowLong(hwnd, GWL_USERDATA);
+ es = (DdeEnumServices *) GetWindowLong(hwnd, GWL_USERDATA);
#endif
- if ((es->service == (ATOM)0 || es->service == service)
- && (es->topic == (ATOM)0 || es->topic == topic)) {
+ if (((es->service == (ATOM)0) || (es->service == service))
+ && ((es->topic == (ATOM)0) || (es->topic == topic))) {
Tcl_Obj *matchPtr = Tcl_NewListObj(0, NULL);
Tcl_Obj *resultPtr = Tcl_GetObjResult(es->interp);
@@ -1156,7 +1161,7 @@ DdeEnumWindowsCallback(
LPARAM lParam)
{
DWORD_PTR dwResult = 0;
- struct DdeEnumServices *es = (struct DdeEnumServices *) lParam;
+ DdeEnumServices *es = (DdeEnumServices *) lParam;
SendMessageTimeout(hwndTarget, WM_DDE_INITIATE, (WPARAM)es->hwnd,
MAKELONG(es->service, es->topic), SMTO_ABORTIFHUNG, 1000,
@@ -1170,7 +1175,7 @@ DdeGetServicesList(
const TCHAR *serviceName,
const TCHAR *topicName)
{
- struct DdeEnumServices es;
+ DdeEnumServices es;
es.interp = interp;
es.result = TCL_OK;
@@ -1291,7 +1296,8 @@ DdeObjCmd(
"-binary", NULL
};
- int index, i, length, argIndex;
+ int index, i, argIndex;
+ size_t length;
int flags = 0, result = TCL_OK, firstArg = 0;
HSZ ddeService = NULL, ddeTopic = NULL, ddeItem = NULL, ddeCookie = NULL;
HDDEDATA ddeData = NULL, ddeItemData = NULL, ddeReturn;
@@ -1300,6 +1306,7 @@ DdeObjCmd(
const char *string;
DWORD ddeResult;
Tcl_Obj *objPtr, *handlerPtr = NULL;
+ Tcl_DString serviceBuf, topicBuf, itemBuf;
/*
* Initialize DDE server/client
@@ -1315,6 +1322,9 @@ DdeObjCmd(
return TCL_ERROR;
}
+ Tcl_DStringInit(&serviceBuf);
+ Tcl_DStringInit(&topicBuf);
+ Tcl_DStringInit(&itemBuf);
switch ((enum DdeSubcommands) index) {
case DDE_SERVERNAME:
for (i = 2; i < objc; i++) {
@@ -1364,7 +1374,7 @@ DdeObjCmd(
if (objc == 5) {
firstArg = 2;
break;
- } else if (objc >= 6 && objc <= 7) {
+ } else if ((objc >= 6) && (objc <= 7)) {
firstArg = objc - 3;
for (i = 2; i < firstArg; i++) {
if (Tcl_GetIndexFromObj(interp, objv[i], ddeExecOptions,
@@ -1449,11 +1459,12 @@ DdeObjCmd(
Initialize();
if (firstArg != 1) {
-#ifdef UNICODE
- serviceName = Tcl_GetUnicodeFromObj(objv[firstArg], &length);
-#else
- serviceName = Tcl_GetStringFromObj(objv[firstArg], &length);
-#endif
+ const char *src = Tcl_GetString(objv[firstArg]);
+
+ length = objv[firstArg]->length;
+ Tcl_WinUtfToTChar(src, length, &serviceBuf);
+ serviceName = (TCHAR *) Tcl_DStringValue(&serviceBuf);
+ length = Tcl_DStringLength(&serviceBuf) / sizeof(TCHAR);
} else {
length = 0;
}
@@ -1466,11 +1477,11 @@ DdeObjCmd(
}
if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) {
-#ifdef UNICODE
- topicName = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 1], &length);
-#else
- topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length);
-#endif
+ const char *src = Tcl_GetString(objv[firstArg + 1]);
+
+ length = objv[firstArg + 1]->length;
+ topicName = Tcl_WinUtfToTChar(src, length, &topicBuf);
+ length = Tcl_DStringLength(&topicBuf) / sizeof(TCHAR);
if (length == 0) {
topicName = NULL;
} else {
@@ -1484,32 +1495,40 @@ DdeObjCmd(
serviceName = DdeSetServerName(interp, serviceName, flags,
handlerPtr);
if (serviceName != NULL) {
-#ifdef UNICODE
- Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, -1));
-#else
- Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1));
-#endif
+ Tcl_DString dsBuf;
+
+ Tcl_WinTCharToUtf(serviceName, -1, &dsBuf);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_DStringValue(&dsBuf),
+ Tcl_DStringLength(&dsBuf)));
+ Tcl_DStringFree(&dsBuf);
} else {
Tcl_ResetResult(interp);
}
break;
case DDE_EXECUTE: {
- int dataLength;
- const Tcl_UniChar *dataString;
+ size_t dataLength;
+ const void *dataString;
+ Tcl_DString dsBuf;
+ Tcl_DStringInit(&dsBuf);
if (flags & DDE_FLAG_BINARY) {
- dataString = (const Tcl_UniChar *)
- Tcl_GetByteArrayFromObj(objv[firstArg + 2], &dataLength);
- } else {
dataString =
- Tcl_GetUnicodeFromObj(objv[firstArg + 2], &dataLength);
- dataLength = (dataLength + 1) * sizeof(Tcl_UniChar);
+ getByteArrayFromObj(objv[firstArg + 2], &dataLength);
+ } else {
+ const char *src;
+
+ src = Tcl_GetString(objv[firstArg + 2]);
+ dataLength = objv[firstArg + 2]->length;
+ dataString = (const TCHAR *)
+ Tcl_WinUtfToTChar(src, dataLength, &dsBuf);
+ dataLength = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR);
}
- if (dataLength <= 0) {
+ if (dataLength + 1 < 2) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("cannot execute null data", -1));
+ Tcl_DStringFree(&dsBuf);
Tcl_SetErrorCode(interp, "TCL", "DDE", "NULL", NULL);
result = TCL_ERROR;
break;
@@ -1519,6 +1538,7 @@ DdeObjCmd(
DdeFreeStringHandle(ddeInstance, ddeTopic);
if (hConv == NULL) {
+ Tcl_DStringFree(&dsBuf);
SetDdeError(interp);
result = TCL_ERROR;
break;
@@ -1544,16 +1564,17 @@ DdeObjCmd(
SetDdeError(interp);
result = TCL_ERROR;
}
+ Tcl_DStringFree(&dsBuf);
break;
}
case DDE_REQUEST: {
-#ifdef UNICODE
- const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2],
- &length);
-#else
- const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2],
- &length);
-#endif
+ const TCHAR *itemString;
+ const char *src;
+
+ src = Tcl_GetString(objv[firstArg + 2]);
+ length = objv[firstArg + 2]->length;
+ itemString = Tcl_WinUtfToTChar(src, length, &itemBuf);
+ length = Tcl_DStringLength(&itemBuf) / sizeof(TCHAR);
if (length == 0) {
Tcl_SetObjResult(interp,
@@ -1581,18 +1602,23 @@ DdeObjCmd(
result = TCL_ERROR;
} else {
DWORD tmp;
- const Tcl_UniChar *dataString = (const Tcl_UniChar *) DdeAccessData(ddeData, &tmp);
+ TCHAR *dataString = (TCHAR *) DdeAccessData(ddeData, &tmp);
if (flags & DDE_FLAG_BINARY) {
returnObjPtr =
- Tcl_NewByteArrayObj((BYTE *) dataString, (int) tmp);
+ Tcl_NewByteArrayObj((BYTE *) dataString, tmp);
} else {
- tmp >>= 1;
- if (tmp && !dataString[(tmp-1)]) {
- --tmp;
+ Tcl_DString dsBuf;
+
+ if ((tmp >= sizeof(TCHAR))
+ && !dataString[tmp / sizeof(TCHAR) - 1]) {
+ tmp -= sizeof(TCHAR);
}
- returnObjPtr = Tcl_NewUnicodeObj(dataString,
- (int) tmp);
+ Tcl_WinTCharToUtf(dataString, tmp, &dsBuf);
+ returnObjPtr =
+ Tcl_NewStringObj(Tcl_DStringValue(&dsBuf),
+ Tcl_DStringLength(&dsBuf));
+ Tcl_DStringFree(&dsBuf);
}
DdeUnaccessData(ddeData);
DdeFreeDataHandle(ddeData);
@@ -1603,19 +1629,18 @@ DdeObjCmd(
result = TCL_ERROR;
}
}
-
break;
}
case DDE_POKE: {
-#ifdef UNICODE
- const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2],
- &length);
-#else
- const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2],
- &length);
-#endif
+ Tcl_DString dsBuf;
+ const TCHAR *itemString;
BYTE *dataString;
+ const char *src;
+ src = Tcl_GetString(objv[firstArg + 2]);
+ length = objv[firstArg + 2]->length;
+ itemString = Tcl_WinUtfToTChar(src, length, &itemBuf);
+ length = Tcl_DStringLength(&itemBuf) / sizeof(TCHAR);
if (length == 0) {
Tcl_SetObjResult(interp,
Tcl_NewStringObj("cannot have a null item", -1));
@@ -1623,13 +1648,17 @@ DdeObjCmd(
result = TCL_ERROR;
goto cleanup;
}
+ Tcl_DStringInit(&dsBuf);
if (flags & DDE_FLAG_BINARY) {
dataString = (BYTE *)
- Tcl_GetByteArrayFromObj(objv[firstArg + 3], &length);
+ getByteArrayFromObj(objv[firstArg + 3], &length);
} else {
+ const char *data =
+ Tcl_GetString(objv[firstArg + 3]);
+ length = objv[firstArg + 3]->length;
dataString = (BYTE *)
- Tcl_GetUnicodeFromObj(objv[firstArg + 3], &length);
- length = 2 * length + 1;
+ Tcl_WinUtfToTChar(data, length, &dsBuf);
+ length = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR);
}
hConv = DdeConnect(ddeInstance, ddeService, ddeTopic, NULL);
@@ -1654,6 +1683,7 @@ DdeObjCmd(
result = TCL_ERROR;
}
}
+ Tcl_DStringFree(&dsBuf);
break;
}
@@ -1712,7 +1742,7 @@ DdeObjCmd(
* referring to deallocated objects.
*/
- if (Tcl_IsSafe(riPtr->interp) && riPtr->handlerPtr == NULL) {
+ if (Tcl_IsSafe(riPtr->interp) && (riPtr->handlerPtr == NULL)) {
Tcl_SetObjResult(riPtr->interp, Tcl_NewStringObj(
"permission denied: a handler procedure must be"
" defined for use in a safe interp", -1));
@@ -1757,8 +1787,7 @@ DdeObjCmd(
objPtr = Tcl_GetVar2Ex(sendInterp, "errorInfo", NULL,
TCL_GLOBAL_ONLY);
if (objPtr) {
- string = Tcl_GetStringFromObj(objPtr, &length);
- Tcl_AddObjErrorInfo(interp, string, length);
+ Tcl_AppendObjToErrorInfo(interp, objPtr);
}
objPtr = Tcl_GetVar2Ex(sendInterp, "errorCode", NULL,
@@ -1772,6 +1801,8 @@ DdeObjCmd(
Tcl_Release(riPtr);
Tcl_Release(sendInterp);
} else {
+ Tcl_DString dsBuf;
+
/*
* This is a non-local request. Send the script to the server and
* poll it for a result.
@@ -1787,9 +1818,14 @@ DdeObjCmd(
}
objPtr = Tcl_ConcatObj(objc, objv);
- string = (const char *) Tcl_GetUnicodeFromObj(objPtr, &length);
- ddeItemData = DdeCreateDataHandle(ddeInstance,
- (BYTE *) string, (DWORD) 2*length+2, 0, 0, CF_UNICODETEXT, 0);
+ string = Tcl_GetString(objPtr);
+ length = objPtr->length;
+ Tcl_WinUtfToTChar(string, length, &dsBuf);
+ string = Tcl_DStringValue(&dsBuf);
+ length = Tcl_DStringLength(&dsBuf) + sizeof(TCHAR);
+ ddeItemData = DdeCreateDataHandle(ddeInstance, (BYTE *) string,
+ (DWORD) length, 0, 0, CF_UNICODETEXT, 0);
+ Tcl_DStringFree(&dsBuf);
if (flags & DDE_FLAG_ASYNC) {
ddeData = DdeClientTransaction((LPBYTE) ddeItemData,
@@ -1818,7 +1854,7 @@ DdeObjCmd(
if (!(flags & DDE_FLAG_ASYNC)) {
Tcl_Obj *resultPtr;
- Tcl_UniChar *ddeDataString;
+ TCHAR *ddeDataString;
/*
* The return handle has a two or four element list in it. The
@@ -1829,13 +1865,17 @@ DdeObjCmd(
* variable "errorInfo".
*/
- resultPtr = Tcl_NewObj();
length = DdeGetData(ddeData, NULL, 0, 0);
- ddeDataString = ckalloc(length);
+ ddeDataString = (TCHAR *) Tcl_Alloc(length);
DdeGetData(ddeData, (BYTE *) ddeDataString, (DWORD) length, 0);
- length = (length >> 1) - 1;
- resultPtr = Tcl_NewUnicodeObj(ddeDataString, length);
- ckfree(ddeDataString);
+ if (length > sizeof(TCHAR)) {
+ length -= sizeof(TCHAR);
+ }
+ Tcl_WinTCharToUtf(ddeDataString, length, &dsBuf);
+ resultPtr = Tcl_NewStringObj(Tcl_DStringValue(&dsBuf),
+ Tcl_DStringLength(&dsBuf));
+ Tcl_DStringFree(&dsBuf);
+ Tcl_Free((char *) ddeDataString);
if (Tcl_ListObjIndex(NULL, resultPtr, 0, &objPtr) != TCL_OK) {
Tcl_DecrRefCount(resultPtr);
@@ -1853,9 +1893,7 @@ DdeObjCmd(
Tcl_DecrRefCount(resultPtr);
goto invalidServerResponse;
}
- length = -1;
- string = Tcl_GetStringFromObj(objPtr, &length);
- Tcl_AddObjErrorInfo(interp, string, length);
+ Tcl_AppendObjToErrorInfo(interp, objPtr);
Tcl_ListObjIndex(NULL, resultPtr, 2, &objPtr);
Tcl_SetObjErrorCode(interp, objPtr);
@@ -1887,6 +1925,9 @@ DdeObjCmd(
if (hConv != NULL) {
DdeDisconnect(hConv);
}
+ Tcl_DStringFree(&itemBuf);
+ Tcl_DStringFree(&topicBuf);
+ Tcl_DStringFree(&serviceBuf);
return result;
}
diff --git a/tcl8.6/win/tclWinFCmd.c b/tcl8.6/win/tclWinFCmd.c
index 52ea8c6..2f28154 100644
--- a/tcl8.6/win/tclWinFCmd.c
+++ b/tcl8.6/win/tclWinFCmd.c
@@ -1026,7 +1026,8 @@ DoRemoveJustDirectory(
if (nativePath == NULL || nativePath[0] == '\0') {
Tcl_SetErrno(ENOENT);
- goto end;
+ Tcl_DStringInit(errorPtr);
+ return TCL_ERROR;
}
attr = GetFileAttributes(nativePath);
@@ -1108,9 +1109,7 @@ DoRemoveJustDirectory(
end:
if (errorPtr != NULL) {
- char *p;
- Tcl_WinTCharToUtf(nativePath, -1, errorPtr);
- p = Tcl_DStringValue(errorPtr);
+ char *p = Tcl_WinTCharToUtf(nativePath, -1, errorPtr);
for (; *p; ++p) {
if (*p == '\\') *p = '/';
}
diff --git a/tcl8.6/win/tclWinFile.c b/tcl8.6/win/tclWinFile.c
index 7586af1..b9787c7 100644..100755
--- a/tcl8.6/win/tclWinFile.c
+++ b/tcl8.6/win/tclWinFile.c
@@ -531,6 +531,11 @@ TclWinSymLinkDelete(
*--------------------------------------------------------------------
*/
+#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+
static Tcl_Obj *
WinReadLinkDirectory(
const TCHAR *linkDirPath)
@@ -648,6 +653,10 @@ WinReadLinkDirectory(
Tcl_SetErrno(EINVAL);
return NULL;
}
+
+#if defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
+#pragma GCC diagnostic pop
+#endif
/*
*--------------------------------------------------------------------
@@ -1436,48 +1445,78 @@ TclpGetUserHome(
Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
* name of user's home directory. */
{
- const char *result = NULL;
- USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr;
+ char *result = NULL;
+ USER_INFO_1 *uiPtr;
Tcl_DString ds;
int nameLen = -1;
- int badDomain = 0;
- char *domain;
- WCHAR *wName, *wHomeDir, *wDomain, **wDomainPtr = &wDomain;
+ int rc = 0;
+ const char *domain;
+ WCHAR *wName, *wHomeDir, *wDomain;
WCHAR buf[MAX_PATH];
Tcl_DStringInit(bufferPtr);
+
wDomain = NULL;
- domain = strchr(name, '@');
- if (domain != NULL) {
+ domain = Tcl_UtfFindFirst(name, '@');
+ if (domain == NULL) {
+ const char *ptr;
+
+ /* no domain - firstly check it's the current user */
+ if ( (ptr = TclpGetUserName(&ds)) != NULL
+ && strcasecmp(name, ptr) == 0
+ ) {
+ /* try safest and fastest way to get current user home */
+ ptr = TclGetEnv("HOME", &ds);
+ if (ptr != NULL) {
+ Tcl_JoinPath(1, &ptr, bufferPtr);
+ rc = 1;
+ result = Tcl_DStringValue(bufferPtr);
+ }
+ }
+ Tcl_DStringFree(&ds);
+ } else {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds);
- badDomain = NetGetDCName(NULL, wName, (LPBYTE *) wDomainPtr);
+ rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain);
Tcl_DStringFree(&ds);
nameLen = domain - name;
}
- if (badDomain == 0) {
+ if (rc == 0) {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
- if (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) uiPtrPtr) == 0) {
+ while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) {
+ /*
+ * user does not exists - if domain was not specified,
+ * try again using current domain.
+ */
+ rc = 1;
+ if (domain != NULL) break;
+ /* get current domain */
+ rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
+ if (rc != 0) break;
+ domain = INT2PTR(-1); /* repeat once */
+ }
+ if (rc == 0) {
+ DWORD i, size = MAX_PATH;
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
- Tcl_UniCharToUtfDString(wHomeDir, lstrlenW(wHomeDir),
- bufferPtr);
+ size = lstrlenW(wHomeDir);
+ Tcl_UniCharToUtfDString(wHomeDir, size, bufferPtr);
} else {
/*
* User exists but has no home dir. Return
* "{GetProfilesDirectory}/<user>".
*/
- DWORD i, size = MAX_PATH;
GetProfilesDirectoryW(buf, &size);
- for (i = 0; i < size; ++i){
- if (buf[i] == '\\') buf[i] = '/';
- }
Tcl_UniCharToUtfDString(buf, size-1, bufferPtr);
- Tcl_DStringAppend(bufferPtr, "/", -1);
- Tcl_DStringAppend(bufferPtr, name, -1);
+ Tcl_DStringAppend(bufferPtr, "/", 1);
+ Tcl_DStringAppend(bufferPtr, name, nameLen);
}
result = Tcl_DStringValue(bufferPtr);
+ /* be sure we returns normalized path */
+ for (i = 0; i < size; ++i){
+ if (result[i] == '\\') result[i] = '/';
+ }
NetApiBufferFree((void *) uiPtr);
}
Tcl_DStringFree(&ds);
@@ -1561,11 +1600,12 @@ NativeAccess(
return 0;
}
- if ((mode & W_OK)
- && (attr & FILE_ATTRIBUTE_READONLY)
- && !(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ /*
+ * If it's not a directory (assume file), do several fast checks:
+ */
+ if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
/*
- * The attributes say the file is not writable. If the file is a
+ * If the attributes say this is not writable at all. The file is a
* regular file (i.e., not a directory), then the file is not
* writable, full stop. For directories, the read-only bit is
* (mostly) ignored by Windows, so we can't ascertain anything about
@@ -1573,21 +1613,38 @@ NativeAccess(
* advanced 'getFileSecurityProc', then more robust ACL checks
* will be done below.
*/
+ if ((mode & W_OK) && (attr & FILE_ATTRIBUTE_READONLY)) {
+ Tcl_SetErrno(EACCES);
+ return -1;
+ }
- Tcl_SetErrno(EACCES);
- return -1;
- }
-
- if (mode & X_OK) {
- if (!(attr & FILE_ATTRIBUTE_DIRECTORY) && !NativeIsExec(nativePath)) {
- /*
- * It's not a directory and doesn't have the correct extension.
- * Therefore it can't be executable
- */
-
+ /* If doesn't have the correct extension, it can't be executable */
+ if ((mode & X_OK) && !NativeIsExec(nativePath)) {
Tcl_SetErrno(EACCES);
return -1;
}
+ /* Special case for read/write/executable check on file */
+ if ((mode & (R_OK|W_OK|X_OK)) && !(mode & ~(R_OK|W_OK|X_OK))) {
+ DWORD mask = 0;
+ HANDLE hFile;
+ if (mode & R_OK) { mask |= GENERIC_READ; }
+ if (mode & W_OK) { mask |= GENERIC_WRITE; }
+ if (mode & X_OK) { mask |= GENERIC_EXECUTE; }
+
+ hFile = CreateFile(nativePath, mask,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ CloseHandle(hFile);
+ return 0;
+ }
+ /* fast exit if access was denied */
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ Tcl_SetErrno(EACCES);
+ return -1;
+ }
+ }
+ /* We cannnot verify the access fast, check it below using security info. */
}
/*
@@ -1792,10 +1849,12 @@ NativeIsExec(
return 0;
}
- 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)) {
+ path += len-3;
+ if ((_tcsicmp(path, TEXT("exe")) == 0)
+ || (_tcsicmp(path, TEXT("com")) == 0)
+ || (_tcsicmp(path, TEXT("cmd")) == 0)
+ || (_tcsicmp(path, TEXT("cmd")) == 0)
+ || (_tcsicmp(path, TEXT("bat")) == 0)) {
return 1;
}
return 0;
@@ -1972,7 +2031,8 @@ NativeStat(
*/
fileHandle = CreateFile(nativePath, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (fileHandle != INVALID_HANDLE_VALUE) {
diff --git a/tcl8.6/win/tclWinInit.c b/tcl8.6/win/tclWinInit.c
index 98c7ed5..ff5327d 100644
--- a/tcl8.6/win/tclWinInit.c
+++ b/tcl8.6/win/tclWinInit.c
@@ -112,7 +112,12 @@ static ProcessGlobalValue sourceLibraryDir =
{0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL};
static void AppendEnvironment(Tcl_Obj *listPtr, const char *lib);
-static int ToUtf(const WCHAR *wSrc, char *dst);
+
+#if TCL_UTF_MAX < 4
+static void ToUtf(const WCHAR *wSrc, char *dst);
+#else
+#define ToUtf(wSrc, dst) WideCharToMultiByte(CP_UTF8, 0, wSrc, -1, dst, MAX_PATH * TCL_UTF_MAX, NULL, NULL)
+#endif
/*
*---------------------------------------------------------------------------
@@ -435,7 +440,7 @@ InitializeSourceLibraryDir(
*
* ToUtf --
*
- * Convert a char string to a UTF string.
+ * Convert a wchar string to a UTF string.
*
* Results:
* None.
@@ -446,21 +451,19 @@ InitializeSourceLibraryDir(
*---------------------------------------------------------------------------
*/
-static int
+#if TCL_UTF_MAX < 4
+static void
ToUtf(
const WCHAR *wSrc,
char *dst)
{
- char *start;
-
- start = dst;
while (*wSrc != '\0') {
dst += Tcl_UniCharToUtf(*wSrc, dst);
wSrc++;
}
*dst = '\0';
- return (int) (dst - start);
}
+#endif
/*
*---------------------------------------------------------------------------
@@ -514,6 +517,27 @@ Tcl_GetEncodingNameFromEnvironment(
return Tcl_DStringValue(bufPtr);
}
+const char *
+TclpGetUserName(
+ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
+ * the name of user. */
+{
+ Tcl_DStringInit(bufferPtr);
+
+ if (TclGetEnv("USERNAME", bufferPtr) == NULL) {
+ TCHAR szUserName[UNLEN+1];
+ DWORD cchUserNameLen = UNLEN;
+
+ if (!GetUserName(szUserName, &cchUserNameLen)) {
+ return NULL;
+ }
+ cchUserNameLen--;
+ cchUserNameLen *= sizeof(TCHAR);
+ Tcl_WinTCharToUtf(szUserName, cchUserNameLen, bufferPtr);
+ }
+ return Tcl_DStringValue(bufferPtr);
+}
+
/*
*---------------------------------------------------------------------------
*
@@ -544,8 +568,6 @@ TclpSetVariables(
static OSVERSIONINFOW osInfo;
static int osInfoInitialized = 0;
Tcl_DString ds;
- TCHAR szUserName[UNLEN+1];
- DWORD cchUserNameLen = UNLEN;
Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
@@ -623,15 +645,8 @@ TclpSetVariables(
* Note: cchUserNameLen is number of characters including nul terminator.
*/
- Tcl_DStringInit(&ds);
- if (TclGetEnv("USERNAME", &ds) == NULL) {
- if (GetUserName(szUserName, &cchUserNameLen) != 0) {
- int cbUserNameLen = cchUserNameLen - 1;
- cbUserNameLen *= sizeof(TCHAR);
- Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds);
- }
- }
- Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),
+ ptr = TclpGetUserName(&ds);
+ Tcl_SetVar2(interp, "tcl_platform", "user", ptr ? ptr : "",
TCL_GLOBAL_ONLY);
Tcl_DStringFree(&ds);
@@ -648,7 +663,7 @@ TclpSetVariables(
* TclpFindVariable --
*
* Locate the entry in environ for a given name. On Unix this routine is
- * case sensitive, on Windows this matches mioxed case.
+ * case sensitive, on Windows this matches mixed case.
*
* Results:
* The return value is the index in environ of an entry with the name
diff --git a/tcl8.6/win/tclWinInt.h b/tcl8.6/win/tclWinInt.h
index 43799d0..d0844da 100644
--- a/tcl8.6/win/tclWinInt.h
+++ b/tcl8.6/win/tclWinInt.h
@@ -90,6 +90,8 @@ MODULE_SCOPE void * TclpGetAllocCache(void);
MODULE_SCOPE void TclpSetAllocCache(void *);
#endif /* TCL_THREADS */
+MODULE_SCOPE const char*TclpGetUserName(Tcl_DString *bufferPtr);
+
/* Needed by tclWinFile.c and tclWinFCmd.c */
#ifndef FILE_ATTRIBUTE_REPARSE_POINT
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
diff --git a/tcl8.6/win/tclWinPipe.c b/tcl8.6/win/tclWinPipe.c
index 4b372a5..826265a 100644
--- a/tcl8.6/win/tclWinPipe.c
+++ b/tcl8.6/win/tclWinPipe.c
@@ -1289,7 +1289,7 @@ ApplicationType(
/*
* Look for the program as an external program. First try the name as it
- * is, then try adding .com, .exe, and .bat, in that order, to the name,
+ * is, then try adding .com, .exe, .bat and .cmd, in that order, to the name,
* looking for an executable.
*
* Using the raw SearchPath() function doesn't do quite what is necessary.
@@ -1408,7 +1408,7 @@ ApplicationType(
return APPL_NONE;
}
- if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
+ if (applType == APPL_WIN3X) {
/*
* Replace long path name of executable with short path name for
* 16-bit applications. Otherwise the application may not be able to
@@ -1442,6 +1442,86 @@ ApplicationType(
*----------------------------------------------------------------------
*/
+static const char *
+BuildCmdLineBypassBS(
+ const char *current,
+ const char **bspos
+) {
+ /* mark first backslash possition */
+ if (!*bspos) {
+ *bspos = current;
+ }
+ do {
+ current++;
+ } while (*current == '\\');
+ return current;
+}
+
+static void
+QuoteCmdLineBackslash(
+ Tcl_DString *dsPtr,
+ const char *start,
+ const char *current,
+ const char *bspos
+) {
+ if (!bspos) {
+ if (current > start) { /* part before current (special) */
+ Tcl_DStringAppend(dsPtr, start, (int) (current - start));
+ }
+ } else {
+ if (bspos > start) { /* part before first backslash */
+ Tcl_DStringAppend(dsPtr, start, (int) (bspos - start));
+ }
+ while (bspos++ < current) { /* each backslash twice */
+ TclDStringAppendLiteral(dsPtr, "\\\\");
+ }
+ }
+}
+
+static const char *
+QuoteCmdLinePart(
+ Tcl_DString *dsPtr,
+ const char *start,
+ const char *special,
+ const char *specMetaChars,
+ const char **bspos
+) {
+ if (!*bspos) {
+ /* rest before special (before quote) */
+ QuoteCmdLineBackslash(dsPtr, start, special, NULL);
+ start = special;
+ } else {
+ /* rest before first backslash and backslashes into new quoted block */
+ QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
+ start = *bspos;
+ }
+ /*
+ * escape all special chars enclosed in quotes like `"..."`, note that here we
+ * don't must escape `\` (with `\`), because it's outside of the main quotes,
+ * so `\` remains `\`, but important - not at end of part, because results as
+ * before the quote, so `%\%\` should be escaped as `"%\%"\\`).
+ */
+ TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */
+ do {
+ *bspos = NULL;
+ special++;
+ if (*special == '\\') {
+ /* bypass backslashes (and mark first backslash possition)*/
+ special = BuildCmdLineBypassBS(special, bspos);
+ if (*special == '\0') break;
+ }
+ } while (*special && strchr(specMetaChars, *special));
+ if (!*bspos) {
+ /* unescaped rest before quote */
+ QuoteCmdLineBackslash(dsPtr, start, special, NULL);
+ } else {
+ /* unescaped rest before first backslash (rather belongs to the main block) */
+ QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
+ }
+ TclDStringAppendLiteral(dsPtr, "\""); /* closing escape quote-char */
+ return special;
+}
+
static void
BuildCommandLine(
const char *executable, /* Full path of executable (including
@@ -1451,10 +1531,22 @@ BuildCommandLine(
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
* command line (TCHAR). */
{
- const char *arg, *start, *special;
- int quote, i;
+ const char *arg, *start, *special, *bspos;
+ int quote = 0, i;
Tcl_DString ds;
+ /* characters to enclose in quotes if unpaired quote flag set */
+ const static char *specMetaChars = "&|^<>!()%";
+ /* characters to enclose in quotes in any case (regardless unpaired-flag) */
+ const static char *specMetaChars2 = "%";
+
+ /* Quote flags:
+ * CL_ESCAPE - escape argument;
+ * CL_QUOTE - enclose in quotes;
+ * CL_UNPAIRED - previous arguments chain contains unpaired quote-char;
+ */
+ enum {CL_ESCAPE = 1, CL_QUOTE = 2, CL_UNPAIRED = 4};
+
Tcl_DStringInit(&ds);
/*
@@ -1474,61 +1566,98 @@ BuildCommandLine(
TclDStringAppendLiteral(&ds, " ");
}
- quote = 0;
+ quote &= ~(CL_ESCAPE|CL_QUOTE); /* reset escape flags */
+ bspos = NULL;
if (arg[0] == '\0') {
- quote = 1;
+ quote = CL_QUOTE;
} else {
int count;
- Tcl_UniChar ch = 0;
-
- for (start = arg; *start != '\0'; start += count) {
- count = TclUtfToUniChar(start, &ch);
- if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */
- quote = 1;
+ Tcl_UniChar ch;
+ for (start = arg;
+ *start != '\0' &&
+ (quote & (CL_ESCAPE|CL_QUOTE)) != (CL_ESCAPE|CL_QUOTE);
+ start += count
+ ) {
+ count = Tcl_UtfToUniChar(start, &ch);
+ if (count > 1) continue;
+ if (Tcl_UniCharIsSpace(ch)) {
+ quote |= CL_QUOTE; /* quote only */
+ if (bspos) { /* if backslash found - escape & quote */
+ quote |= CL_ESCAPE;
+ break;
+ }
+ continue;
+ }
+ if (strchr(specMetaChars, *start)) {
+ quote |= (CL_ESCAPE|CL_QUOTE); /*escape & quote */
break;
}
+ if (*start == '"') {
+ quote |= CL_ESCAPE; /* escape only */
+ continue;
+ }
+ if (*start == '\\') {
+ bspos = start;
+ if (quote & CL_QUOTE) { /* if quote - escape & quote */
+ quote |= CL_ESCAPE;
+ break;
+ }
+ continue;
+ }
}
+ bspos = NULL;
}
- if (quote) {
+ if (quote & CL_QUOTE) {
+ /* start of argument (main opening quote-char) */
TclDStringAppendLiteral(&ds, "\"");
}
- start = arg;
- for (special = arg; ; ) {
- if ((*special == '\\') && (special[1] == '\\' ||
- special[1] == '"' || (quote && special[1] == '\0'))) {
- Tcl_DStringAppend(&ds, start, (int) (special - start));
- start = special;
- while (1) {
- special++;
- if (*special == '"' || (quote && *special == '\0')) {
- /*
- * N backslashes followed a quote -> insert N * 2 + 1
- * backslashes then a quote.
- */
-
- Tcl_DStringAppend(&ds, start,
- (int) (special - start));
- break;
- }
- if (*special != '\\') {
- break;
- }
+ if (!(quote & CL_ESCAPE)) {
+ /* nothing to escape */
+ Tcl_DStringAppend(&ds, arg, -1);
+ } else {
+ start = arg;
+ for (special = arg; *special != '\0'; ) {
+ /* position of `\` is important before quote or at end (equal `\"` because quoted) */
+ if (*special == '\\') {
+ /* bypass backslashes (and mark first backslash possition)*/
+ special = BuildCmdLineBypassBS(special, &bspos);
+ if (*special == '\0') break;
}
- Tcl_DStringAppend(&ds, start, (int) (special - start));
- start = special;
- }
- if (*special == '"') {
- Tcl_DStringAppend(&ds, start, (int) (special - start));
- TclDStringAppendLiteral(&ds, "\\\"");
- start = special + 1;
- }
- if (*special == '\0') {
- break;
+ /* ["] */
+ if (*special == '"') {
+ quote ^= CL_UNPAIRED; /* invert unpaired flag - observe unpaired quotes */
+ /* add part before (and escape backslashes before quote) */
+ QuoteCmdLineBackslash(&ds, start, special, bspos);
+ bspos = NULL;
+ /* escape using backslash */
+ TclDStringAppendLiteral(&ds, "\\\"");
+ start = ++special;
+ continue;
+ }
+ /* unpaired (escaped) quote causes special handling on meta-chars */
+ if ((quote & CL_UNPAIRED) && strchr(specMetaChars, *special)) {
+ special = QuoteCmdLinePart(&ds, start, special, specMetaChars, &bspos);
+ /* start to current or first backslash */
+ start = !bspos ? special : bspos;
+ continue;
+ }
+ /* special case for % - should be enclosed always (paired also) */
+ if (strchr(specMetaChars2, *special)) {
+ special = QuoteCmdLinePart(&ds, start, special, specMetaChars2, &bspos);
+ /* start to current or first backslash */
+ start = !bspos ? special : bspos;
+ continue;
+ }
+ /* other not special (and not meta) character */
+ bspos = NULL; /* reset last backslash possition (not interesting) */
+ special++;
}
- special++;
+ /* rest of argument (and escape backslashes before closing main quote) */
+ QuoteCmdLineBackslash(&ds, start, special,
+ (quote & CL_QUOTE) ? bspos : NULL);
}
- Tcl_DStringAppend(&ds, start, (int) (special - start));
- if (quote) {
+ if (quote & CL_QUOTE) {
+ /* end of argument (main closing quote-char) */
TclDStringAppendLiteral(&ds, "\"");
}
}
diff --git a/tcl8.6/win/tclWinPort.h b/tcl8.6/win/tclWinPort.h
index 159a708..29b1447 100644
--- a/tcl8.6/win/tclWinPort.h
+++ b/tcl8.6/win/tclWinPort.h
@@ -568,4 +568,7 @@ typedef DWORD_PTR * PDWORD_PTR;
# define LABEL_SECURITY_INFORMATION (0x00000010L)
#endif
+#define Tcl_DirEntry void
+#define TclDIR void
+
#endif /* _TCLWINPORT */
diff --git a/tcl8.6/win/tclWinReg.c b/tcl8.6/win/tclWinReg.c
index de48b9b..f93a553 100644
--- a/tcl8.6/win/tclWinReg.c
+++ b/tcl8.6/win/tclWinReg.c
@@ -22,13 +22,6 @@
#endif
#include <stdlib.h>
-#ifndef UNICODE
-# undef Tcl_WinTCharToUtf
-# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c)
-# undef Tcl_WinUtfToTChar
-# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c)
-#endif /* !UNICODE */
-
/*
* Ensure that we can say which registry is being accessed.
*/
@@ -131,6 +124,25 @@ static int SetValue(Tcl_Interp *interp, Tcl_Obj *keyNameObj,
Tcl_Obj *valueNameObj, Tcl_Obj *dataObj,
Tcl_Obj *typeObj, REGSAM mode);
+static unsigned char *
+getByteArrayFromObj(
+ Tcl_Obj *objPtr,
+ size_t *lengthPtr
+) {
+ int length;
+
+ unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length);
+#if TCL_MAJOR_VERSION > 8
+ if (sizeof(TCL_HASH_TYPE) > sizeof(int)) {
+ /* 64-bit and TIP #494 situation: */
+ *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1;
+ } else
+#endif
+ /* 32-bit or without TIP #494 */
+ *lengthPtr = (size_t) (unsigned) length;
+ return result;
+}
+
DLLEXPORT int Registry_Init(Tcl_Interp *interp);
DLLEXPORT int Registry_Unload(Tcl_Interp *interp, int flags);
@@ -163,7 +175,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.2");
+ return Tcl_PkgProvide(interp, "registry", "1.3.3");
}
/*
@@ -414,12 +426,12 @@ DeleteKey(
*/
keyName = Tcl_GetString(keyNameObj);
- buffer = ckalloc(keyNameObj->length + 1);
+ buffer = Tcl_Alloc(keyNameObj->length + 1);
strcpy(buffer, keyName);
if (ParseKeyName(interp, buffer, &hostName, &rootKey,
&keyName) != TCL_OK) {
- ckfree(buffer);
+ Tcl_Free(buffer);
return TCL_ERROR;
}
@@ -427,7 +439,7 @@ DeleteKey(
Tcl_SetObjResult(interp,
Tcl_NewStringObj("bad key: cannot delete root keys", -1));
Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", NULL);
- ckfree(buffer);
+ Tcl_Free(buffer);
return TCL_ERROR;
}
@@ -442,7 +454,7 @@ DeleteKey(
mode |= KEY_ENUMERATE_SUB_KEYS | DELETE;
result = OpenSubKey(hostName, rootKey, keyName, mode, 0, &subkey);
if (result != ERROR_SUCCESS) {
- ckfree(buffer);
+ Tcl_Free(buffer);
if (result == ERROR_FILE_NOT_FOUND) {
return TCL_OK;
}
@@ -470,7 +482,7 @@ DeleteKey(
}
RegCloseKey(subkey);
- ckfree(buffer);
+ Tcl_Free(buffer);
return result;
}
@@ -499,7 +511,6 @@ DeleteValue(
{
HKEY key;
char *valueName;
- size_t length;
DWORD result;
Tcl_DString ds;
@@ -513,8 +524,7 @@ DeleteValue(
}
valueName = Tcl_GetString(valueNameObj);
- length = valueNameObj->length;
- Tcl_WinUtfToTChar(valueName, length, &ds);
+ Tcl_WinUtfToTChar(valueName, valueNameObj->length, &ds);
result = RegDeleteValue(key, (const TCHAR *)Tcl_DStringValue(&ds));
Tcl_DStringFree(&ds);
if (result != ERROR_SUCCESS) {
@@ -603,8 +613,7 @@ GetKeyNames(
}
break;
}
- Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds);
- name = Tcl_DStringValue(&ds);
+ name = Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds);
if (pattern && !Tcl_StringMatch(name, pattern)) {
Tcl_DStringFree(&ds);
continue;
@@ -655,7 +664,6 @@ GetType(
Tcl_DString ds;
const char *valueName;
const TCHAR *nativeValue;
- size_t length;
/*
* Attempt to open the key for reading.
@@ -671,8 +679,7 @@ GetType(
*/
valueName = Tcl_GetString(valueNameObj);
- length = valueNameObj->length;
- nativeValue = Tcl_WinUtfToTChar(valueName, length, &ds);
+ nativeValue = Tcl_WinUtfToTChar(valueName, valueNameObj->length, &ds);
result = RegQueryValueEx(key, nativeValue, NULL, &type,
NULL, NULL);
Tcl_DStringFree(&ds);
@@ -728,7 +735,6 @@ GetValue(
const TCHAR *nativeValue;
DWORD result, length, type;
Tcl_DString data, buf;
- size_t nameLen;
/*
* Attempt to open the key for reading.
@@ -754,8 +760,7 @@ GetValue(
length = TCL_DSTRING_STATIC_SIZE/sizeof(TCHAR) - 1;
valueName = Tcl_GetString(valueNameObj);
- nameLen = valueNameObj->length;
- nativeValue = Tcl_WinUtfToTChar(valueName, nameLen, &buf);
+ nativeValue = Tcl_WinUtfToTChar(valueName, valueNameObj->length, &buf);
result = RegQueryValueEx(key, nativeValue, NULL, &type,
(BYTE *) Tcl_DStringValue(&data), &length);
@@ -944,13 +949,11 @@ OpenKey(
HKEY *keyPtr) /* Returned HKEY. */
{
char *keyName, *buffer, *hostName;
- size_t length;
HKEY rootKey;
DWORD result;
keyName = Tcl_GetString(keyNameObj);
- length = keyNameObj->length;
- buffer = ckalloc(length + 1);
+ buffer = Tcl_Alloc(keyNameObj->length + 1);
strcpy(buffer, keyName);
result = ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName);
@@ -966,7 +969,7 @@ OpenKey(
}
}
- ckfree(buffer);
+ Tcl_Free(buffer);
return result;
}
@@ -1019,7 +1022,9 @@ OpenSubKey(
* this key must be closed by the caller.
*/
- keyName = (char *) Tcl_WinUtfToTChar(keyName, -1, &buf);
+ if (keyName) {
+ keyName = (char *) Tcl_WinUtfToTChar(keyName, -1, &buf);
+ }
if (flags & REG_CREATE) {
DWORD create;
@@ -1037,7 +1042,9 @@ OpenSubKey(
result = RegOpenKeyEx(rootKey, (TCHAR *)keyName, 0, mode,
keyPtr);
}
- Tcl_DStringFree(&buf);
+ if (keyName) {
+ Tcl_DStringFree(&buf);
+ }
/*
* Be sure to close the root key since we are done with it now.
@@ -1248,7 +1255,6 @@ SetValue(
REGSAM mode) /* Mode flags to pass. */
{
int type;
- size_t length;
DWORD result;
HKEY key;
const char *valueName;
@@ -1269,8 +1275,7 @@ SetValue(
}
valueName = Tcl_GetString(valueNameObj);
- length = valueNameObj->length;
- valueName = (char *) Tcl_WinUtfToTChar(valueName, length, &nameBuf);
+ valueName = (char *) Tcl_WinUtfToTChar(valueName, valueNameObj->length, &nameBuf);
if (type == REG_DWORD || type == REG_DWORD_BIG_ENDIAN) {
int value;
@@ -1305,8 +1310,7 @@ SetValue(
for (i = 0; i < objc; i++) {
const char *bytes = Tcl_GetString(objv[i]);
- length = objv[i]->length;
- Tcl_DStringAppend(&data, bytes, length);
+ Tcl_DStringAppend(&data, bytes, objv[i]->length);
/*
* Add a null character to separate this value from the next.
@@ -1326,28 +1330,26 @@ SetValue(
Tcl_DString buf;
const char *data = Tcl_GetString(dataObj);
- length = dataObj->length;
- data = (char *) Tcl_WinUtfToTChar(data, length, &buf);
+ data = (char *) Tcl_WinUtfToTChar(data, dataObj->length, &buf);
/*
* Include the null in the length, padding if needed for WCHAR.
*/
Tcl_DStringSetLength(&buf, Tcl_DStringLength(&buf)+1);
- length = Tcl_DStringLength(&buf) + 1;
result = RegSetValueEx(key, (TCHAR *) valueName, 0,
- (DWORD) type, (BYTE *) data, (DWORD) length);
+ (DWORD) type, (BYTE *) data, (DWORD) Tcl_DStringLength(&buf) + 1);
Tcl_DStringFree(&buf);
} else {
BYTE *data;
- int bytelength;
+ size_t bytelength;
/*
* Store binary data in the registry.
*/
- data = (BYTE *) Tcl_GetByteArrayFromObj(dataObj, &bytelength);
+ data = (BYTE *) getByteArrayFromObj(dataObj, &bytelength);
result = RegSetValueEx(key, (TCHAR *) valueName, 0,
(DWORD) type, data, (DWORD) bytelength);
}
@@ -1408,8 +1410,7 @@ BroadcastValue(
}
str = Tcl_GetString(objv[0]);
- len = objv[0]->length;
- wstr = (WCHAR *) Tcl_WinUtfToTChar(str, len, &ds);
+ wstr = (WCHAR *) Tcl_WinUtfToTChar(str, objv[0]->length, &ds);
if (Tcl_DStringLength(&ds) == 0) {
wstr = NULL;
}
diff --git a/tcl8.6/win/tclWinSock.c b/tcl8.6/win/tclWinSock.c
index da2e60a..e2479e8 100644
--- a/tcl8.6/win/tclWinSock.c
+++ b/tcl8.6/win/tclWinSock.c
@@ -686,7 +686,7 @@ WaitForConnect(
}
/*
- * A non blocking socket waiting for an asyncronous connect
+ * A non blocking socket waiting for an asynchronous connect
* returns directly the error EWOULDBLOCK
*/
@@ -1606,9 +1606,9 @@ TcpGetHandleProc(
*
* This might be called in 3 circumstances:
* - By a regular socket command
- * - By the event handler to continue an asynchroneous connect
+ * - By the event handler to continue an asynchronously connect
* - By a blocking socket function (gets/puts) to terminate the
- * connect synchroneously
+ * connect synchronously
*
* Results:
* TCL_OK, if the socket was successfully connected or an asynchronous
@@ -1620,7 +1620,7 @@ TcpGetHandleProc(
*
* Remarks:
* A single host name may resolve to more than one IP address, e.g. for
- * an IPv4/IPv6 dual stack host. For handling asyncronously connecting
+ * an IPv4/IPv6 dual stack host. For handling asynchronously connecting
* sockets in the background for such hosts, this function can act as a
* coroutine. On the first call, it sets up the control variables for the
* two nested loops over the local and remote addresses. Once the first
@@ -1628,7 +1628,7 @@ TcpGetHandleProc(
* event handler for that socket, and returns. When the callback occurs,
* control is transferred to the "reenter" label, right after the initial
* return and the loops resume as if they had never been interrupted.
- * For syncronously connecting sockets, the loops work the usual way.
+ * For synchronously connecting sockets, the loops work the usual way.
*
*----------------------------------------------------------------------
*/
@@ -1718,7 +1718,7 @@ TcpConnect(
continue;
}
/*
- * For asyncroneous connect set the socket in nonblocking mode
+ * For asynchroneous connect set the socket in nonblocking mode
* and activate connect notification
*/
if (async_connect) {
@@ -1806,7 +1806,7 @@ TcpConnect(
/*
* Clear the tsd socket list pointer if we did not wait for
- * the FD_CONNECT asyncroneously
+ * the FD_CONNECT asynchroneously
*/
tsdPtr->pendingTcpState = NULL;
@@ -1868,7 +1868,7 @@ out:
SetEvent(tsdPtr->socketListLock);
}
/*
- * Error message on syncroneous connect
+ * Error message on synchroneous connect
*/
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
diff --git a/tcl8.6/win/tclWinThrd.c b/tcl8.6/win/tclWinThrd.c
index 8f3ddb9..0f83526 100644
--- a/tcl8.6/win/tclWinThrd.c
+++ b/tcl8.6/win/tclWinThrd.c
@@ -247,7 +247,7 @@ TclpThreadCreate(
/*
* The only purpose of this is to decrement the reference count so the
- * OS resources will be reaquired when the thread closes.
+ * OS resources will be reacquired when the thread closes.
*/
CloseHandle(tHandle);
@@ -405,7 +405,7 @@ TclpInitUnlock(void)
* mutexes, condition variables, and thread local storage keys.
*
* This lock must be different than the initLock because the initLock is
- * held during creation of syncronization objects.
+ * held during creation of synchronization objects.
*
* Results:
* None.
@@ -555,7 +555,7 @@ static void FinalizeConditionEvent(ClientData data);
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
+ * May block the current thread. The mutex is acquired when this returns.
*
*----------------------------------------------------------------------
*/
@@ -655,7 +655,7 @@ TclpFinalizeMutex(
* None.
*
* Side effects:
- * May block the current thread. The mutex is aquired when this returns.
+ * May block the current thread. The mutex is acquired when this returns.
* Will allocate memory for a HANDLE and initialize this the first time
* this Tcl_Condition is used.
*